From cf9986896ccf40a3b23271927ae6e183fc20c268 Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 12 Feb 2016 16:32:56 +0000
Subject: [PATCH] Simplified test code: Removed JDNI, Removed direct use of Sockets and *ProtocolOp, replaced with new RemoteConnection class.

---
 opendj-server-legacy/src/test/java/org/opends/server/core/DeleteOperationTestCase.java            |  182 -
 opendj-server-legacy/src/test/java/org/opends/server/core/AbandonOperationTestCase.java           |  545 ++---
 opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPAuthenticationHandlerTestCase.java | 2283 ++++--------------------
 opendj-server-legacy/src/test/java/org/opends/server/core/AddOperationTestCase.java               |  120 
 opendj-server-legacy/src/test/java/org/opends/server/api/PasswordValidatorTestCase.java           |  170 -
 opendj-server-legacy/src/test/java/org/opends/server/tools/RemoteConnection.java                  |  329 +++
 opendj-server-legacy/src/test/java/org/opends/server/core/IdleTimeLimitTestCase.java              |  118 -
 opendj-server-legacy/src/test/java/org/opends/server/controls/PasswordPolicyControlTestCase.java  |  722 +------
 opendj-server-legacy/src/test/java/org/opends/server/crypto/CryptoManagerTestCase.java            |   61 
 opendj-server-legacy/src/test/java/org/opends/server/core/TestModifyDNOperation.java              |   99 
 opendj-server-legacy/src/test/java/org/opends/server/core/SearchOperationTestCase.java            |   63 
 opendj-server-legacy/src/test/java/org/opends/server/core/ModifyOperationTestCase.java            |  779 +++-----
 12 files changed, 1,661 insertions(+), 3,810 deletions(-)

diff --git a/opendj-server-legacy/src/test/java/org/opends/server/api/PasswordValidatorTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/api/PasswordValidatorTestCase.java
index d69c7b5..6c5aa89 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/api/PasswordValidatorTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/api/PasswordValidatorTestCase.java
@@ -22,16 +22,22 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS.
+ *      Portions Copyright 2011-2016 ForgeRock AS.
  */
 package org.opends.server.api;
 
+import static org.forgerock.opendj.ldap.ModificationType.*;
+import static org.forgerock.opendj.ldap.requests.Requests.*;
+import static org.opends.server.TestCaseUtils.*;
+import static org.testng.Assert.*;
+
 import java.net.Socket;
 import java.util.ArrayList;
 import java.util.Set;
 
 import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.ModificationType;
+import org.forgerock.opendj.ldap.ResultCode;
 import org.opends.server.TestCaseUtils;
 import org.opends.server.extensions.TestPasswordValidator;
 import org.opends.server.protocols.ldap.BindRequestProtocolOp;
@@ -43,14 +49,12 @@
 import org.opends.server.protocols.ldap.ModifyResponseProtocolOp;
 import org.opends.server.tools.LDAPPasswordModify;
 import org.opends.server.tools.LDAPWriter;
+import org.opends.server.tools.RemoteConnection;
 import org.opends.server.types.RawModification;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import static org.opends.server.TestCaseUtils.*;
-import static org.testng.Assert.*;
-
 /**
  * A set of generic test cases for password validators.
  */
@@ -490,37 +494,19 @@
          "userPassword: password");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("uid=test.user,o=test", "password");
 
-    BindRequestProtocolOp bindRequest =
-      new BindRequestProtocolOp(
-               ByteString.valueOfUtf8("uid=test.user,o=test"),
-                                3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
+      TestPasswordValidator.setNextReturnValue(false);
+      LDAPMessage message = conn.modify(
+          newModifyRequest("uid=test.user,o=test")
+          .addModification(REPLACE, "userPassword", "newPassword"),
+          false);
+      ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
+      assertNotEquals(modifyResponse.getResultCode(), ResultCode.SUCCESS.intValue());
+    }
 
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
-
-    ArrayList<RawModification> mods = new ArrayList<>();
-    LDAPAttribute attr = new LDAPAttribute("userPassword", "newPassword");
-    mods.add(new LDAPModification(ModificationType.REPLACE, attr));
-
-    TestPasswordValidator.setNextReturnValue(false);
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(
-                  ByteString.valueOfUtf8("uid=test.user,o=test"), mods);
-    message = new LDAPMessage(2, modifyRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    ModifyResponseProtocolOp modifyResponse =
-         message.getModifyResponseProtocolOp();
-    assertNotEquals(modifyResponse.getResultCode(), 0);
 
     assertEquals(TestPasswordValidator.getLastNewPassword(),
                  ByteString.valueOfUtf8("newPassword"));
@@ -559,40 +545,15 @@
          "ds-privilege-name: bypass-acl",
          "userPassword: password");
 
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("uid=test.user,o=test", "password");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
-
-    BindRequestProtocolOp bindRequest =
-      new BindRequestProtocolOp(
-               ByteString.valueOfUtf8("uid=test.user,o=test"),
-                                3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
-
-    LDAPAttribute attr = new LDAPAttribute("userPassword", "password");
-    ArrayList<RawModification> mods = new ArrayList<>();
-    mods.add(new LDAPModification(ModificationType.DELETE, attr));
-
-    attr = new LDAPAttribute("userPassword", "newPassword");
-    mods.add(new LDAPModification(ModificationType.ADD, attr));
-
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(
-                  ByteString.valueOfUtf8("uid=test.user,o=test"), mods);
-    message = new LDAPMessage(2, modifyRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    ModifyResponseProtocolOp modifyResponse =
-         message.getModifyResponseProtocolOp();
-    assertEquals(modifyResponse.getResultCode(), 0);
+      conn.modify(
+          newModifyRequest("uid=test.user,o=test")
+          .addModification(DELETE, "userPassword", "password")
+          .addModification(ADD, "userPassword", "newPassword"));
+    }
 
     Set<ByteString> currentPasswords =
          TestPasswordValidator.getLastCurrentPasswords();
@@ -634,37 +595,14 @@
          "ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
               "cn=Password Policies,cn=config");
 
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("uid=test.user,o=test", "password");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
-
-    BindRequestProtocolOp bindRequest =
-      new BindRequestProtocolOp(
-               ByteString.valueOfUtf8("uid=test.user,o=test"),
-                                3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
-
-    LDAPAttribute attr = new LDAPAttribute("userPassword", "newPassword");
-    ArrayList<RawModification> mods = new ArrayList<>();
-    mods.add(new LDAPModification(ModificationType.REPLACE, attr));
-
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(
-                  ByteString.valueOfUtf8("uid=test.user,o=test"), mods);
-    message = new LDAPMessage(2, modifyRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    ModifyResponseProtocolOp modifyResponse =
-         message.getModifyResponseProtocolOp();
-    assertEquals(modifyResponse.getResultCode(), 0);
+      conn.modify(
+          newModifyRequest("uid=test.user,o=test")
+          .addModification(REPLACE, "userPassword", "newPassword"));
+    }
 
     Set<ByteString> currentPasswords =
          TestPasswordValidator.getLastCurrentPasswords();
@@ -707,39 +645,15 @@
               "cn=Password Policies,cn=config");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("uid=test.user,o=test", "password");
 
-    BindRequestProtocolOp bindRequest =
-      new BindRequestProtocolOp(
-               ByteString.valueOfUtf8("uid=test.user,o=test"),
-                                3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
-
-    LDAPAttribute attr = new LDAPAttribute("userPassword", "password");
-    ArrayList<RawModification> mods = new ArrayList<>();
-    mods.add(new LDAPModification(ModificationType.DELETE, attr));
-
-    attr = new LDAPAttribute("userPassword", "newPassword");
-    mods.add(new LDAPModification(ModificationType.ADD, attr));
-
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(
-                  ByteString.valueOfUtf8("uid=test.user,o=test"), mods);
-    message = new LDAPMessage(2, modifyRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    ModifyResponseProtocolOp modifyResponse =
-         message.getModifyResponseProtocolOp();
-    assertEquals(modifyResponse.getResultCode(), 0);
+      conn.modify(
+          newModifyRequest("uid=test.user,o=test")
+          .addModification(DELETE, "userPassword", "password")
+          .addModification(ADD, "userPassword", "newPassword"));
+    }
 
     Set<ByteString> currentPasswords =
          TestPasswordValidator.getLastCurrentPasswords();
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/controls/PasswordPolicyControlTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/controls/PasswordPolicyControlTestCase.java
index f4c59ac..c43285c 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/controls/PasswordPolicyControlTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/controls/PasswordPolicyControlTestCase.java
@@ -22,30 +22,42 @@
  *
  *
  *      Copyright 2008-2009 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS.
+ *      Portions Copyright 2011-2016 ForgeRock AS.
  */
 package org.opends.server.controls;
 
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
 import java.util.List;
 
-import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.DereferenceAliasesPolicy;
-import org.forgerock.opendj.ldap.ModificationType;
 import org.forgerock.opendj.ldap.SearchScope;
+import org.forgerock.opendj.ldap.controls.PasswordPolicyRequestControl;
+import org.forgerock.opendj.ldap.controls.ProxiedAuthV2RequestControl;
+import org.forgerock.opendj.ldap.requests.AddRequest;
+import org.forgerock.opendj.ldap.requests.CompareRequest;
+import org.forgerock.opendj.ldap.requests.DeleteRequest;
+import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
+import org.forgerock.opendj.ldap.requests.ModifyRequest;
+import org.forgerock.opendj.ldap.requests.SearchRequest;
+import org.forgerock.opendj.ldap.requests.SimpleBindRequest;
 import org.opends.server.TestCaseUtils;
-import org.opends.server.protocols.ldap.*;
+import org.opends.server.protocols.ldap.AddResponseProtocolOp;
+import org.opends.server.protocols.ldap.CompareResponseProtocolOp;
+import org.opends.server.protocols.ldap.DeleteResponseProtocolOp;
+import org.opends.server.protocols.ldap.LDAPControl;
+import org.opends.server.protocols.ldap.LDAPMessage;
+import org.opends.server.protocols.ldap.LDAPResultCode;
+import org.opends.server.protocols.ldap.ModifyDNResponseProtocolOp;
+import org.opends.server.protocols.ldap.ModifyResponseProtocolOp;
+import org.opends.server.protocols.ldap.SearchResultDoneProtocolOp;
+import org.opends.server.tools.RemoteConnection;
 import org.opends.server.types.Control;
 import org.opends.server.types.DirectoryException;
-import org.opends.server.types.RawAttribute;
-import org.opends.server.types.RawModification;
-import org.opends.server.util.StaticUtils;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import static org.assertj.core.api.Assertions.*;
+import static org.forgerock.opendj.ldap.ModificationType.*;
+import static org.forgerock.opendj.ldap.requests.Requests.*;
 import static org.opends.server.TestCaseUtils.*;
 import static org.opends.server.util.ServerConstants.*;
 import static org.testng.Assert.*;
@@ -101,65 +113,27 @@
         "userPassword: password",
         "ds-privilege-name: bypass-acl");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection c = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
+      LDAPMessage bindMessage = c.bind("uid=test.user,o=test", "password", newPasswordPolicyControl());
+      assertTrue(passwordPolicyControlExists(bindMessage.getControls(), PasswordPolicyErrorType.CHANGE_AFTER_RESET));
 
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest, controls);
-      w.writeMessage(message);
+      AddRequest addRequest = newAddRequest("ou=People,o=test")
+          .addAttribute("objectClass", "organizationalUnit")
+          .addAttribute("ou", "People")
+          .addControl(newPasswordPolicyControl());
+      LDAPMessage message = c.add(addRequest, false);
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.CHANGE_AFTER_RESET));
-
-
-      ArrayList<RawAttribute> rawAttrs = new ArrayList<>();
-      rawAttrs.add(RawAttribute.create("objectClass", "organizationalUnit"));
-      rawAttrs.add(RawAttribute.create("ou", "People"));
-
-      AddRequestProtocolOp addRequest = new AddRequestProtocolOp(
-           ByteString.valueOfUtf8("ou=People,o=test"), rawAttrs);
-
-      controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, addRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
       AddResponseProtocolOp addResponse = message.getAddResponseProtocolOp();
       assertNotEquals(addResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.CHANGE_AFTER_RESET));
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.CHANGE_AFTER_RESET));
     }
     finally
     {
       setPasswordPolicyProp("--set", "force-change-on-add:false");
-
-      StaticUtils.close(s);
     }
   }
 
-
-
   /**
    * Tests that an appropriate password policy response control is returned for
    * an add operation in which the proposed password is pre-encoded.
@@ -172,61 +146,30 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection c = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("cn=Directory Manager"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      c.bind("cn=Directory Manager", "password", newPasswordPolicyControl());
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-
-      ArrayList<RawAttribute> rawAttrs = new ArrayList<>();
-      rawAttrs.add(RawAttribute.create("objectClass", "inetOrgPerson"));
-      rawAttrs.add(RawAttribute.create("uid", "test.user"));
-      rawAttrs.add(RawAttribute.create("givenName", "Test"));
-      rawAttrs.add(RawAttribute.create("sn", "User"));
-      rawAttrs.add(RawAttribute.create("cn", "Test User"));
-      rawAttrs.add(RawAttribute.create("userPassword",
-                        "{SSHA}0pZPpMIm6xSBIW4hGvR/72fjO4M9p3Ff1g7QFw=="));
-
-      AddRequestProtocolOp addRequest = new AddRequestProtocolOp(
-           ByteString.valueOfUtf8("ou=uid=test.user,o=test"), rawAttrs);
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, addRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
+      AddRequest addRequest = newAddRequest("ou=uid=test.user,o=test")
+          .addAttribute("objectClass", "inetOrgPerson")
+          .addAttribute("uid", "test.user")
+          .addAttribute("givenName", "Test")
+          .addAttribute("sn", "User")
+          .addAttribute("cn", "Test User")
+          .addAttribute("userPassword", "{SSHA}0pZPpMIm6xSBIW4hGvR/72fjO4M9p3Ff1g7QFw==")
+          .addControl(newPasswordPolicyControl());
+      LDAPMessage message = c.add(addRequest, false);
       AddResponseProtocolOp addResponse = message.getAddResponseProtocolOp();
       assertNotEquals(addResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY));
-    }
-    finally
-    {
-      StaticUtils.close(s);
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY));
     }
   }
 
   private boolean passwordPolicyControlExists(List<Control> controls, PasswordPolicyErrorType expectedErrorType)
       throws DirectoryException
   {
-    boolean found = false;
+    assertThat(controls).isNotEmpty();
+
     for(Control c : controls)
     {
       if (c.getOID().equals(OID_PASSWORD_POLICY_CONTROL))
@@ -241,10 +184,10 @@
           pwpControl = (PasswordPolicyResponseControl)c;
         }
         assertEquals(pwpControl.getErrorType(), expectedErrorType);
-        found = true;
+        return true;
       }
     }
-    return found;
+    return false;
   }
 
 
@@ -262,55 +205,26 @@
 
     setPasswordPolicyProp("--add", "password-validator:Length-Based Password Validator");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection c = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("cn=Directory Manager"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      c.bind("cn=Directory Manager", "password", newPasswordPolicyControl());
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-
-      ArrayList<RawAttribute> rawAttrs = new ArrayList<>();
-      rawAttrs.add(RawAttribute.create("objectClass", "inetOrgPerson"));
-      rawAttrs.add(RawAttribute.create("uid", "test.user"));
-      rawAttrs.add(RawAttribute.create("givenName", "Test"));
-      rawAttrs.add(RawAttribute.create("sn", "User"));
-      rawAttrs.add(RawAttribute.create("cn", "Test User"));
-      rawAttrs.add(RawAttribute.create("userPassword", "short"));
-
-      AddRequestProtocolOp addRequest = new AddRequestProtocolOp(
-           ByteString.valueOfUtf8("ou=uid=test.user,o=test"), rawAttrs);
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, addRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
+      AddRequest addRequest = newAddRequest("ou=uid=test.user,o=test")
+          .addAttribute("objectClass", "inetOrgPerson")
+          .addAttribute("uid", "test.user")
+          .addAttribute("givenName", "Test")
+          .addAttribute("sn", "User")
+          .addAttribute("cn", "Test User")
+          .addAttribute("userPassword", "short")
+          .addControl(newPasswordPolicyControl());
+      LDAPMessage message = c.add(addRequest, false);
       AddResponseProtocolOp addResponse = message.getAddResponseProtocolOp();
       assertNotEquals(addResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY));
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY));
     }
     finally
     {
       setPasswordPolicyProp("--remove", "password-validator:Length-Based Password Validator");
-
-      StaticUtils.close(s);
     }
   }
 
@@ -344,51 +258,28 @@
         "userPassword: password",
         "ds-privilege-name: bypass-acl");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection c = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("wrong"));
-
       for (int i=1; i <= 3; i++)
       {
-        LDAPMessage message = new LDAPMessage(1, bindRequest);
-        w.writeMessage(message);
-
-        message = r.readMessage();
-        BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-        assertNotEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+        SimpleBindRequest request =
+            newSimpleBindRequest("uid=test.user,o=test", "wrong".getBytes())
+            .addControl(newPasswordPolicyControl());
+        LDAPMessage message = c.bind(request, false);
+        assertNotEquals(message.getBindResponseProtocolOp().getResultCode(), LDAPResultCode.SUCCESS);
       }
 
-      bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
+      SimpleBindRequest request =
+          newSimpleBindRequest("uid=test.user,o=test", "password".getBytes())
+          .addControl(newPasswordPolicyControl());
 
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      LDAPMessage message = new LDAPMessage(4, bindRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertNotEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.ACCOUNT_LOCKED));
+      LDAPMessage message = c.bind(request, false);
+      assertNotEquals(message.getBindResponseProtocolOp().getResultCode(), LDAPResultCode.SUCCESS);
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.ACCOUNT_LOCKED));
     }
     finally
     {
       setPasswordPolicyProp("--set", "lockout-failure-count:0");
-
-      StaticUtils.close(s);
     }
   }
 
@@ -420,52 +311,28 @@
         "userPassword: password",
         "ds-privilege-name: bypass-acl");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection c = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      c.bind("uid=test.user,o=test", "password");
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-
-      CompareRequestProtocolOp compareRequest =
-           new CompareRequestProtocolOp(ByteString.valueOfUtf8("o=test"), "o",
-                                        ByteString.valueOfUtf8("test"));
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, compareRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      CompareResponseProtocolOp compareResponse =
-           message.getCompareResponseProtocolOp();
+      CompareRequest request = newCompareRequest("o=test", "o", "test").addControl(newPasswordPolicyControl());
+      LDAPMessage message = c.compare(request, false);
+      CompareResponseProtocolOp compareResponse = message.getCompareResponseProtocolOp();
       assertNotEquals(compareResponse.getResultCode(), LDAPResultCode.SUCCESS);
 
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.CHANGE_AFTER_RESET));
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.CHANGE_AFTER_RESET));
     }
     finally
     {
       setPasswordPolicyProp("--set", "force-change-on-add:false");
-
-      StaticUtils.close(s);
     }
   }
 
+  private PasswordPolicyRequestControl newPasswordPolicyControl()
+  {
+    return PasswordPolicyRequestControl.newControl(true);
+  }
+
 
 
   /**
@@ -500,48 +367,20 @@
         "objectClass: organizationalUnit",
         "ou: People");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection c = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      c.bind("uid=test.user,o=test", "password");
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-
-      DeleteRequestProtocolOp deleteRequest =
-           new DeleteRequestProtocolOp(ByteString.valueOfUtf8("ou=People,o=test"));
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, deleteRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      DeleteResponseProtocolOp deleteResponse =
-           message.getDeleteResponseProtocolOp();
+      DeleteRequest deleteRequest = newDeleteRequest("ou=People,o=test").addControl(newPasswordPolicyControl());
+      LDAPMessage message = c.delete(deleteRequest, false);
+      DeleteResponseProtocolOp deleteResponse = message.getDeleteResponseProtocolOp();
       assertNotEquals(deleteResponse.getResultCode(), LDAPResultCode.SUCCESS);
 
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.CHANGE_AFTER_RESET));
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.CHANGE_AFTER_RESET));
     }
     finally
     {
       setPasswordPolicyProp("--set", "force-change-on-add:false");
-
-      StaticUtils.close(s);
     }
   }
 
@@ -621,54 +460,26 @@
         "userPassword: password",
         "ds-privilege-name: bypass-acl");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8(userDN), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      conn.bind(userDN, "password");
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-
-      ArrayList<RawModification> mods = new ArrayList<>();
-      mods.add(RawModification.create(ModificationType.REPLACE, "description",
-                                      "foo"));
-
-      ModifyRequestProtocolOp modifyRequest =
-           new ModifyRequestProtocolOp(ByteString.valueOfUtf8(entryDN), mods);
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, modifyRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      ModifyResponseProtocolOp modifyResponse =
-           message.getModifyResponseProtocolOp();
-
+      ModifyRequest modifyRequest =
+          newModifyRequest(entryDN).addModification(REPLACE, "description", "foo")
+          .addControl(newPasswordPolicyControl());
+      LDAPMessage message = conn.modify(modifyRequest, false);
+      ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
       if (changeAfterReset)
       {
-        assertEquals(modifyResponse.getResultCode(),
-            LDAPResultCode.CONSTRAINT_VIOLATION);
+        assertEquals(modifyResponse.getResultCode(), LDAPResultCode.CONSTRAINT_VIOLATION);
       }
       else
       {
-        assertEquals(modifyResponse.getResultCode(),
-            LDAPResultCode.SUCCESS);
+        assertEquals(modifyResponse.getResultCode(), LDAPResultCode.SUCCESS);
       }
 
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
+      List<Control> controls = message.getControls();
+      assertThat(controls).isNotEmpty();
 
       boolean found = false;
       for(Control c : controls)
@@ -699,8 +510,6 @@
     finally
     {
       setPasswordPolicyProp("--set", "force-change-on-add:false");
-
-      StaticUtils.close(s);
     }
   }
 
@@ -766,56 +575,23 @@
         "userPassword: password",
         "ds-privilege-name: bypass-acl");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8(userDN), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      conn.bind(userDN, "password");
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+      ModifyRequest modifyRequest = newModifyRequest(entryDN)
+          .addModification(REPLACE, "description", "foo")
+          .addControl(newPasswordPolicyControl())
+          .addControl(ProxiedAuthV2RequestControl.newControl("dn:" + authzDN));
+      LDAPMessage message = conn.modify(modifyRequest, false);
+      ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
+      assertEquals(modifyResponse.getResultCode(), LDAPResultCode.CONSTRAINT_VIOLATION);
 
-
-      ArrayList<RawModification> mods = new ArrayList<>();
-      mods.add(RawModification.create(ModificationType.REPLACE, "description",
-                                      "foo"));
-
-      ModifyRequestProtocolOp modifyRequest =
-           new ModifyRequestProtocolOp(ByteString.valueOfUtf8(entryDN), mods);
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-      controls.add(new LDAPControl(OID_PROXIED_AUTH_V2, true,
-          ByteString.valueOfUtf8("dn:" + authzDN)));
-
-      message = new LDAPMessage(2, modifyRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      ModifyResponseProtocolOp modifyResponse =
-           message.getModifyResponseProtocolOp();
-
-      assertEquals(modifyResponse.getResultCode(),
-          LDAPResultCode.CONSTRAINT_VIOLATION);
-
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.CHANGE_AFTER_RESET));
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.CHANGE_AFTER_RESET));
     }
     finally
     {
       setPasswordPolicyProp("--set", "force-change-on-add:false");
-
-      StaticUtils.close(s);
     }
   }
 
@@ -849,53 +625,22 @@
         "userPassword: password",
         "ds-privilege-name: bypass-acl");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      conn.bind("uid=test.user,o=test", "password");
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-
-      ArrayList<RawModification> mods = new ArrayList<>();
-      mods.add(RawModification.create(ModificationType.REPLACE, "userPassword",
-                                      "newpassword"));
-
-      ModifyRequestProtocolOp modifyRequest =
-           new ModifyRequestProtocolOp(
-                    ByteString.valueOfUtf8("uid=test.user,o=test"), mods);
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, modifyRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      ModifyResponseProtocolOp modifyResponse =
-           message.getModifyResponseProtocolOp();
+      ModifyRequest modifyRequest = newModifyRequest("uid=test.user,o=test")
+          .addModification(REPLACE, "userPassword", "newpassword")
+          .addControl(newPasswordPolicyControl());
+      LDAPMessage message = conn.modify(modifyRequest, false);
+      ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
       assertNotEquals(modifyResponse.getResultCode(), LDAPResultCode.SUCCESS);
 
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED));
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED));
     }
     finally
     {
       setPasswordPolicyProp("--set", "allow-user-password-changes:true");
-
-      StaticUtils.close(s);
     }
   }
 
@@ -927,53 +672,22 @@
         "userPassword: password",
         "ds-privilege-name: bypass-acl");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      conn.bind("uid=test.user,o=test", "password");
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-
-      ArrayList<RawModification> mods = new ArrayList<>();
-      mods.add(RawModification.create(ModificationType.REPLACE, "userPassword",
-                                      "password"));
-
-      ModifyRequestProtocolOp modifyRequest =
-           new ModifyRequestProtocolOp(
-                    ByteString.valueOfUtf8("uid=test.user,o=test"), mods);
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, modifyRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      ModifyResponseProtocolOp modifyResponse =
-           message.getModifyResponseProtocolOp();
+      ModifyRequest modifyRequest = newModifyRequest("uid=test.user,o=test")
+          .addModification(REPLACE, "userPassword", "password")
+          .addControl(newPasswordPolicyControl());
+      LDAPMessage message = conn.modify(modifyRequest, false);
+      ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
       assertNotEquals(modifyResponse.getResultCode(), LDAPResultCode.SUCCESS);
 
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.PASSWORD_IN_HISTORY));
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.PASSWORD_IN_HISTORY));
     }
     finally
     {
       setPasswordPolicyProp("--set", "password-history-count:0");
-
-      StaticUtils.close(s);
     }
   }
 
@@ -1007,53 +721,22 @@
         "userPassword: password",
         "ds-privilege-name: bypass-acl");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      conn.bind("uid=test.user,o=test", "password");
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-
-      ArrayList<RawModification> mods = new ArrayList<>();
-      mods.add(RawModification.create(ModificationType.REPLACE, "userPassword",
-                                      "newpassword"));
-
-      ModifyRequestProtocolOp modifyRequest =
-           new ModifyRequestProtocolOp(
-                    ByteString.valueOfUtf8("uid=test.user,o=test"), mods);
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, modifyRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      ModifyResponseProtocolOp modifyResponse =
-           message.getModifyResponseProtocolOp();
+      ModifyRequest modifyRequest = newModifyRequest("uid=test.user,o=test")
+          .addModification(REPLACE, "userPassword", "newpassword")
+          .addControl(newPasswordPolicyControl());
+      LDAPMessage message = conn.modify(modifyRequest, false);
+      ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
       assertNotEquals(modifyResponse.getResultCode(), LDAPResultCode.SUCCESS);
 
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.MUST_SUPPLY_OLD_PASSWORD));
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.MUST_SUPPLY_OLD_PASSWORD));
     }
     finally
     {
       setPasswordPolicyProp("--set", "password-change-requires-current-password:false");
-
-      StaticUtils.close(s);
     }
   }
 
@@ -1087,53 +770,22 @@
         "userPassword: password",
         "ds-privilege-name: bypass-acl");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      conn.bind("uid=test.user,o=test", "password");
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-
-      ArrayList<RawModification> mods = new ArrayList<>();
-      mods.add(RawModification.create(ModificationType.REPLACE, "userPassword",
-                                      "newpassword"));
-
-      ModifyRequestProtocolOp modifyRequest =
-           new ModifyRequestProtocolOp(
-                    ByteString.valueOfUtf8("uid=test.user,o=test"), mods);
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, modifyRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      ModifyResponseProtocolOp modifyResponse =
-           message.getModifyResponseProtocolOp();
+      ModifyRequest modifyRequest = newModifyRequest("uid=test.user,o=test")
+          .addModification(REPLACE, "userPassword", "newpassword")
+          .addControl(newPasswordPolicyControl());
+      LDAPMessage message = conn.modify(modifyRequest, false);
+      ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
       assertNotEquals(modifyResponse.getResultCode(), LDAPResultCode.SUCCESS);
 
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.PASSWORD_TOO_YOUNG));
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.PASSWORD_TOO_YOUNG));
     }
     finally
     {
       setPasswordPolicyProp("--set", "min-password-age:0 seconds");
-
-      StaticUtils.close(s);
     }
   }
 
@@ -1171,50 +823,22 @@
         "objectClass: organizationalUnit",
         "ou: People");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      conn.bind("uid=test.user,o=test", "password");
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-
-      ModifyDNRequestProtocolOp modifyDNRequest =
-           new ModifyDNRequestProtocolOp(
-                    ByteString.valueOfUtf8("ou=People,o=test"),
-                    ByteString.valueOfUtf8("ou=Users"), true);
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, modifyDNRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      ModifyDNResponseProtocolOp modifyDNResponse =
-           message.getModifyDNResponseProtocolOp();
+      ModifyDNRequest modifyDNRequest = newModifyDNRequest("ou=People,o=test", "ou=Users")
+          .setDeleteOldRDN(true)
+          .addControl(newPasswordPolicyControl());
+      LDAPMessage message = conn.modifyDN(modifyDNRequest, false);
+      ModifyDNResponseProtocolOp modifyDNResponse = message.getModifyDNResponseProtocolOp();
       assertNotEquals(modifyDNResponse.getResultCode(), LDAPResultCode.SUCCESS);
 
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.CHANGE_AFTER_RESET));
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.CHANGE_AFTER_RESET));
     }
     finally
     {
       setPasswordPolicyProp("--set", "force-change-on-add:false");
-
-      StaticUtils.close(s);
     }
   }
 
@@ -1245,52 +869,22 @@
         "userPassword: password",
         "ds-privilege-name: bypass-acl");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    org.opends.server.tools.LDAPWriter w = new org.opends.server.tools.LDAPWriter(s);
-
-    try
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
+      conn.bind("uid=test.user,o=test", "password");
 
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
-
-
-      SearchRequestProtocolOp searchRequest =
-           new SearchRequestProtocolOp(ByteString.valueOfUtf8("o=test"),
-                                       SearchScope.BASE_OBJECT,
-                                       DereferenceAliasesPolicy.NEVER, 0, 0, false,
-                                       LDAPFilter.objectClassPresent(),
-                                       new LinkedHashSet<String>());
-
-      List<Control> controls = new ArrayList<>();
-      controls.add(new LDAPControl(OID_PASSWORD_POLICY_CONTROL, true));
-
-      message = new LDAPMessage(2, searchRequest, controls);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      SearchResultDoneProtocolOp searchDone =
-           message.getSearchResultDoneProtocolOp();
+      SearchRequest searchRequest = newSearchRequest("o=test", SearchScope.BASE_OBJECT, "(objectclass=*)")
+          .addControl(newPasswordPolicyControl());
+      conn.search(searchRequest);
+      LDAPMessage message = conn.readMessage();
+      SearchResultDoneProtocolOp searchDone = message.getSearchResultDoneProtocolOp();
       assertNotEquals(searchDone.getResultCode(), LDAPResultCode.SUCCESS);
 
-      controls = message.getControls();
-      assertNotNull(controls);
-      assertFalse(controls.isEmpty());
-
-      assertTrue(passwordPolicyControlExists(controls, PasswordPolicyErrorType.CHANGE_AFTER_RESET));
+      assertTrue(passwordPolicyControlExists(message.getControls(), PasswordPolicyErrorType.CHANGE_AFTER_RESET));
     }
     finally
     {
       setPasswordPolicyProp("--set", "force-change-on-add:false");
-
-      StaticUtils.close(s);
     }
   }
 
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/core/AbandonOperationTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/core/AbandonOperationTestCase.java
index fa7ed46..dddef8c 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/core/AbandonOperationTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/core/AbandonOperationTestCase.java
@@ -22,10 +22,14 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS.
+ *      Portions Copyright 2011-2016 ForgeRock AS.
  */
 package org.opends.server.core;
 
+import static org.opends.server.util.CollectionUtils.*;
+import static org.opends.server.util.ServerConstants.*;
+import static org.testng.Assert.*;
+
 import java.net.Socket;
 import java.util.ArrayList;
 import java.util.LinkedHashSet;
@@ -40,18 +44,37 @@
 import org.opends.server.plugins.DelayPreOpPlugin;
 import org.opends.server.plugins.DisconnectClientPlugin;
 import org.opends.server.protocols.internal.InternalClientConnection;
-import org.opends.server.protocols.ldap.*;
-import org.opends.server.tools.LDAPReader;
+import org.opends.server.protocols.ldap.AbandonRequestProtocolOp;
+import org.opends.server.protocols.ldap.AddRequestProtocolOp;
+import org.opends.server.protocols.ldap.AddResponseProtocolOp;
+import org.opends.server.protocols.ldap.CompareRequestProtocolOp;
+import org.opends.server.protocols.ldap.CompareResponseProtocolOp;
+import org.opends.server.protocols.ldap.DeleteRequestProtocolOp;
+import org.opends.server.protocols.ldap.DeleteResponseProtocolOp;
+import org.opends.server.protocols.ldap.ExtendedRequestProtocolOp;
+import org.opends.server.protocols.ldap.ExtendedResponseProtocolOp;
+import org.opends.server.protocols.ldap.LDAPAttribute;
+import org.opends.server.protocols.ldap.LDAPFilter;
+import org.opends.server.protocols.ldap.LDAPMessage;
+import org.opends.server.protocols.ldap.LDAPModification;
+import org.opends.server.protocols.ldap.LDAPResultCode;
+import org.opends.server.protocols.ldap.ModifyDNRequestProtocolOp;
+import org.opends.server.protocols.ldap.ModifyDNResponseProtocolOp;
+import org.opends.server.protocols.ldap.ModifyRequestProtocolOp;
+import org.opends.server.protocols.ldap.ModifyResponseProtocolOp;
+import org.opends.server.protocols.ldap.SearchRequestProtocolOp;
+import org.opends.server.protocols.ldap.SearchResultDoneProtocolOp;
 import org.opends.server.tools.LDAPWriter;
-import org.opends.server.types.*;
+import org.opends.server.tools.RemoteConnection;
+import org.opends.server.types.CancelRequest;
+import org.opends.server.types.Control;
+import org.opends.server.types.Operation;
+import org.opends.server.types.RawAttribute;
+import org.opends.server.types.RawModification;
 import org.opends.server.util.StaticUtils;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import static org.opends.server.util.CollectionUtils.*;
-import static org.opends.server.util.ServerConstants.*;
-import static org.testng.Assert.*;
-
 /**
  * A set of test cases for abandon operations.
  */
@@ -251,63 +274,47 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    // Establish a connection to the server and bind as a root user.
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+      long abandonRequests = ldapStatistics.getAbandonRequests();
+      long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
+      // Create an add request and send it to the server. Make sure to include
+      // the delay request control so it won't complete before we can send the
+      // abandon request.
+      ArrayList<RawAttribute> attributes = newArrayList(
+          newRawAttribute("objectClass", "top", "organizationalUnit"),
+          newRawAttribute("ou", "People"));
 
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+      AddRequestProtocolOp addRequest =
+          new AddRequestProtocolOp(ByteString.valueOfUtf8("ou=People,o=test"), attributes);
+      conn.writeMessage(addRequest, DelayPreOpPlugin.createDelayControlList(5000));
 
+      // Send the abandon request to the server.
+      conn.writeMessage(new AbandonRequestProtocolOp(2));
 
-    long abandonRequests   = ldapStatistics.getAbandonRequests();
-    long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
+      // Normally, abandoned operations don't receive a response. However, the
+      // testing configuration has been updated to ensure that if an operation
+      // does get abandoned, the server will return a response for it with a
+      // result code of "cancelled".
+      LDAPMessage message = conn.readMessage();
+      AddResponseProtocolOp addResponse = message.getAddResponseProtocolOp();
+      assertEquals(addResponse.getResultCode(), LDAPResultCode.CANCELED);
 
-
-    // Create an add request and send it to the server.  Make sure to include
-    // the delay request control so it won't complete before we can send the
-    // abandon request.
-    ArrayList<RawAttribute> attributes = new ArrayList<>();
-    attributes.add(new LDAPAttribute("objectClass", newArrayList("top", "organizationalUnit")));
-    attributes.add(new LDAPAttribute("ou", "People"));
-
-    AddRequestProtocolOp addRequest =
-         new AddRequestProtocolOp(ByteString.valueOfUtf8("ou=People,o=test"), attributes);
-    message = new LDAPMessage(2, addRequest,
-                       DelayPreOpPlugin.createDelayControlList(5000));
-    w.writeMessage(message);
-
-
-    // Send the abandon request to the server.
-    AbandonRequestProtocolOp abandonRequest = new AbandonRequestProtocolOp(2);
-    w.writeMessage(new LDAPMessage(3, abandonRequest));
-
-
-    // Normally, abandoned operations don't receive a response.  However, the
-    // testing configuration has been updated to ensure that if an operation
-    // does get abandoned, the server will return a response for it with a
-    // result code of "cancelled".
-    message = r.readMessage();
-    AddResponseProtocolOp addResponse = message.getAddResponseProtocolOp();
-    assertEquals(addResponse.getResultCode(), LDAPResultCode.CANCELED);
-
-    assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests+1);
-    waitForAbandon(abandonsCompleted+1);
-
-    s.close();
+      assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests + 1);
+      waitForAbandon(abandonsCompleted + 1);
+    }
   }
 
 
 
+  private RawAttribute newRawAttribute(String attrType, String... attrValues)
+  {
+    return new LDAPAttribute(attrType, newArrayList(attrValues));
+  }
+
   /**
    * Tests the ability to abandon a compare operation.
    *
@@ -319,58 +326,38 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    // Establish a connection to the server and bind as a root user.
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+      long abandonRequests   = ldapStatistics.getAbandonRequests();
+      long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+      // Create a compare request and send it to the server.  Make sure to include
+      // the delay request control so it won't complete before we can send the
+      // abandon request.
+      CompareRequestProtocolOp compareRequest =
+          new CompareRequestProtocolOp(ByteString.valueOfUtf8("o=test"), "o",
+              ByteString.valueOfUtf8("test"));
+      conn.writeMessage(compareRequest, DelayPreOpPlugin.createDelayControlList(5000));
 
 
-    long abandonRequests   = ldapStatistics.getAbandonRequests();
-    long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
+      // Send the abandon request to the server and wait a few seconds to ensure
+      // it has completed before closing the connection.
+      conn.writeMessage(new AbandonRequestProtocolOp(2));
 
 
-    // Create a compare request and send it to the server.  Make sure to include
-    // the delay request control so it won't complete before we can send the
-    // abandon request.
-    CompareRequestProtocolOp compareRequest =
-      new CompareRequestProtocolOp(ByteString.valueOfUtf8("o=test"), "o",
-                                   ByteString.valueOfUtf8("test"));
-    message = new LDAPMessage(2, compareRequest,
-                       DelayPreOpPlugin.createDelayControlList(5000));
-    w.writeMessage(message);
+      // Normally, abandoned operations don't receive a response.  However, the
+      // testing configuration has been updated to ensure that if an operation
+      // does get abandoned, the server will return a response for it with a
+      // result code of "cancelled".
+      LDAPMessage message = conn.readMessage();
+      CompareResponseProtocolOp compareResponse = message.getCompareResponseProtocolOp();
+      assertEquals(compareResponse.getResultCode(), LDAPResultCode.CANCELED);
 
-
-    // Send the abandon request to the server and wait a few seconds to ensure
-    // it has completed before closing the connection.
-    AbandonRequestProtocolOp abandonRequest = new AbandonRequestProtocolOp(2);
-    w.writeMessage(new LDAPMessage(3, abandonRequest));
-
-
-    // Normally, abandoned operations don't receive a response.  However, the
-    // testing configuration has been updated to ensure that if an operation
-    // does get abandoned, the server will return a response for it with a
-    // result code of "cancelled".
-    message = r.readMessage();
-    CompareResponseProtocolOp compareResponse =
-         message.getCompareResponseProtocolOp();
-    assertEquals(compareResponse.getResultCode(), LDAPResultCode.CANCELED);
-
-    assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests+1);
-    waitForAbandon(abandonsCompleted+1);
-
-    s.close();
+      assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests+1);
+      waitForAbandon(abandonsCompleted+1);
+    }
   }
 
 
@@ -392,56 +379,34 @@
          "objectClass: device",
          "cn: test");
 
-    // Establish a connection to the server and bind as a root user.
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
+      long abandonRequests = ldapStatistics.getAbandonRequests();
+      long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
 
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+      // Create a delete request and send it to the server. Make sure to include
+      // the delay request control so it won't complete before we can send the
+      // abandon request.
+      DeleteRequestProtocolOp deleteRequest = new DeleteRequestProtocolOp(ByteString.valueOfUtf8("cn=test,o=test"));
+      conn.writeMessage(deleteRequest, DelayPreOpPlugin.createDelayControlList(5000));
 
+      // Send the abandon request to the server and wait a few seconds to ensure
+      // it has completed before closing the connection.
+      conn.writeMessage(new AbandonRequestProtocolOp(2));
 
-    long abandonRequests   = ldapStatistics.getAbandonRequests();
-    long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
+      // Normally, abandoned operations don't receive a response. However, the
+      // testing configuration has been updated to ensure that if an operation
+      // does get abandoned, the server will return a response for it with a
+      // result code of "cancelled".
+      LDAPMessage message = conn.readMessage();
+      DeleteResponseProtocolOp deleteResponse = message.getDeleteResponseProtocolOp();
+      assertEquals(deleteResponse.getResultCode(), LDAPResultCode.CANCELED);
 
-
-    // Create a delete request and send it to the server.  Make sure to include
-    // the delay request control so it won't complete before we can send the
-    // abandon request.
-    DeleteRequestProtocolOp deleteRequest =
-         new DeleteRequestProtocolOp(ByteString.valueOfUtf8("cn=test,o=test"));
-    message = new LDAPMessage(2, deleteRequest,
-                       DelayPreOpPlugin.createDelayControlList(5000));
-    w.writeMessage(message);
-
-
-    // Send the abandon request to the server and wait a few seconds to ensure
-    // it has completed before closing the connection.
-    AbandonRequestProtocolOp abandonRequest = new AbandonRequestProtocolOp(2);
-    w.writeMessage(new LDAPMessage(3, abandonRequest));
-
-
-    // Normally, abandoned operations don't receive a response.  However, the
-    // testing configuration has been updated to ensure that if an operation
-    // does get abandoned, the server will return a response for it with a
-    // result code of "cancelled".
-    message = r.readMessage();
-    DeleteResponseProtocolOp deleteResponse =
-         message.getDeleteResponseProtocolOp();
-    assertEquals(deleteResponse.getResultCode(), LDAPResultCode.CANCELED);
-
-    assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests+1);
-    waitForAbandon(abandonsCompleted+1);
-
-    s.close();
+      assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests + 1);
+      waitForAbandon(abandonsCompleted + 1);
+    }
   }
 
 
@@ -457,57 +422,34 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    // Establish a connection to the server and bind as a root user.
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+      long abandonRequests = ldapStatistics.getAbandonRequests();
+      long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
+      // Create a "Who Am I?" extended operation and send it to the server. Make
+      // sure to include the delay request control so it won't complete before we
+      // can send the abandon request.
+      ExtendedRequestProtocolOp whoAmIRequest = new ExtendedRequestProtocolOp(OID_WHO_AM_I_REQUEST, null);
+      conn.writeMessage(whoAmIRequest, DelayPreOpPlugin.createDelayControlList(5000));
 
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+      // Send the abandon request to the server and wait a few seconds to ensure
+      // it has completed before closing the connection.
+      conn.writeMessage(new AbandonRequestProtocolOp(2));
 
+      // Normally, abandoned operations don't receive a response. However, the
+      // testing configuration has been updated to ensure that if an operation
+      // does get abandoned, the server will return a response for it with a
+      // result code of "cancelled".
+      LDAPMessage message = conn.readMessage();
+      ExtendedResponseProtocolOp extendedResponse = message.getExtendedResponseProtocolOp();
+      assertEquals(extendedResponse.getResultCode(), LDAPResultCode.CANCELED);
 
-    long abandonRequests   = ldapStatistics.getAbandonRequests();
-    long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
-
-
-    // Create a "Who Am I?" extended operation and send it to the server.  Make
-    // sure to include the delay request control so it won't complete before we
-    // can send the abandon request.
-    ExtendedRequestProtocolOp whoAmIRequest =
-         new ExtendedRequestProtocolOp(OID_WHO_AM_I_REQUEST, null);
-    message = new LDAPMessage(2, whoAmIRequest,
-                       DelayPreOpPlugin.createDelayControlList(5000));
-    w.writeMessage(message);
-
-
-    // Send the abandon request to the server and wait a few seconds to ensure
-    // it has completed before closing the connection.
-    AbandonRequestProtocolOp abandonRequest = new AbandonRequestProtocolOp(2);
-    w.writeMessage(new LDAPMessage(3, abandonRequest));
-
-
-    // Normally, abandoned operations don't receive a response.  However, the
-    // testing configuration has been updated to ensure that if an operation
-    // does get abandoned, the server will return a response for it with a
-    // result code of "cancelled".
-    message = r.readMessage();
-    ExtendedResponseProtocolOp extendedResponse =
-         message.getExtendedResponseProtocolOp();
-    assertEquals(extendedResponse.getResultCode(), LDAPResultCode.CANCELED);
-
-    assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests+1);
-    waitForAbandon(abandonsCompleted+1);
-
-    s.close();
+      assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests + 1);
+      waitForAbandon(abandonsCompleted + 1);
+    }
   }
 
 
@@ -523,61 +465,37 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    // Establish a connection to the server and bind as a root user.
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+      long abandonRequests = ldapStatistics.getAbandonRequests();
+      long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
+      // Create a modify request and send it to the server. Make sure to include
+      // the delay request control so it won't complete before we can send the
+      // abandon request.
+      ArrayList<RawModification> mods = new ArrayList<>(1);
+      mods.add(new LDAPModification(ModificationType.REPLACE, new LDAPAttribute("description", "foo")));
 
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+      ModifyRequestProtocolOp modifyRequest = new ModifyRequestProtocolOp(ByteString.valueOfUtf8("o=test"), mods);
+      conn.writeMessage(modifyRequest, DelayPreOpPlugin.createDelayControlList(5000));
 
+      // Send the abandon request to the server and wait a few seconds to ensure
+      // it has completed before closing the connection.
+      conn.writeMessage(new AbandonRequestProtocolOp(2));
 
-    long abandonRequests   = ldapStatistics.getAbandonRequests();
-    long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
+      // Normally, abandoned operations don't receive a response. However, the
+      // testing configuration has been updated to ensure that if an operation
+      // does get abandoned, the server will return a response for it with a
+      // result code of "cancelled".
+      LDAPMessage message = conn.readMessage();
+      ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
+      assertEquals(modifyResponse.getResultCode(), LDAPResultCode.CANCELED);
 
-
-    // Create a modify request and send it to the server.  Make sure to include
-    // the delay request control so it won't complete before we can send the
-    // abandon request.
-    ArrayList<RawModification> mods = new ArrayList<>(1);
-    mods.add(new LDAPModification(ModificationType.REPLACE,
-                                  new LDAPAttribute("description", "foo")));
-
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(ByteString.valueOfUtf8("o=test"), mods);
-    message = new LDAPMessage(2, modifyRequest,
-                       DelayPreOpPlugin.createDelayControlList(5000));
-    w.writeMessage(message);
-
-
-    // Send the abandon request to the server and wait a few seconds to ensure
-    // it has completed before closing the connection.
-    AbandonRequestProtocolOp abandonRequest = new AbandonRequestProtocolOp(2);
-    w.writeMessage(new LDAPMessage(3, abandonRequest));
-
-
-    // Normally, abandoned operations don't receive a response.  However, the
-    // testing configuration has been updated to ensure that if an operation
-    // does get abandoned, the server will return a response for it with a
-    // result code of "cancelled".
-    message = r.readMessage();
-    ModifyResponseProtocolOp modifyResponse =
-         message.getModifyResponseProtocolOp();
-    assertEquals(modifyResponse.getResultCode(), LDAPResultCode.CANCELED);
-
-    assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests+1);
-    waitForAbandon(abandonsCompleted+1);
-
-    s.close();
+      assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests + 1);
+      waitForAbandon(abandonsCompleted + 1);
+    }
   }
 
 
@@ -599,57 +517,35 @@
          "objectClass: device",
          "cn: test");
 
-    // Establish a connection to the server and bind as a root user.
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
+      long abandonRequests = ldapStatistics.getAbandonRequests();
+      long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
 
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+      // Create a modify DN request and send it to the server. Make sure to
+      // include the delay request control so it won't complete before we can send
+      // the abandon request.
+      ModifyDNRequestProtocolOp modifyDNRequest = new ModifyDNRequestProtocolOp(
+          ByteString.valueOfUtf8("cn=test,o=test"), ByteString.valueOfUtf8("cn=test2"), true);
+      conn.writeMessage(modifyDNRequest, DelayPreOpPlugin.createDelayControlList(5000));
 
+      // Send the abandon request to the server and wait a few seconds to ensure
+      // it has completed before closing the connection.
+      conn.writeMessage(new AbandonRequestProtocolOp(2));
 
-    long abandonRequests   = ldapStatistics.getAbandonRequests();
-    long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
+      // Normally, abandoned operations don't receive a response. However, the
+      // testing configuration has been updated to ensure that if an operation
+      // does get abandoned, the server will return a response for it with a
+      // result code of "cancelled".
+      LDAPMessage message = conn.readMessage();
+      ModifyDNResponseProtocolOp modifyDNResponse = message.getModifyDNResponseProtocolOp();
+      assertEquals(modifyDNResponse.getResultCode(), LDAPResultCode.CANCELED);
 
-
-    // Create a modify DN request and send it to the server.  Make sure to
-    // include the delay request control so it won't complete before we can send
-    // the abandon request.
-    ModifyDNRequestProtocolOp modifyDNRequest =
-         new ModifyDNRequestProtocolOp(ByteString.valueOfUtf8("cn=test,o=test"),
-                                       ByteString.valueOfUtf8("cn=test2"), true);
-    message = new LDAPMessage(2, modifyDNRequest,
-                       DelayPreOpPlugin.createDelayControlList(5000));
-    w.writeMessage(message);
-
-
-    // Send the abandon request to the server and wait a few seconds to ensure
-    // it has completed before closing the connection.
-    AbandonRequestProtocolOp abandonRequest = new AbandonRequestProtocolOp(2);
-    w.writeMessage(new LDAPMessage(3, abandonRequest));
-
-
-    // Normally, abandoned operations don't receive a response.  However, the
-    // testing configuration has been updated to ensure that if an operation
-    // does get abandoned, the server will return a response for it with a
-    // result code of "cancelled".
-    message = r.readMessage();
-    ModifyDNResponseProtocolOp modifyDNResponse =
-         message.getModifyDNResponseProtocolOp();
-    assertEquals(modifyDNResponse.getResultCode(), LDAPResultCode.CANCELED);
-
-    assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests+1);
-    waitForAbandon(abandonsCompleted+1);
-
-    s.close();
+      assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests + 1);
+      waitForAbandon(abandonsCompleted + 1);
+    }
   }
 
 
@@ -665,62 +561,37 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    // Establish a connection to the server and bind as a root user.
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+      long abandonRequests = ldapStatistics.getAbandonRequests();
+      long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
+      // Create a search request and send it to the server. Make sure to include
+      // the delay request control so it won't complete before we can send the
+      // abandon request.
+      SearchRequestProtocolOp searchRequest =
+          new SearchRequestProtocolOp(ByteString.valueOfUtf8("o=test"), SearchScope.BASE_OBJECT,
+              DereferenceAliasesPolicy.NEVER, 0, 0, false, LDAPFilter.decode("(match=false)"),
+              new LinkedHashSet<String>());
+      conn.writeMessage(searchRequest, DelayPreOpPlugin.createDelayControlList(5000));
 
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+      // Send the abandon request to the server and wait a few seconds to ensure
+      // it has completed before closing the connection.
+      conn.writeMessage(new AbandonRequestProtocolOp(2));
 
+      // Normally, abandoned operations don't receive a response. However, the
+      // testing configuration has been updated to ensure that if an operation
+      // does get abandoned, the server will return a response for it with a
+      // result code of "cancelled".
+      LDAPMessage message = conn.readMessage();
+      SearchResultDoneProtocolOp searchDone = message.getSearchResultDoneProtocolOp();
+      assertEquals(searchDone.getResultCode(), LDAPResultCode.CANCELED);
 
-    long abandonRequests   = ldapStatistics.getAbandonRequests();
-    long abandonsCompleted = ldapStatistics.getOperationsAbandoned();
-
-
-    // Create a search request and send it to the server.  Make sure to include
-    // the delay request control so it won't complete before we can send the
-    // abandon request.
-    SearchRequestProtocolOp searchRequest =
-         new SearchRequestProtocolOp(ByteString.valueOfUtf8("o=test"),
-                                     SearchScope.BASE_OBJECT,
-                                     DereferenceAliasesPolicy.NEVER, 0,
-                                     0, false,
-                                     LDAPFilter.decode("(match=false)"),
-                                     new LinkedHashSet<String>());
-    message = new LDAPMessage(2, searchRequest,
-                       DelayPreOpPlugin.createDelayControlList(5000));
-    w.writeMessage(message);
-
-
-    // Send the abandon request to the server and wait a few seconds to ensure
-    // it has completed before closing the connection.
-    AbandonRequestProtocolOp abandonRequest = new AbandonRequestProtocolOp(2);
-    w.writeMessage(new LDAPMessage(3, abandonRequest));
-
-
-    // Normally, abandoned operations don't receive a response.  However, the
-    // testing configuration has been updated to ensure that if an operation
-    // does get abandoned, the server will return a response for it with a
-    // result code of "cancelled".
-    message = r.readMessage();
-    SearchResultDoneProtocolOp searchDone =
-         message.getSearchResultDoneProtocolOp();
-    assertEquals(searchDone.getResultCode(), LDAPResultCode.CANCELED);
-
-    assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests+1);
-    waitForAbandon(abandonsCompleted+1);
-
-    s.close();
+      assertEquals(ldapStatistics.getAbandonRequests(), abandonRequests + 1);
+      waitForAbandon(abandonsCompleted + 1);
+    }
   }
 
 
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/core/AddOperationTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/core/AddOperationTestCase.java
index 5cdb541..1d477e6 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/core/AddOperationTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/core/AddOperationTestCase.java
@@ -35,6 +35,7 @@
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.requests.AddRequest;
 import org.forgerock.opendj.ldap.schema.AttributeType;
 import org.opends.server.TestCaseUtils;
 import org.opends.server.api.Backend;
@@ -42,7 +43,6 @@
 import org.opends.server.plugins.ShortCircuitPlugin;
 import org.opends.server.plugins.UpdatePreOpPlugin;
 import org.opends.server.protocols.ldap.AddRequestProtocolOp;
-import org.opends.server.protocols.ldap.AddResponseProtocolOp;
 import org.opends.server.protocols.ldap.BindRequestProtocolOp;
 import org.opends.server.protocols.ldap.BindResponseProtocolOp;
 import org.opends.server.protocols.ldap.LDAPAttribute;
@@ -50,6 +50,7 @@
 import org.opends.server.tools.LDAPModify;
 import org.opends.server.tools.LDAPReader;
 import org.opends.server.tools.LDAPWriter;
+import org.opends.server.tools.RemoteConnection;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.Attributes;
 import org.opends.server.types.CancelRequest;
@@ -69,6 +70,7 @@
 import org.testng.annotations.Test;
 
 import static org.assertj.core.api.Assertions.*;
+import static org.forgerock.opendj.ldap.requests.Requests.*;
 import static org.opends.server.TestCaseUtils.*;
 import static org.opends.server.protocols.internal.InternalClientConnection.*;
 import static org.opends.server.protocols.ldap.LDAPConstants.*;
@@ -631,28 +633,23 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    bind(r, w);
+      long addRequests  = ldapStatistics.getAddRequests();
+      long addResponses = ldapStatistics.getAddResponses();
 
-    ArrayList<RawAttribute> attrs = newRawAttributes(
-        new LDAPAttribute("objectClass", newArrayList("top", "organizationalUnit")),
-        new LDAPAttribute("ou", "People"),
-        new LDAPAttribute("creatorsName", "cn=Directory Manager"),
-        new LDAPAttribute("createTimestamp", "20060101000000Z"));
+      AddRequest addRequest = newAddRequest("ou=People,o=test")
+          .addAttribute("objectClass", "top", "organizationalUnit")
+          .addAttribute("ou", "People")
+          .addAttribute("creatorsName", "cn=Directory Manager")
+          .addAttribute("createTimestamp", "20060101000000Z");
+      addFailure(conn, addRequest);
 
-    long addRequests  = ldapStatistics.getAddRequests();
-    long addResponses = ldapStatistics.getAddResponses();
-
-    addSuccess(r, w, attrs);
-
-    assertEquals(ldapStatistics.getAddRequests(), addRequests+1);
-    waitForAddResponsesStat(addResponses+1);
-
-    StaticUtils.close(s);
+      assertEquals(ldapStatistics.getAddRequests(), addRequests+1);
+      waitForAddResponsesStat(addResponses+1);
+    }
   }
 
   /**
@@ -1202,30 +1199,26 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    bind(r, w);
+      DirectoryServer.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
 
-    ArrayList<RawAttribute> attrs = newRawAttributes(
-        new LDAPAttribute("objectClass", newArrayList("top", "organizationalUnit")),
-        new LDAPAttribute("ou", "People"));
+      long addRequests  = ldapStatistics.getAddRequests();
+      long addResponses = ldapStatistics.getAddResponses();
 
-    DirectoryServer.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
+      AddRequest addRequest =
+          newAddRequest("ou=People,o=test")
+          .addAttribute("objectClass", "top", "organizationalUnit")
+          .addAttribute("ou", "People");
+      addFailure(conn, addRequest);
 
-    long addRequests  = ldapStatistics.getAddRequests();
-    long addResponses = ldapStatistics.getAddResponses();
+      assertEquals(ldapStatistics.getAddRequests(), addRequests+1);
+      waitForAddResponsesStat(addResponses+1);
 
-    addSuccess(r, w, attrs);
-
-    assertEquals(ldapStatistics.getAddRequests(), addRequests+1);
-    waitForAddResponsesStat(addResponses+1);
-
-    StaticUtils.close(s);
-
-    DirectoryServer.setWritabilityMode(WritabilityMode.ENABLED);
+      DirectoryServer.setWritabilityMode(WritabilityMode.ENABLED);
+    }
   }
 
   private void bind(LDAPReader r, LDAPWriter w) throws Exception
@@ -1239,14 +1232,10 @@
     assertEquals(bindResponse.getResultCode(), 0);
   }
 
-  private void addSuccess(LDAPReader r, LDAPWriter w,
-      ArrayList<RawAttribute> attrs) throws Exception
+  private void addFailure(RemoteConnection conn, AddRequest addRequest) throws Exception
   {
-    writeAddRequest(w, attrs, null);
-
-    LDAPMessage message = r.readMessage();
-    AddResponseProtocolOp addResponse = message.getAddResponseProtocolOp();
-    assertFalse(addResponse.getResultCode() == 0);
+    LDAPMessage message = conn.add(addRequest, false);
+    assertNotEquals(message.getAddResponseProtocolOp().getResultCode(), ResultCode.SUCCESS.intValue());
   }
 
   /**
@@ -1325,31 +1314,27 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    bind(r, w);
+      Backend<?> b = DirectoryServer.getBackend(DN.valueOf("o=test"));
+      b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
 
-    ArrayList<RawAttribute> attrs = newRawAttributes(
-        new LDAPAttribute("objectClass", newArrayList("top", "organizationalUnit")),
-        new LDAPAttribute("ou", "People"));
+      long addRequests  = ldapStatistics.getAddRequests();
+      long addResponses = ldapStatistics.getAddResponses();
 
-    Backend<?> b = DirectoryServer.getBackend(DN.valueOf("o=test"));
-    b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
+      AddRequest addRequest =
+          newAddRequest("ou=People,o=test")
+          .addAttribute("objectClass", "top", "organizationalUnit")
+          .addAttribute("ou", "People");
+      addFailure(conn, addRequest);
 
-    long addRequests  = ldapStatistics.getAddRequests();
-    long addResponses = ldapStatistics.getAddResponses();
+      assertEquals(ldapStatistics.getAddRequests(), addRequests+1);
+      waitForAddResponsesStat(addResponses+1);
 
-    addSuccess(r, w, attrs);
-
-    assertEquals(ldapStatistics.getAddRequests(), addRequests+1);
-    waitForAddResponsesStat(addResponses+1);
-
-    StaticUtils.close(s);
-
-    b.setWritabilityMode(WritabilityMode.ENABLED);
+      b.setWritabilityMode(WritabilityMode.ENABLED);
+    }
   }
 
   /**
@@ -1547,8 +1532,7 @@
     }
   }
 
-  private void writeAddRequest(LDAPWriter w, ArrayList<RawAttribute> attrs,
-      String section) throws IOException
+  private void writeAddRequest(LDAPWriter w, List<RawAttribute> attrs, String section) throws IOException
   {
     AddRequestProtocolOp addRequest = new AddRequestProtocolOp(ByteString.valueOfUtf8("ou=People,o=test"), attrs);
     List<Control> controls = section != null
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/core/DeleteOperationTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/core/DeleteOperationTestCase.java
index 84d8cc5..c5fd5ec 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/core/DeleteOperationTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/core/DeleteOperationTestCase.java
@@ -22,11 +22,10 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS.
+ *      Portions Copyright 2011-2016 ForgeRock AS.
  */
 package org.opends.server.core;
 
-import java.net.Socket;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -37,15 +36,18 @@
 import org.opends.server.api.Backend;
 import org.opends.server.plugins.DisconnectClientPlugin;
 import org.opends.server.plugins.ShortCircuitPlugin;
-import org.opends.server.protocols.ldap.BindRequestProtocolOp;
-import org.opends.server.protocols.ldap.BindResponseProtocolOp;
 import org.opends.server.protocols.ldap.DeleteRequestProtocolOp;
 import org.opends.server.protocols.ldap.LDAPMessage;
 import org.opends.server.tools.LDAPDelete;
-import org.opends.server.tools.LDAPWriter;
-import org.opends.server.types.*;
+import org.opends.server.tools.RemoteConnection;
+import org.opends.server.types.CancelRequest;
+import org.opends.server.types.CancelResult;
+import org.opends.server.types.Control;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
 import org.opends.server.types.LockManager.DNLock;
-import org.opends.server.util.StaticUtils;
+import org.opends.server.types.Operation;
+import org.opends.server.types.WritabilityMode;
 import org.opends.server.workflowelement.localbackend.LocalBackendDeleteOperation;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.Test;
@@ -721,38 +723,21 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
-
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse =
-         message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
-
-
-    DeleteRequestProtocolOp deleteRequest =
-         new DeleteRequestProtocolOp(ByteString.valueOfUtf8("o=test"));
-    message = new LDAPMessage(2, deleteRequest,
-         DisconnectClientPlugin.createDisconnectControlList("PreParse"));
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    if (message != null)
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      // If we got an element back, then it must be a notice of disconnect
-      // unsolicited notification.
-      assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
-    }
+      conn.bind("cn=Directory Manager", "password");
 
-    StaticUtils.close(s);
+      DeleteRequestProtocolOp deleteRequest = new DeleteRequestProtocolOp(ByteString.valueOfUtf8("o=test"));
+      conn.writeMessage(deleteRequest, DisconnectClientPlugin.createDisconnectControlList("PreParse"));
+
+      LDAPMessage message = conn.readMessage();
+      if (message != null)
+      {
+        // If we got an element back, then it must be a notice of disconnect
+        // unsolicited notification.
+        assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+      }
+    }
   }
 
 
@@ -768,39 +753,21 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
-
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse =
-         message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
-
-
-    DeleteRequestProtocolOp deleteRequest =
-         new DeleteRequestProtocolOp(ByteString.valueOfUtf8("o=test"));
-    message = new LDAPMessage(2, deleteRequest,
-         DisconnectClientPlugin.createDisconnectControlList(
-              "PreOperation"));
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    if (message != null)
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      // If we got an element back, then it must be a notice of disconnect
-      // unsolicited notification.
-      assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
-    }
+      conn.bind("cn=Directory Manager", "password");
 
-    StaticUtils.close(s);
+      DeleteRequestProtocolOp deleteRequest = new DeleteRequestProtocolOp(ByteString.valueOfUtf8("o=test"));
+      conn.writeMessage(deleteRequest, DisconnectClientPlugin.createDisconnectControlList("PreOperation"));
+
+      LDAPMessage message = conn.readMessage();
+      if (message != null)
+      {
+        // If we got an element back, then it must be a notice of disconnect
+        // unsolicited notification.
+        assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+      }
+    }
   }
 
 
@@ -816,39 +783,22 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
-
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse =
-         message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
-
-
-    DeleteRequestProtocolOp deleteRequest =
-         new DeleteRequestProtocolOp(ByteString.valueOfUtf8("o=test"));
-    message = new LDAPMessage(2, deleteRequest,
-         DisconnectClientPlugin.createDisconnectControlList(
-              "PostOperation"));
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    if (message != null)
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      // If we got an element back, then it must be a notice of disconnect
-      // unsolicited notification.
-      assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
-    }
+      conn.bind("cn=Directory Manager", "password");
 
-    StaticUtils.close(s);
+      DeleteRequestProtocolOp deleteRequest = new DeleteRequestProtocolOp(ByteString.valueOfUtf8("o=test"));
+      conn.writeMessage(deleteRequest,
+          DisconnectClientPlugin.createDisconnectControlList("PostOperation"));
+
+      LDAPMessage message = conn.readMessage();
+      if (message != null)
+      {
+        // If we got an element back, then it must be a notice of disconnect
+        // unsolicited notification.
+        assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+      }
+    }
   }
 
 
@@ -864,34 +814,17 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse =
-         message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
-
-
-    DeleteRequestProtocolOp deleteRequest =
-         new DeleteRequestProtocolOp(ByteString.valueOfUtf8("o=test"));
-    message = new LDAPMessage(2, deleteRequest,
-         DisconnectClientPlugin.createDisconnectControlList(
-              "PostResponse"));
-    w.writeMessage(message);
+      DeleteRequestProtocolOp deleteRequest = new DeleteRequestProtocolOp(ByteString.valueOfUtf8("o=test"));
+      conn.writeMessage(deleteRequest, DisconnectClientPlugin.createDisconnectControlList("PostResponse"));
 
 responseLoop:
     while (true)
     {
-      message = r.readMessage();
+      LDAPMessage message = conn.readMessage();
       if (message == null)
       {
         // The connection has been closed.
@@ -909,15 +842,12 @@
           break responseLoop;
         default:
           // This is a problem.  It's an unexpected response.
-          StaticUtils.close(s);
-
           throw new Exception("Unexpected response message " + message +
                               " encountered in " +
                               "testDisconnectInPostResponseDelete");
       }
     }
-
-    StaticUtils.close(s);
+    }
   }
 
 
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/core/IdleTimeLimitTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/core/IdleTimeLimitTestCase.java
index 69d6bca..db50bb1 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/core/IdleTimeLimitTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/core/IdleTimeLimitTestCase.java
@@ -22,31 +22,23 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS.
+ *      Portions Copyright 2011-2016 ForgeRock AS.
  */
 package org.opends.server.core;
 
+import static org.testng.Assert.*;
 
+import java.io.IOException;
 
-import java.net.Socket;
-
+import org.opends.server.TestCaseUtils;
+import org.opends.server.protocols.ldap.ExtendedResponseProtocolOp;
+import org.opends.server.protocols.ldap.LDAPConstants;
+import org.opends.server.tools.RemoteConnection;
+import org.opends.server.types.LDAPException;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import org.opends.server.TestCaseUtils;
-import org.forgerock.opendj.ldap.ByteString;
-import org.opends.server.protocols.ldap.*;
-import org.opends.server.tools.LDAPWriter;
-import org.opends.server.util.StaticUtils;
-
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases that involve disconnecting clients due to the idle time
- * limit.
- */
+/** A set of test cases that involve disconnecting clients due to the idle time limit. */
 public class IdleTimeLimitTestCase
        extends CoreTestCase
 {
@@ -77,27 +69,12 @@
       "set-global-configuration-prop",
       "--set", "idle-time-limit:5 seconds");
 
-
-    Socket s = null;
-    try
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-      LDAPWriter w = new LDAPWriter(s);
-      org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-      TestCaseUtils.configureSocket(s);
-
-      LDAPMessage m = r.readMessage();
-      ExtendedResponseProtocolOp extendedResponse =
-           m.getExtendedResponseProtocolOp();
-      assertEquals(extendedResponse.getOID(),
-                   LDAPConstants.OID_NOTICE_OF_DISCONNECTION);
-
-      assertNull(r.readMessage());
+      readNoticeOfDisconnectionMessage(conn);
     }
     finally
     {
-      StaticUtils.close(s);
-
       TestCaseUtils.dsconfig(
         "set-global-configuration-prop",
         "--set", "idle-time-limit:0 seconds");
@@ -135,39 +112,14 @@
       "--set", "idle-time-limit:5 seconds");
 
 
-    Socket s = null;
-    try
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-      LDAPWriter w = new LDAPWriter(s);
-      org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-      TestCaseUtils.configureSocket(s);
+      conn.bind("uid=test.user,o=test", "password");
 
-
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage m = new LDAPMessage(1, bindRequest);
-      w.writeMessage(m);
-
-
-      m = r.readMessage();
-      BindResponseProtocolOp bindResponse = m.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), 0);
-
-
-      m = r.readMessage();
-      ExtendedResponseProtocolOp extendedResponse =
-           m.getExtendedResponseProtocolOp();
-      assertEquals(extendedResponse.getOID(),
-                   LDAPConstants.OID_NOTICE_OF_DISCONNECTION);
-
-      assertNull(r.readMessage());
+      readNoticeOfDisconnectionMessage(conn);
     }
     finally
     {
-      StaticUtils.close(s);
-
       TestCaseUtils.dsconfig(
         "set-global-configuration-prop",
         "--set", "idle-time-limit:0 seconds");
@@ -201,39 +153,19 @@
     );
 
 
-    Socket s = null;
-    try
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-      LDAPWriter w = new LDAPWriter(s);
-      org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-      TestCaseUtils.configureSocket(s);
+      conn.bind("uid=test.user,o=test", "password");
 
-
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(
-           ByteString.valueOfUtf8("uid=test.user,o=test"), 3,
-           ByteString.valueOfUtf8("password"));
-      LDAPMessage m = new LDAPMessage(1, bindRequest);
-      w.writeMessage(m);
-
-
-      m = r.readMessage();
-      BindResponseProtocolOp bindResponse = m.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), 0);
-
-
-      m = r.readMessage();
-      ExtendedResponseProtocolOp extendedResponse =
-           m.getExtendedResponseProtocolOp();
-      assertEquals(extendedResponse.getOID(),
-                   LDAPConstants.OID_NOTICE_OF_DISCONNECTION);
-
-      assertNull(r.readMessage());
-    }
-    finally
-    {
-      StaticUtils.close(s);
+      readNoticeOfDisconnectionMessage(conn);
     }
   }
-}
 
+  private void readNoticeOfDisconnectionMessage(RemoteConnection conn) throws IOException, LDAPException
+  {
+    ExtendedResponseProtocolOp extendedResponse = conn.readMessage().getExtendedResponseProtocolOp();
+    assertEquals(extendedResponse.getOID(), LDAPConstants.OID_NOTICE_OF_DISCONNECTION);
+
+    assertNull(conn.readMessage());
+  }
+}
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/core/ModifyOperationTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/core/ModifyOperationTestCase.java
index b0103fb..354fdd9 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/core/ModifyOperationTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/core/ModifyOperationTestCase.java
@@ -26,7 +26,6 @@
  */
 package org.opends.server.core;
 
-import java.net.Socket;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -36,6 +35,8 @@
 import org.forgerock.opendj.ldap.ModificationType;
 import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.SearchScope;
+import org.forgerock.opendj.ldap.requests.ModifyRequest;
+import org.forgerock.opendj.ldap.requests.Requests;
 import org.opends.server.TestCaseUtils;
 import org.opends.server.api.Backend;
 import org.opends.server.plugins.DisconnectClientPlugin;
@@ -44,8 +45,6 @@
 import org.opends.server.protocols.internal.InternalClientConnection;
 import org.opends.server.protocols.internal.InternalSearchOperation;
 import org.opends.server.protocols.internal.SearchRequest;
-import org.opends.server.protocols.ldap.BindRequestProtocolOp;
-import org.opends.server.protocols.ldap.BindResponseProtocolOp;
 import org.opends.server.protocols.ldap.LDAPAttribute;
 import org.opends.server.protocols.ldap.LDAPControl;
 import org.opends.server.protocols.ldap.LDAPMessage;
@@ -53,7 +52,7 @@
 import org.opends.server.protocols.ldap.ModifyRequestProtocolOp;
 import org.opends.server.protocols.ldap.ModifyResponseProtocolOp;
 import org.opends.server.tools.LDAPModify;
-import org.opends.server.tools.LDAPWriter;
+import org.opends.server.tools.RemoteConnection;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.Attributes;
 import org.opends.server.types.CancelRequest;
@@ -69,7 +68,6 @@
 import org.opends.server.types.WritabilityMode;
 import org.opends.server.util.Base64;
 import org.opends.server.util.ServerConstants;
-import org.opends.server.util.StaticUtils;
 import org.opends.server.workflowelement.localbackend.LocalBackendModifyOperation;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
@@ -78,6 +76,8 @@
 import org.testng.annotations.Test;
 
 import static org.assertj.core.api.Assertions.*;
+import static org.forgerock.opendj.ldap.ModificationType.*;
+import static org.forgerock.opendj.ldap.requests.Requests.*;
 import static org.opends.server.TestCaseUtils.*;
 import static org.opends.server.protocols.internal.InternalClientConnection.*;
 import static org.opends.server.protocols.internal.Requests.*;
@@ -123,39 +123,39 @@
 
     List<Control> noControls = new ArrayList<>();
 
-    LDAPAttribute ldapAttr = new LDAPAttribute("description", "foo");
-    List<RawModification> ldapMods = newRawModifications(add(ldapAttr));
+    List<RawModification> ldapMods = newRawModifications(ADD, "description", "foo");
 
     opList.add(newModifyOperation(null, ByteString.empty(), ldapMods));
     opList.add(newModifyOperation(noControls, ByteString.empty(), ldapMods));
     opList.add(newModifyOperation(null, ByteString.valueOfUtf8("o=test"), ldapMods));
     opList.add(newModifyOperation(noControls, ByteString.valueOfUtf8("o=test"), ldapMods));
 
-    ldapMods = newRawModifications(delete(ldapAttr));
+    ldapMods = newRawModifications(DELETE, "description", "foo");
 
     opList.add(newModifyOperation(null, ByteString.empty(), ldapMods));
     opList.add(newModifyOperation(noControls, ByteString.empty(), ldapMods));
     opList.add(newModifyOperation(null, ByteString.valueOfUtf8("o=test"), ldapMods));
     opList.add(newModifyOperation(noControls, ByteString.valueOfUtf8("o=test"), ldapMods));
 
-    ldapMods = newRawModifications(replace(ldapAttr));
+    ldapMods = newRawModifications(REPLACE, "description", "foo");
 
     opList.add(newModifyOperation(null, ByteString.empty(), ldapMods));
     opList.add(newModifyOperation(noControls, ByteString.empty(), ldapMods));
     opList.add(newModifyOperation(null, ByteString.valueOfUtf8("o=test"), ldapMods));
     opList.add(newModifyOperation(noControls, ByteString.valueOfUtf8("o=test"), ldapMods));
 
-    String value2 = "bar";
-    LDAPAttribute ldapAttr2 = new LDAPAttribute("description", value2);
-    ldapMods = newRawModifications(delete(ldapAttr), add(ldapAttr2));
+    ldapMods = newArrayList(
+        newRawModification(DELETE, "description", "foo"),
+        newRawModification(ADD, "description", "bar"));
 
     opList.add(newModifyOperation(null, ByteString.empty(), ldapMods));
     opList.add(newModifyOperation(noControls, ByteString.empty(), ldapMods));
     opList.add(newModifyOperation(null, ByteString.valueOfUtf8("o=test"), ldapMods));
     opList.add(newModifyOperation(noControls, ByteString.valueOfUtf8("o=test"), ldapMods));
 
-    ldapAttr2 = new LDAPAttribute("cn", value2);
-    ldapMods = newRawModifications(replace(ldapAttr), replace(ldapAttr2));
+    ldapMods = newArrayList(
+        newRawModification(REPLACE, "description", "foo"),
+        newRawModification(REPLACE, "cn", "bar"));
 
     opList.add(newModifyOperation(null, ByteString.empty(), ldapMods));
     opList.add(newModifyOperation(noControls, ByteString.empty(), ldapMods));
@@ -164,46 +164,39 @@
 
 
 
-    List<Modification> mods = newModifications(new Modification(ModificationType.ADD,
-        Attributes.create("description", "foo")));
+    List<Modification> mods = newModifications(ADD, "description", "foo");
 
     opList.add(newModifyOperation(null, DN.rootDN(), mods));
     opList.add(newModifyOperation(noControls, DN.rootDN(), mods));
     opList.add(newModifyOperation(null, DN.valueOf("o=test"), mods));
     opList.add(newModifyOperation(noControls, DN.valueOf("o=test"), mods));
 
-    mods = newModifications(new Modification(ModificationType.DELETE,
-        Attributes.create("description", "foo")));
+    mods = newModifications(DELETE, "description", "foo");
 
     opList.add(newModifyOperation(null, DN.rootDN(), mods));
     opList.add(newModifyOperation(noControls, DN.rootDN(), mods));
     opList.add(newModifyOperation(null, DN.valueOf("o=test"), mods));
     opList.add(newModifyOperation(noControls, DN.valueOf("o=test"), mods));
 
-    mods = newModifications(new Modification(ModificationType.REPLACE,
-        Attributes.create("description", "foo")));
+    mods = newModifications(REPLACE, "description", "foo");
 
     opList.add(newModifyOperation(null, DN.rootDN(), mods));
     opList.add(newModifyOperation(noControls, DN.rootDN(), mods));
     opList.add(newModifyOperation(null, DN.valueOf("o=test"), mods));
     opList.add(newModifyOperation(noControls, DN.valueOf("o=test"), mods));
 
-    mods = newModifications(
-        new Modification(ModificationType.DELETE,
-            Attributes.create("description", "foo")),
-        new Modification(ModificationType.ADD,
-            Attributes.create("description", "bar")));
+    mods = newArrayList(
+        newModification(DELETE, "description", "foo"),
+        newModification(ADD, "description", "bar"));
 
     opList.add(newModifyOperation(null, DN.rootDN(), mods));
     opList.add(newModifyOperation(noControls, DN.rootDN(), mods));
     opList.add(newModifyOperation(null, DN.valueOf("o=test"), mods));
     opList.add(newModifyOperation(noControls, DN.valueOf("o=test"), mods));
 
-    mods = newModifications(
-        new Modification(ModificationType.REPLACE,
-            Attributes.create("description", "foo")),
-        new Modification(ModificationType.REPLACE,
-            Attributes.create("cn", "bar")));
+    mods = newArrayList(
+        newModification(REPLACE, "description", "foo"),
+        newModification(REPLACE, "cn", "bar"));
 
     opList.add(newModifyOperation(null, DN.rootDN(), mods));
     opList.add(newModifyOperation(noControls, DN.rootDN(), mods));
@@ -299,18 +292,11 @@
   @Test
   public void testGetEntryDNInitiallyNull()
   {
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-    List<RawModification> mods = newRawModifications(replace(attr));
-
+    List<RawModification> mods = newRawModifications(REPLACE, "description", "foo");
     ModifyOperation modifyOperation = newModifyOperation(null, ByteString.empty(), mods);
     assertNotNull(modifyOperation.getEntryDN());
   }
 
-  private LDAPAttribute newLDAPAttribute(String attributeType, String... valueStrings)
-  {
-    return new LDAPAttribute(attributeType, newArrayList(valueStrings));
-  }
-
   /**
    * Tests the <CODE>getEntryDN</CODE> method for the case in which we expect
    * the DN to be initially non-null.
@@ -320,9 +306,7 @@
   @Test
   public void testGetEntryDNInitiallyNonNull() throws Exception
   {
-    List<Modification> mods = newModifications(
-        new Modification(ModificationType.REPLACE,
-            Attributes.create("description", "foo")));
+    List<Modification> mods = newModifications(REPLACE, "description", "foo");
     ModifyOperation modifyOperation = newModifyOperation(null, DN.rootDN(), mods);
     assertNotNull(modifyOperation.getEntryDN());
   }
@@ -339,9 +323,7 @@
   @Test
   public void testGetEntryDNNonNullChangedToNull() throws Exception
   {
-    List<Modification> mods = newModifications(
-        new Modification(ModificationType.REPLACE,
-            Attributes.create("description", "foo")));
+    List<Modification> mods = newModifications(REPLACE, "description", "foo");
     ModifyOperation modifyOperation = newModifyOperation(null, DN.rootDN(), mods);
     assertNotNull(modifyOperation.getEntryDN());
 
@@ -366,9 +348,7 @@
     List<RawModification> clonedMods = new ArrayList<>(rawMods);
     modifyOperation.setRawModifications(clonedMods);
 
-    LDAPAttribute attr = newLDAPAttribute("test", "test");
-
-    modifyOperation.addRawModification(replace(attr));
+    modifyOperation.addRawModification(newRawModification(REPLACE, "test", "test"));
 
     assertEquals(modifyOperation.getRawModifications().size(), rawMods.size() + 1);
 
@@ -444,10 +424,7 @@
              Attributes.create("description", "foo")));
 
 
-    List<Modification> mods = newModifications(
-        new Modification(ModificationType.REPLACE,
-            Attributes.create("l", "Austin")));
-
+    List<Modification> mods = newModifications(REPLACE, "l", "Austin");
     ModifyOperation modifyOperation =
         getRootConnection().processModify(DN.valueOf("o=test"), mods);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
@@ -467,8 +444,8 @@
   @Test
   public void testFailInvalidDN()
   {
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-    ModifyOperation modifyOperation = processModify("invaliddn", replace(attr));
+    RawModification mod = newRawModification(REPLACE, "description", "foo");
+    ModifyOperation modifyOperation = processModify("invaliddn", mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -482,8 +459,8 @@
   @Test
   public void testFailNoSuchSuffix()
   {
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-    ModifyOperation modifyOperation = processModify("o=nonexistent", replace(attr));
+    RawModification mod = newRawModification(REPLACE, "description", "foo");
+    ModifyOperation modifyOperation = processModify("o=nonexistent", mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -500,8 +477,8 @@
   public void testFailNoSuchParent(String baseDN)
          throws Exception
   {
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-    ModifyOperation modifyOperation = processModify("cn=test,ou=nosuchparent," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "description", "foo");
+    ModifyOperation modifyOperation = processModify("cn=test,ou=nosuchparent," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -518,14 +495,12 @@
   public void testFailNoSuchEntry(String baseDN)
          throws Exception
   {
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-    ModifyOperation modifyOperation = processModify("cn=nosuchentry," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "description", "foo");
+    ModifyOperation modifyOperation = processModify("cn=nosuchentry," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
 
-
-
   /**
    * Tests to ensure that a modify attempt fails if the modification doesn't
    * contain any changes.
@@ -555,8 +530,8 @@
     Entry e = DirectoryServer.getEntry(DN.valueOf("o=test"));
     assertThat(e.getAttribute(DirectoryServer.getAttributeType("description"))).isEmpty();
 
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-    ModifyOperation modifyOperation = processModify("o=test", replace(attr));
+    RawModification mod = newRawModification(REPLACE, "description", "foo");
+    ModifyOperation modifyOperation = processModify("o=test", mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -580,8 +555,7 @@
     List<Attribute> attrList = e.getAttribute(DirectoryServer.getAttributeType("o"));
     assertEquals(countValues(attrList), 1);
 
-    LDAPAttribute attr = newLDAPAttribute("o", "test2");
-    ModifyOperation modifyOperation = processModify("o=test", add(attr));
+    ModifyOperation modifyOperation = processModify("o=test", newRawModification(ADD, "o", "test2"));
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -607,8 +581,8 @@
     List<Attribute> attrList = e.getAttribute(DirectoryServer.getAttributeType("o"));
     assertEquals(countValues(attrList), 1);
 
-    LDAPAttribute attr = newLDAPAttribute("o;lang-en-us", "test");
-    ModifyOperation modifyOperation = processModify(baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "o;lang-en-us", "test");
+    ModifyOperation modifyOperation = processModify(baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -652,8 +626,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("displayName", "foo");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "displayName", "foo");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -684,8 +658,8 @@
          "userPassword: password",
          "ds-pwp-account-disabled: true");
 
-    LDAPAttribute attr = newLDAPAttribute("ds-pwp-account-disabled", "false");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "ds-pwp-account-disabled", "false");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -715,8 +689,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("displayName", "foo", "bar");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "displayName", "foo", "bar");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -747,34 +721,13 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("ds-pwp-account-disabled", "true", "false");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "ds-pwp-account-disabled", "true", "false");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
 
-  private LDAPModification replace(LDAPAttribute attr)
-  {
-    return new LDAPModification(ModificationType.REPLACE, attr);
-  }
-
-  private LDAPModification add(LDAPAttribute attr)
-  {
-    return new LDAPModification(ModificationType.ADD, attr);
-  }
-
-  private LDAPModification delete(LDAPAttribute attr)
-  {
-    return new LDAPModification(ModificationType.DELETE, attr);
-  }
-
-  private LDAPModification increment(LDAPAttribute attr)
-  {
-    return new LDAPModification(ModificationType.INCREMENT, attr);
-  }
-
-  private ModifyOperation processModify(String entryDN,
-      List<RawModification> mods)
+  private ModifyOperation processModify(String entryDN, List<RawModification> mods)
   {
     InternalClientConnection conn = getRootConnection();
     return conn.processModify(ByteString.valueOfUtf8(entryDN), mods);
@@ -816,8 +769,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("givenName", "Test");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "givenName", "Test");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -847,8 +800,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("description", "Foo", "Foo");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "description", "Foo", "Foo");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -879,8 +832,8 @@
          "userPassword: password",
          "manager: cn=boss," + baseDN);
 
-    LDAPAttribute attr = newLDAPAttribute("manager", "invaliddn");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "manager", "invaliddn");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -910,8 +863,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("manager", "invaliddn");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "manager", "invaliddn");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -941,8 +894,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("dc", "foo");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "dc", "foo");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.OBJECTCLASS_VIOLATION);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -974,9 +927,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("dc", "foo");
-    attr = newLDAPAttribute("objectClass", "extensibleObject");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "objectClass", "extensibleObject");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1006,8 +958,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("uid", "foo");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "uid", "foo");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1037,8 +989,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = new LDAPAttribute("uid");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "uid");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1068,8 +1020,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("uid", "test.user");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "uid", "test.user");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1099,8 +1051,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("givenName", "Foo");
-    ModifyOperation modifyOperation = processModify("givenName=Test,sn=User," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "givenName", "Foo");
+    ModifyOperation modifyOperation = processModify("givenName=Test,sn=User," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1130,8 +1082,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = new LDAPAttribute("givenName");
-    ModifyOperation modifyOperation = processModify("givenName=Test,sn=User," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "givenName");
+    ModifyOperation modifyOperation = processModify("givenName=Test,sn=User," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1161,8 +1113,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = new LDAPAttribute("displayName");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "displayName");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1194,8 +1146,8 @@
          "mail: foo",
          "mail: bar");
 
-    LDAPAttribute attr = newLDAPAttribute("mail", "foo");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "mail", "foo");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1226,8 +1178,8 @@
          "userPassword: password",
          "mail: foo");
 
-    LDAPAttribute attr = newLDAPAttribute("mail", "foo");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "mail", "foo");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1259,8 +1211,8 @@
          "mail: foo",
          "mail: bar");
 
-    LDAPAttribute attr = newLDAPAttribute("mail", "foo", "bar");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "mail", "foo", "bar");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1290,8 +1242,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = new LDAPAttribute("sn");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "sn");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1321,8 +1273,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("sn", "User");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "sn", "User");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1352,8 +1304,8 @@
          "userPassword: password",
          "mail: foo");
 
-    LDAPAttribute attr = newLDAPAttribute("description", "bar");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "description", "bar");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1385,8 +1337,7 @@
          "mail: foo");
 
     String dn = "uid=test.user," + baseDN;
-    LDAPAttribute attr = newLDAPAttribute("uid", "test.user");
-    ModifyOperation modifyOperation = processModify(dn, replace(attr));
+    ModifyOperation modifyOperation = processModify(dn, newRawModifications(REPLACE, "uid", "test.user"));
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -1424,8 +1375,9 @@
          "userPassword: password",
          "mail: foo");
 
-    LDAPAttribute attr = newLDAPAttribute("cn", "Test User");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr), add(attr));
+    RawModification delete = newRawModification(DELETE, "cn", "Test User");
+    RawModification add = newRawModification(ADD, "cn", "Test User");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete, add);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -1463,8 +1415,8 @@
          "userPassword: password",
          "mail: foo");
 
-    LDAPAttribute attr = newLDAPAttribute("givenName;lang-fr", "X");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "givenName;lang-fr", "X");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -1502,8 +1454,8 @@
          "userPassword: password",
          "mail: foo");
 
-    LDAPAttribute attr = new LDAPAttribute("description");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "description");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1533,8 +1485,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = new LDAPAttribute("description");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "description");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1564,8 +1516,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "description", "foo");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1596,9 +1548,9 @@
          "userPassword: password",
          "mail: foo");
 
-    LDAPAttribute attr = newLDAPAttribute("mail", "foo");
-    LDAPAttribute attr2 = newLDAPAttribute("mail", "bar");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr), add(attr2));
+    RawModification delete = newRawModification(DELETE, "mail", "foo");
+    RawModification add = newRawModification(ADD, "mail", "bar");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete, add);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1630,9 +1582,9 @@
          "mail: foo",
          "mail: bar");
 
-    LDAPAttribute attr = newLDAPAttribute("mail", "foo");
-    LDAPAttribute attr2 = new LDAPAttribute("mail", "baz");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr), add(attr2));
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN,
+        newRawModification(DELETE, "mail", "foo"),
+        newRawModification(ADD, "mail", "baz"));
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1663,9 +1615,9 @@
          "userPassword: password",
          "mail: foo");
 
-    LDAPAttribute attr = newLDAPAttribute("mail", "foo");
-    LDAPAttribute attr2 = newLDAPAttribute("mail", "bar", "baz");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr), add(attr2));
+    RawModification delete = newRawModification(DELETE, "mail", "foo");
+    RawModification add = newRawModification(ADD, "mail", "bar", "baz");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete, add);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -1694,8 +1646,8 @@
          "cn: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = new LDAPAttribute("displayName");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "displayName");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1725,8 +1677,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("displayName", "Foo");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "displayName", "Foo");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1756,8 +1708,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = new LDAPAttribute("objectClass");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "objectClass");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1787,8 +1739,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = new LDAPAttribute("objectClass");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, replace(attr));
+    RawModification mod = newRawModification(REPLACE, "objectClass");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1812,8 +1764,8 @@
          "objectClass: extensibleObject",
          "ou: People");
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "organizationalUnit");
-    ModifyOperation modifyOperation = processModify("ou=People," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "objectClass", "organizationalUnit");
+    ModifyOperation modifyOperation = processModify("ou=People," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1837,8 +1789,8 @@
          "objectClass: extensibleObject",
          "ou: People");
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "organization");
-    ModifyOperation modifyOperation = processModify("ou=People," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "objectClass", "organization");
+    ModifyOperation modifyOperation = processModify("ou=People," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -1870,8 +1822,8 @@
          "mail: foo",
          "employeeNumber: 1");
 
-    LDAPAttribute attr = newLDAPAttribute("employeeNumber", "1");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, increment(attr));
+    RawModification mod = newRawModification(INCREMENT, "employeeNumber", "1");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -1908,8 +1860,8 @@
          "mail: foo",
          "employeeNumber: 1");
 
-    LDAPAttribute attr = newLDAPAttribute("employeeNumber", "10");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, increment(attr));
+    RawModification mod = newRawModification(INCREMENT, "employeeNumber", "10");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -1946,8 +1898,8 @@
          "mail: foo",
          "employeeNumber: 1");
 
-    LDAPAttribute attr = newLDAPAttribute("employeeNumber", "-1");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, increment(attr));
+    RawModification mod = newRawModification(INCREMENT, "employeeNumber", "-1");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -1996,8 +1948,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("displayName", "1");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, increment(attr));
+    RawModification mod = newRawModification(INCREMENT, "displayName", "1");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -2028,8 +1980,8 @@
          "userPassword: password",
          "mail: 1");
 
-    LDAPAttribute attr = newLDAPAttribute("description", "notnumeric");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, increment(attr));
+    RawModification mod = newRawModification(INCREMENT, "description", "notnumeric");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -2061,8 +2013,8 @@
          "roomNumber: 1",
          "roomNumber: 2");
 
-    LDAPAttribute attr = newLDAPAttribute("roomNumber", "1");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, increment(attr));
+    RawModification mod = newRawModification(INCREMENT, "roomNumber", "1");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
   }
@@ -2093,8 +2045,8 @@
          "userPassword: password",
          "roomNumber: 1");
 
-    LDAPAttribute attr = new LDAPAttribute("roomNumber");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, increment(attr));
+    RawModification mod = newRawModification(INCREMENT, "roomNumber");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -2125,8 +2077,8 @@
          "userPassword: password",
          "roomNumber: 1");
 
-    LDAPAttribute attr = newLDAPAttribute("roomNumber", "1", "2");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, increment(attr));
+    RawModification mod = newRawModification(INCREMENT, "roomNumber", "1", "2");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -2156,8 +2108,8 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("employeeNumber", "1");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, increment(attr));
+    RawModification mod = newRawModification(INCREMENT, "employeeNumber", "1");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -2190,8 +2142,8 @@
          "mail: foo",
          "employeeNumber: 1");
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "extensibleObject");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "objectClass", "extensibleObject");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -2227,8 +2179,8 @@
          "mail: foo",
          "employeeNumber: 1");
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "extensibleObject");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "objectClass", "extensibleObject");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -2267,8 +2219,8 @@
          "mail: foo",
          "employeeNumber: 1");
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "inetOrgPerson");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "objectClass", "inetOrgPerson");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -2299,8 +2251,8 @@
          "mail: foo",
          "employeeNumber: 1");
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "organizationalUnit");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, delete(attr));
+    RawModification mod = newRawModification(DELETE, "objectClass", "organizationalUnit");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
   }
@@ -2330,41 +2282,22 @@
          "displayName: Test User",
          "userPassword: password");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
+      long modifyRequests = ldapStatistics.getModifyRequests();
+      long modifyResponses = ldapStatistics.getModifyResponses();
 
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse =
-         message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
+      ModifyRequest modifyRequest = Requests.newModifyRequest("uid=test.user," + baseDN)
+          .addModification(REPLACE, "entryUUID", "12345678-1234-1234-1234-1234567890ab");
+      LDAPMessage message = conn.modify(modifyRequest, false);
+      ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
+      assertFalse(modifyResponse.getResultCode() == 0);
 
-    LDAPAttribute attr = newLDAPAttribute("entryUUID", "12345678-1234-1234-1234-1234567890ab");
-    List<RawModification> mods = newRawModifications(replace(attr));
-
-    long modifyRequests  = ldapStatistics.getModifyRequests();
-    long modifyResponses = ldapStatistics.getModifyResponses();
-
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(
-                  ByteString.valueOfUtf8("uid=test.user," + baseDN), mods);
-    message = new LDAPMessage(2, modifyRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    ModifyResponseProtocolOp modifyResponse =
-         message.getModifyResponseProtocolOp();
-    assertFalse(modifyResponse.getResultCode() == 0);
-
-    assertEquals(ldapStatistics.getModifyRequests(), modifyRequests+1);
-    waitForModifyResponsesStat(modifyResponses+1);
+      assertEquals(ldapStatistics.getModifyRequests(), modifyRequests + 1);
+      waitForModifyResponsesStat(modifyResponses + 1);
+    }
   }
 
 
@@ -2396,8 +2329,8 @@
 
     DirectoryServer.setWritabilityMode(WritabilityMode.DISABLED);
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "extensibleObject");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "objectClass", "extensibleObject");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
 
@@ -2433,8 +2366,8 @@
 
     DirectoryServer.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "extensibleObject");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "objectClass", "extensibleObject");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -2470,43 +2403,25 @@
 
     DirectoryServer.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
+      long modifyRequests = ldapStatistics.getModifyRequests();
+      long modifyResponses = ldapStatistics.getModifyResponses();
 
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse =
-         message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
+      ModifyRequest modifyRequest =
+          newModifyRequest("uid=test.user," + baseDN)
+          .addModification(ADD, "objectClass", "extensibleObject");
+      LDAPMessage message = conn.modify(modifyRequest, false);
+      ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
+      assertFalse(modifyResponse.getResultCode() == 0);
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "extensibleObject");
-    List<RawModification> mods = newRawModifications(add(attr));
+      assertEquals(ldapStatistics.getModifyRequests(), modifyRequests + 1);
+      waitForModifyResponsesStat(modifyResponses + 1);
 
-    long modifyRequests  = ldapStatistics.getModifyRequests();
-    long modifyResponses = ldapStatistics.getModifyResponses();
-
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(
-                  ByteString.valueOfUtf8("uid=test.user," + baseDN), mods);
-    message = new LDAPMessage(2, modifyRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    ModifyResponseProtocolOp modifyResponse =
-         message.getModifyResponseProtocolOp();
-    assertFalse(modifyResponse.getResultCode() == 0);
-
-    assertEquals(ldapStatistics.getModifyRequests(), modifyRequests+1);
-    waitForModifyResponsesStat(modifyResponses+1);
-
-    DirectoryServer.setWritabilityMode(WritabilityMode.ENABLED);
+      DirectoryServer.setWritabilityMode(WritabilityMode.ENABLED);
+    }
   }
 
 
@@ -2539,8 +2454,8 @@
     Backend<?> b = DirectoryServer.getBackend(DN.valueOf(baseDN));
     b.setWritabilityMode(WritabilityMode.DISABLED);
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "extensibleObject");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "objectClass", "extensibleObject");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveFailedOperationElements(modifyOperation);
 
@@ -2577,8 +2492,8 @@
     Backend<?> b = DirectoryServer.getBackend(DN.valueOf(baseDN));
     b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "extensibleObject");
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    RawModification mod = newRawModification(ADD, "objectClass", "extensibleObject");
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, mod);
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -2615,44 +2530,25 @@
     Backend<?> b = DirectoryServer.getBackend(DN.valueOf(baseDN));
     b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
 
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+      long modifyRequests = ldapStatistics.getModifyRequests();
+      long modifyResponses = ldapStatistics.getModifyResponses();
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
+      ModifyRequest modifyRequest =
+          newModifyRequest("uid=test.user," + baseDN)
+          .addModification(ADD, "objectClass", "extensibleObject");
+      LDAPMessage message = conn.modify(modifyRequest, false);
+      ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
+      assertFalse(modifyResponse.getResultCode() == 0);
 
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse =
-         message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
+      assertEquals(ldapStatistics.getModifyRequests(), modifyRequests + 1);
+      waitForModifyResponsesStat(modifyResponses + 1);
 
-    LDAPAttribute attr = newLDAPAttribute("objectClass", "extensibleObject");
-    List<RawModification> mods = newRawModifications(add(attr));
-
-    long modifyRequests  = ldapStatistics.getModifyRequests();
-    long modifyResponses = ldapStatistics.getModifyResponses();
-
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(
-                  ByteString.valueOfUtf8("uid=test.user," + baseDN), mods);
-    message = new LDAPMessage(2, modifyRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    ModifyResponseProtocolOp modifyResponse =
-         message.getModifyResponseProtocolOp();
-    assertFalse(modifyResponse.getResultCode() == 0);
-
-    assertEquals(ldapStatistics.getModifyRequests(), modifyRequests+1);
-    waitForModifyResponsesStat(modifyResponses+1);
-
-    b.setWritabilityMode(WritabilityMode.ENABLED);
+      b.setWritabilityMode(WritabilityMode.ENABLED);
+    }
   }
 
 
@@ -2673,8 +2569,8 @@
     {
       assertEquals(changeListener.getModifyCount(), 0);
 
-      LDAPAttribute attr = newLDAPAttribute("description", "foo");
-      ModifyOperation modifyOperation = processModify("o=test", replace(attr));
+      RawModification mod = newRawModification(REPLACE, "description", "foo");
+      ModifyOperation modifyOperation = processModify("o=test", mod);
       assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
       retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -2704,8 +2600,8 @@
     {
       assertEquals(changeListener.getModifyCount(), 0);
 
-      LDAPAttribute attr = newLDAPAttribute("dc", "foo");
-      ModifyOperation modifyOperation = processModify(baseDN, replace(attr));
+      RawModification mod = newRawModification(REPLACE, "dc", "foo");
+      ModifyOperation modifyOperation = processModify(baseDN, mod);
       assertNotEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
       retrieveFailedOperationElements(modifyOperation);
 
@@ -2728,8 +2624,7 @@
   public void testCancelBeforeStartup(String baseDN)
          throws Exception
   {
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-    List<RawModification> mods = newRawModifications(replace(attr));
+    List<RawModification> mods = newRawModifications(REPLACE, "description", "foo");
 
     ModifyOperation modifyOperation =
         newModifyOperation(null, ByteString.valueOfUtf8(baseDN), mods);
@@ -2752,8 +2647,7 @@
   public void testCancelAfterOperation(String baseDN)
          throws Exception
   {
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-    List<RawModification> mods = newRawModifications(replace(attr));
+    List<RawModification> mods = newRawModifications(REPLACE, "description", "foo");
 
     ModifyOperation modifyOperation =
         newModifyOperation(null, ByteString.valueOfUtf8(baseDN), mods);
@@ -2781,8 +2675,8 @@
     final DNLock entryLock = DirectoryServer.getLockManager().tryReadLockEntry(DN.valueOf(baseDN));
     try
     {
-      LDAPAttribute attr = newLDAPAttribute("description", "foo");
-      ModifyOperation modifyOperation = processModify(baseDN, replace(attr));
+      RawModification mod = newRawModification(REPLACE, "description", "foo");
+      ModifyOperation modifyOperation = processModify(baseDN, mod);
       assertEquals(modifyOperation.getResultCode(), ResultCode.BUSY);
     }
     finally
@@ -2802,42 +2696,22 @@
   public void testDisconnectInPreParseModify(String baseDN)
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
-
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse =
-         message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
-
-
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-
-    List<RawModification> mods = newRawModifications(replace(attr));
-
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(ByteString.valueOfUtf8(baseDN), mods);
-    message = new LDAPMessage(2, modifyRequest,
-         DisconnectClientPlugin.createDisconnectControlList("PreParse"));
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    if (message != null)
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      // If we got an element back, then it must be a notice of disconnect
-      // unsolicited notification.
-      assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
-    }
+      conn.bind("cn=Directory Manager", "password");
 
-    StaticUtils.close(s);
+      List<RawModification> mods = newRawModifications(REPLACE, "description", "foo");
+      ModifyRequestProtocolOp modifyRequest = new ModifyRequestProtocolOp(ByteString.valueOfUtf8(baseDN), mods);
+      conn.writeMessage(modifyRequest, DisconnectClientPlugin.createDisconnectControlList("PreParse"));
+
+      LDAPMessage message = conn.readMessage();
+      if (message != null)
+      {
+        // If we got an element back, then it must be a notice of disconnect
+        // unsolicited notification.
+        assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+      }
+    }
   }
 
 
@@ -2851,44 +2725,22 @@
   @Test
   public void testDisconnectInPreOperationModify() throws Exception
   {
-
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
-
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse =
-         message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
-
-
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-
-    List<RawModification> mods = newRawModifications(replace(attr));
-
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(ByteString.valueOfUtf8("o=test"), mods);
-    message = new LDAPMessage(2, modifyRequest,
-         DisconnectClientPlugin.createDisconnectControlList(
-              "PreOperation"));
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    if (message != null)
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      // If we got an element back, then it must be a notice of disconnect
-      // unsolicited notification.
-      assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
-    }
+      conn.bind("cn=Directory Manager", "password");
 
-    StaticUtils.close(s);
+      List<RawModification> mods = newRawModifications(REPLACE, "description", "foo");
+      ModifyRequestProtocolOp modifyRequest = new ModifyRequestProtocolOp(ByteString.valueOfUtf8("o=test"), mods);
+      conn.writeMessage(modifyRequest, DisconnectClientPlugin.createDisconnectControlList("PreOperation"));
+
+      LDAPMessage message = conn.readMessage();
+      if (message != null)
+      {
+        // If we got an element back, then it must be a notice of disconnect
+        // unsolicited notification.
+        assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+      }
+    }
   }
 
 
@@ -2903,42 +2755,28 @@
   public void testDisconnectInPostOperationModify(String baseDN)
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
+    {
+      conn.bind("cn=Directory Manager", "password");
 
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
+      List<RawModification> mods = newRawModifications(REPLACE, "description", "foo");
 
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse =
-         message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
+      ModifyRequestProtocolOp modifyRequest = new ModifyRequestProtocolOp(ByteString.valueOfUtf8(baseDN), mods);
+      conn.writeMessage(modifyRequest, DisconnectClientPlugin.createDisconnectControlList("PostOperation"));
 
+      // The operation should NOT be aborted at the post operation stage. While
+      // the plugin can disconnect the client, the modify should have already
+      // been committed to the backend and a SUCCESS COULD get back to the client.
+      waitForResponse(conn, "testDisconnectInPostOperationModify");
+    }
+  }
 
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-
-    List<RawModification> mods = newRawModifications(replace(attr));
-
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(ByteString.valueOfUtf8(baseDN), mods);
-    message = new LDAPMessage(2, modifyRequest,
-         DisconnectClientPlugin.createDisconnectControlList(
-              "PostOperation"));
-    w.writeMessage(message);
-
-    // The operation should NOT be aborted at the post operation stage. While
-    // the plugin can disconnect the client, the modify should have already
-    // been committed to the backend and a SUCCESS COULD get back to the
-    // client.
-responseLoop:
+  private void waitForResponse(RemoteConnection conn, String string) throws Exception
+  {
+    responseLoop:
     while (true)
     {
-      message = r.readMessage();
+      LDAPMessage message = conn.readMessage();
       if (message == null)
       {
         // The connection has been closed.
@@ -2947,24 +2785,18 @@
 
       switch (message.getProtocolOpType())
       {
-        case OP_TYPE_MODIFY_RESPONSE:
-          // This was expected.  The disconnect didn't happen until after the
-          // response was sent.
-          break;
-        case OP_TYPE_EXTENDED_RESPONSE:
-          // The server is notifying us that it will be closing the connection.
-          break responseLoop;
-        default:
-          // This is a problem.  It's an unexpected response.
-        StaticUtils.close(s);
-
-          throw new Exception("Unexpected response message " + message +
-                              " encountered in " +
-                              "testDisconnectInPostOperationModify");
+      case OP_TYPE_MODIFY_RESPONSE:
+        // This was expected. The disconnect didn't happen until after the
+        // response was sent.
+        break;
+      case OP_TYPE_EXTENDED_RESPONSE:
+        // The server is notifying us that it will be closing the connection.
+        break responseLoop;
+      default:
+        // This is a problem. It's an unexpected response.
+        throw new Exception("Unexpected response message " + message + " encountered in " + string);
       }
     }
-
-    StaticUtils.close(s);
   }
 
 
@@ -2979,73 +2811,37 @@
   public void testDisconnectInPostResponseModify(String baseDN)
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
-
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(ByteString.valueOfUtf8("cn=Directory Manager"),
-                                   3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    BindResponseProtocolOp bindResponse =
-         message.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), 0);
-
-
-    LDAPAttribute attr = newLDAPAttribute("description", "foo");
-    List<RawModification> mods = newRawModifications(replace(attr));
-
-    ModifyRequestProtocolOp modifyRequest =
-         new ModifyRequestProtocolOp(ByteString.valueOfUtf8(baseDN), mods);
-    message = new LDAPMessage(2, modifyRequest,
-         DisconnectClientPlugin.createDisconnectControlList(
-              "PostResponse"));
-    w.writeMessage(message);
-
-responseLoop:
-    while (true)
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      message = r.readMessage();
-      if (message == null)
-      {
-        // The connection has been closed.
-        break responseLoop;
-      }
+      conn.bind("cn=Directory Manager", "password");
 
-      switch (message.getProtocolOpType())
-      {
-        case OP_TYPE_MODIFY_RESPONSE:
-          // This was expected.  The disconnect didn't happen until after the
-          // response was sent.
-          break;
-        case OP_TYPE_EXTENDED_RESPONSE:
-          // The server is notifying us that it will be closing the connection.
-          break responseLoop;
-        default:
-          // This is a problem.  It's an unexpected response.
-        StaticUtils.close(s);
+      List<RawModification> mods = newRawModifications(REPLACE, "description", "foo");
+      ModifyRequestProtocolOp modifyRequest = new ModifyRequestProtocolOp(ByteString.valueOfUtf8(baseDN), mods);
+      conn.writeMessage(modifyRequest, DisconnectClientPlugin.createDisconnectControlList("PostResponse"));
 
-          throw new Exception("Unexpected response message " + message +
-                              " encountered in " +
-                              "testDisconnectInPostResponseModify");
-      }
+      waitForResponse(conn, "testDisconnectInPostResponseModify");
     }
-
-    StaticUtils.close(s);
   }
 
-  private List<Modification> newModifications(Modification... mods)
+  private List<Modification> newModifications(ModificationType modType, String attrType, String attrValue)
   {
-    return newArrayList(mods);
+    return newArrayList(newModification(modType, attrType, attrValue));
   }
 
-  private List<RawModification> newRawModifications(RawModification... mods)
+  private Modification newModification(ModificationType modType, String attrType, String attrValue)
   {
-    return newArrayList(mods);
+    return new Modification(modType, Attributes.create(attrType, attrValue));
+  }
+
+  private RawModification newRawModification(ModificationType modType, String attributeType, String... attributeValues)
+  {
+    return new LDAPModification(modType, new LDAPAttribute(attributeType, newArrayList(attributeValues)));
+  }
+
+  private List<RawModification> newRawModifications(ModificationType modType, String attributeType,
+      String... attributeValues)
+  {
+    return newArrayList(newRawModification(modType, attributeType, attributeValues));
   }
 
   /**
@@ -3174,8 +2970,7 @@
     List<Control> controls =
          ShortCircuitPlugin.createShortCircuitControlList(0, "PreParse");
 
-    List<RawModification> mods = newRawModifications(
-        RawModification.create(ModificationType.REPLACE, "description", "foo"));
+    List<RawModification> mods = newRawModifications(REPLACE, "description", "foo");
 
     ModifyOperation modifyOperation =
         newModifyOperation(controls, ByteString.valueOfUtf8("o=test"), mods);
@@ -3215,8 +3010,7 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("givenName", "Test");
-    List<RawModification> mods = newRawModifications(add(attr));
+    List<RawModification> mods = newRawModifications(ADD, "givenName", "Test");
 
     List<Control> requestControls = new ArrayList<>();
     requestControls.add(
@@ -3251,8 +3045,7 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = newLDAPAttribute("givenName", "Foo");
-    List<RawModification> mods = newRawModifications(delete(attr));
+    List<RawModification> mods = newRawModifications(DELETE, "givenName", "Foo");
 
     List<Control> requestControls = new ArrayList<>();
     requestControls.add(
@@ -3287,8 +3080,7 @@
          "displayName: Test User",
          "userPassword: password");
 
-    LDAPAttribute attr = new LDAPAttribute("description");
-    List<RawModification> mods = newRawModifications(delete(attr));
+    List<RawModification> mods = newRawModifications(DELETE, "description");
 
     List<Control> requestControls = new ArrayList<>();
     requestControls.add(
@@ -3650,7 +3442,7 @@
 
     ByteString value = ByteString.wrap(Base64.decode(certificateValue));
     LDAPAttribute attr = new LDAPAttribute("usercertificate", value);
-    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, add(attr));
+    ModifyOperation modifyOperation = processModify("uid=test.user," + baseDN, new LDAPModification(ADD, attr));
     assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
     retrieveSuccessfulOperationElements(modifyOperation);
 
@@ -3683,8 +3475,7 @@
 
     // First check that adding "dc" fails because it is not allowed by
     // inetOrgPerson.
-    LDAPAttribute attr = newLDAPAttribute("dc", "foo");
-    List<RawModification> mods = newRawModifications(add(attr));
+    List<RawModification> mods = newRawModifications(ADD, "dc", "foo");
 
     ModifyOperation modifyOperation = processModify("cn=Test User," + baseDN, mods);
     assertEquals(modifyOperation.getResultCode(), ResultCode.OBJECTCLASS_VIOLATION);
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/core/SearchOperationTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/core/SearchOperationTestCase.java
index 6abe5af..26ee5c0 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/core/SearchOperationTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/core/SearchOperationTestCase.java
@@ -22,17 +22,21 @@
  *
  *
  *      Copyright 2006-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS
+ *      Portions Copyright 2011-2016 ForgeRock AS
  */
 package org.opends.server.core;
 
-import java.io.IOException;
-import java.net.Socket;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.assertj.core.api.SoftAssertions;
 import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.DecodeException;
 import org.forgerock.opendj.ldap.DereferenceAliasesPolicy;
 import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.SearchScope;
@@ -44,10 +48,27 @@
 import org.opends.server.protocols.internal.InternalSearchOperation;
 import org.opends.server.protocols.internal.Requests;
 import org.opends.server.protocols.internal.SearchRequest;
-import org.opends.server.protocols.ldap.*;
+import org.opends.server.protocols.ldap.BindResponseProtocolOp;
+import org.opends.server.protocols.ldap.LDAPAttribute;
+import org.opends.server.protocols.ldap.LDAPConstants;
+import org.opends.server.protocols.ldap.LDAPControl;
+import org.opends.server.protocols.ldap.LDAPFilter;
+import org.opends.server.protocols.ldap.LDAPMessage;
+import org.opends.server.protocols.ldap.LDAPResultCode;
+import org.opends.server.protocols.ldap.SearchRequestProtocolOp;
+import org.opends.server.protocols.ldap.SearchResultDoneProtocolOp;
+import org.opends.server.protocols.ldap.SearchResultEntryProtocolOp;
 import org.opends.server.tools.LDAPModify;
-import org.opends.server.tools.LDAPWriter;
-import org.opends.server.types.*;
+import org.opends.server.tools.RemoteConnection;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.Control;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.Entry;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.types.Operation;
+import org.opends.server.types.SearchResultEntry;
+import org.opends.server.types.SearchResultReference;
 import org.opends.server.util.StaticUtils;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
@@ -207,13 +228,9 @@
        throws Exception
   {
     // Establish a connection to the server.
-    try (Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort()))
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-      LDAPWriter w = new LDAPWriter(s);
-      TestCaseUtils.configureSocket(s);
-
-      bindAsManager(w, r);
+      bindAsManager(conn);
 
       // Since we are going to be watching the post-response count, we need to
       // wait for the server to become idle before kicking off the next request
@@ -228,12 +245,12 @@
       long searchReferences = ldapStatistics.getSearchResultReferences();
       long searchesDone     = ldapStatistics.getSearchResultsDone();
 
-      LDAPMessage message = new LDAPMessage(2, searchRequest, controls);
-      w.writeMessage(message);
+      conn.writeMessage(searchRequest, controls);
 
+      LDAPMessage message;
       SearchResultEntryProtocolOp searchResultEntry = null;
       SearchResultDoneProtocolOp searchResultDone = null;
-      while (searchResultDone == null && (message = r.readMessage()) != null)
+      while (searchResultDone == null && (message = conn.readMessage()) != null)
       {
         switch (message.getProtocolOpType())
         {
@@ -265,8 +282,7 @@
     }
   }
 
-  private void bindAsManager(LDAPWriter w, org.opends.server.tools.LDAPReader r)
-       throws IOException, LDAPException, DecodeException, InterruptedException
+  private void bindAsManager(RemoteConnection conn) throws Exception
   {
     // Since we are going to be watching the post-response count, we need to
     // wait for the server to become idle before kicking off the next request to
@@ -275,14 +291,7 @@
     assertTrue(DirectoryServer.getWorkQueue().waitUntilIdle(10000));
 
     InvocationCounterPlugin.resetAllCounters();
-    BindRequestProtocolOp bindRequest =
-         new BindRequestProtocolOp(
-              ByteString.valueOfUtf8("cn=Directory Manager"),
-              3, ByteString.valueOfUtf8("password"));
-    LDAPMessage message = new LDAPMessage(1, bindRequest);
-    w.writeMessage(message);
-
-    message = r.readMessage();
+    LDAPMessage message = conn.bind("cn=Directory Manager", "password");
     BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
     assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
   }
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/core/TestModifyDNOperation.java b/opendj-server-legacy/src/test/java/org/opends/server/core/TestModifyDNOperation.java
index c3577c1..c6946c4 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/core/TestModifyDNOperation.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/core/TestModifyDNOperation.java
@@ -27,16 +27,9 @@
  */
 package org.opends.server.core;
 
-import java.net.Socket;
 import java.util.Collections;
-import java.util.Hashtable;
 import java.util.List;
 
-import javax.naming.Context;
-import javax.naming.InvalidNameException;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.InitialDirContext;
-
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.opendj.ldap.AVA;
 import org.forgerock.opendj.ldap.ByteString;
@@ -48,15 +41,13 @@
 import org.opends.server.plugins.InvocationCounterPlugin;
 import org.opends.server.plugins.ShortCircuitPlugin;
 import org.opends.server.protocols.internal.InternalClientConnection;
-import org.opends.server.protocols.ldap.BindRequestProtocolOp;
-import org.opends.server.protocols.ldap.BindResponseProtocolOp;
 import org.opends.server.protocols.ldap.LDAPControl;
 import org.opends.server.protocols.ldap.LDAPMessage;
 import org.opends.server.protocols.ldap.LDAPResultCode;
 import org.opends.server.protocols.ldap.ModifyDNRequestProtocolOp;
 import org.opends.server.protocols.ldap.ModifyDNResponseProtocolOp;
 import org.opends.server.tools.LDAPModify;
-import org.opends.server.tools.LDAPWriter;
+import org.opends.server.tools.RemoteConnection;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.CancelRequest;
 import org.opends.server.types.CancelResult;
@@ -72,6 +63,7 @@
 
 import static org.assertj.core.api.Assertions.*;
 import static org.forgerock.opendj.ldap.ResultCode.*;
+import static org.opends.server.TestCaseUtils.*;
 import static org.opends.server.protocols.internal.InternalClientConnection.*;
 import static org.opends.server.util.ServerConstants.*;
 import static org.testng.Assert.*;
@@ -761,34 +753,22 @@
     assertTrue(DirectoryServer.getWorkQueue().waitUntilIdle(10000));
 
     // Establish a connection to the server.
-    try (Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort()))
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-    InvocationCounterPlugin.resetAllCounters();
+      InvocationCounterPlugin.resetAllCounters();
 
-    org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-    TestCaseUtils.configureSocket(s);
-    BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(b("cn=Directory Manager"), 3, b("password"));
-    LDAPMessage bindMessage = new LDAPMessage(1, bindRequest);
-    w.writeMessage(bindMessage);
+      conn.bind("cn=Directory Manager", "password");
 
-    bindMessage = r.readMessage();
-    BindResponseProtocolOp bindResponse = bindMessage.getBindResponseProtocolOp();
-    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+      assertTrue(DirectoryServer.getWorkQueue().waitUntilIdle(10000));
+      InvocationCounterPlugin.resetAllCounters();
+      ModifyDNRequestProtocolOp modifyRequest =
+          new ModifyDNRequestProtocolOp(b(entry.getName().toString()), b("uid=user.test0"), false);
+      conn.writeMessage(modifyRequest, ShortCircuitPlugin.createShortCircuitControlList(80, "PreOperation"));
 
-    assertTrue(DirectoryServer.getWorkQueue().waitUntilIdle(10000));
-    InvocationCounterPlugin.resetAllCounters();
-    ModifyDNRequestProtocolOp modifyRequest =
-        new ModifyDNRequestProtocolOp(b(entry.getName().toString()), b("uid=user.test0"), false);
-    LDAPMessage message = new LDAPMessage(2, modifyRequest,
-                                          ShortCircuitPlugin.createShortCircuitControlList(80, "PreOperation"));
-    w.writeMessage(message);
-
-    message = r.readMessage();
-    ModifyDNResponseProtocolOp modifyResponse = message.getModifyDNResponseProtocolOp();
-
-    assertEquals(modifyResponse.getResultCode(), 80);
-//    assertEquals(InvocationCounterPlugin.waitForPostResponse(), 1);
+      LDAPMessage message = conn.readMessage();
+      ModifyDNResponseProtocolOp modifyResponse = message.getModifyDNResponseProtocolOp();
+      assertEquals(modifyResponse.getResultCode(), 80);
+      // assertEquals(InvocationCounterPlugin.waitForPostResponse(), 1);
     }
   }
 
@@ -800,19 +780,9 @@
     // modify DN operation does not proceed.
 
     // Establish a connection to the server.
-    try (Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort()))
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort()))
     {
-      org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
-      LDAPWriter w = new LDAPWriter(s);
-      TestCaseUtils.configureSocket(s);
-
-      BindRequestProtocolOp bindRequest = new BindRequestProtocolOp(b("cn=Directory Manager"), 3, b("password"));
-      LDAPMessage message = new LDAPMessage(1, bindRequest);
-      w.writeMessage(message);
-
-      message = r.readMessage();
-      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
-      assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+      conn.bind("cn=Directory Manager", "password");
 
       // Since we are going to be watching the post-response count, we need to
       // wait for the server to become idle before kicking off the next request
@@ -830,14 +800,7 @@
         //long modifyDNRequests  = ldapStatistics.getModifyDNRequests();
         //long modifyDNResponses = ldapStatistics.getModifyDNResponses();
 
-        ModifyDNRequestProtocolOp modifyRequest =
-            new ModifyDNRequestProtocolOp(b(entry.getName().toString()), b("uid=user.test0"), false);
-        message = new LDAPMessage(2, modifyRequest);
-        w.writeMessage(message);
-
-        message = r.readMessage();
-        ModifyDNResponseProtocolOp modifyResponse = message.getModifyDNResponseProtocolOp();
-
+        ModifyDNResponseProtocolOp modifyResponse = conn.modifyDN(entry.getName().toString(), "uid=user.test0", false);
         assertEquals(modifyResponse.getResultCode(), LDAPResultCode.BUSY);
 
 //        assertEquals(InvocationCounterPlugin.getPreParseCount(), 1);
@@ -1081,30 +1044,16 @@
    *
    * @throws Exception
    */
-  @Test(expectedExceptions=InvalidNameException.class)
+  @Test
   public void testInvalidModRDN() throws Exception
   {
-    Hashtable<String,String> env = new Hashtable<>();
-    env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
-    String url = "ldap://localhost:" + TestCaseUtils.getServerLdapPort()
-            +"/dc=example,dc=com";
-    env.put(Context.PROVIDER_URL,url);
-    env.put(Context.SECURITY_AUTHENTICATION, "simple");
-    env.put(Context.SECURITY_PRINCIPAL, "cn=directory manager");
-    env.put(Context.SECURITY_CREDENTIALS, "password");
+    try (RemoteConnection c = new RemoteConnection("localhost", getServerLdapPort()))
+    {
+      c.bind("cn=Directory Manager", "password");
 
-    env.put("java.naming.ldap.deleteRDN", "true");  // default is 'true'
-    /* Create the initial context */
-    DirContext ctx = new InitialDirContext(env);
-    try
-    {
-      ctx.rename("uid=user.0,ou=People,dc=example,dc=com",
-                   "uid=,ou=People,dc=example,dc=com");
-    }
-    finally
-    {
-      /* Close the context when it's done */
-      ctx.close();
+      ModifyDNResponseProtocolOp modifyDNResponse =
+          c.modifyDN("uid=user.0,ou=People,dc=example,dc=com", "uid=,ou=People,dc=example,dc=com", true);
+      assertEquals(modifyDNResponse.getResultCode(), ResultCode.INVALID_DN_SYNTAX.intValue());
     }
   }
 }
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/crypto/CryptoManagerTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/crypto/CryptoManagerTestCase.java
index 1fd731a..8d23920 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/crypto/CryptoManagerTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/crypto/CryptoManagerTestCase.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
- *      Portions Copyright 2013-2015 ForgeRock AS
+ *      Portions Copyright 2013-2016 ForgeRock AS
  */
 package org.opends.server.crypto;
 
@@ -33,21 +33,21 @@
 import java.io.OutputStream;
 import java.security.MessageDigest;
 import java.util.Arrays;
+import java.util.List;
 
 import javax.crypto.Mac;
-import javax.naming.directory.SearchControls;
-import javax.naming.directory.SearchResult;
-import javax.naming.ldap.InitialLdapContext;
-import javax.naming.ldap.LdapName;
 
 import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.SearchScope;
 import org.opends.admin.ads.ADSContext;
-import org.opends.admin.ads.util.ConnectionUtils;
 import org.opends.server.TestCaseUtils;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.protocols.internal.InternalSearchOperation;
 import org.opends.server.protocols.internal.SearchRequest;
+import org.opends.server.protocols.ldap.LDAPAttribute;
+import org.opends.server.protocols.ldap.SearchResultEntryProtocolOp;
+import org.opends.server.tools.RemoteConnection;
 import org.opends.server.types.CryptoManager;
 import org.opends.server.types.CryptoManagerException;
 import org.opends.server.types.DN;
@@ -60,8 +60,7 @@
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
-import com.forgerock.opendj.cli.CliConstants;
-
+import static org.assertj.core.api.Assertions.*;
 import static org.opends.server.config.ConfigConstants.*;
 import static org.opends.server.protocols.internal.InternalClientConnection.*;
 import static org.opends.server.protocols.internal.Requests.*;
@@ -95,32 +94,34 @@
     assertNotNull(cert);
 
     // The certificate should now be accessible in the truststore backend via LDAP.
-    final InitialLdapContext ctx = ConnectionUtils.createLdapsContext(
-            "ldaps://" + "127.0.0.1" + ":"
-                    + String.valueOf(TestCaseUtils.getServerAdminPort()),
-            "cn=Directory Manager", "password",
-            CliConstants.DEFAULT_LDAP_CONNECT_TIMEOUT, null, null, null);
-    // TODO: should the below dn be in ConfigConstants?
-    final String dnStr = "ds-cfg-key-id=ads-certificate,cn=ads-truststore";
-    final LdapName dn = new LdapName(dnStr);
-    final SearchControls searchControls = new SearchControls();
-    searchControls.setSearchScope(SearchControls.OBJECT_SCOPE);
-    final String attrIDs[] = { "ds-cfg-public-key-certificate;binary" };
-    searchControls.setReturningAttributes(attrIDs);
-    final SearchResult certEntry = ctx.search(dn,
-               "(objectclass=ds-cfg-instance-key)", searchControls).next();
-    final javax.naming.directory.Attribute certAttr
-            = certEntry.getAttributes().get(attrIDs[0]);
-    /* attribute ds-cfg-public-key-certificate is a MUST in the schema */
-    assertNotNull(certAttr);
-    byte[] ldapCert = (byte[])certAttr.get();
-    // Compare the certificate values.
-    assertTrue(Arrays.equals(ldapCert, cert));
+    ByteString ldapCert;
+    try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerAdminPort(), true))
+    {
+      conn.bind("cn=Directory Manager", "password");
+
+      // TODO: should the below dn be in ConfigConstants?
+      final String dnStr = "ds-cfg-key-id=ads-certificate,cn=ads-truststore";
+      conn.search(dnStr, SearchScope.BASE_OBJECT, "(objectclass=ds-cfg-instance-key)",
+          "ds-cfg-public-key-certificate;binary");
+      List<SearchResultEntryProtocolOp> searchEntries = conn.readEntries();
+      assertThat(searchEntries).hasSize(1);
+      SearchResultEntryProtocolOp searchEntry = searchEntries.get(0);
+      List<LDAPAttribute> attributes = searchEntry.getAttributes();
+      assertThat(attributes).hasSize(1);
+      LDAPAttribute certAttr = attributes.get(0);
+      /* attribute ds-cfg-public-key-certificate is a MUST in the schema */
+      assertNotNull(certAttr);
+      List<ByteString> values = certAttr.getValues();
+      assertThat(values).hasSize(1);
+      ldapCert = values.get(0);
+      // Compare the certificate values.
+      assertEquals(ldapCert.toByteArray(), cert);
+    }
 
     // Compare the MD5 hash of the LDAP attribute with the one
     // retrieved from the CryptoManager.
     MessageDigest md = MessageDigest.getInstance("MD5");
-    String actual = StaticUtils.bytesToHexNoSpace(md.digest(ldapCert));
+    String actual = StaticUtils.bytesToHexNoSpace(md.digest(ldapCert.toByteArray()));
     assertEquals(actual, cm.getInstanceKeyID());
 
     // Call twice to ensure idempotent.
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPAuthenticationHandlerTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPAuthenticationHandlerTestCase.java
index c115052..770f3ec 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPAuthenticationHandlerTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPAuthenticationHandlerTestCase.java
@@ -22,11 +22,15 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
- *      Portions Copyright 2014-2015 ForgeRock AS
+ *      Portions Copyright 2014-2016 ForgeRock AS
  */
 package org.opends.server.tools;
 
+import static org.opends.server.util.CollectionUtils.*;
+import static org.testng.Assert.*;
+
 import java.io.File;
+import java.io.IOException;
 import java.net.InetAddress;
 import java.net.Socket;
 import java.net.UnknownHostException;
@@ -34,6 +38,7 @@
 import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.forgerock.i18n.LocalizableMessage;
@@ -51,8 +56,6 @@
 
 import com.forgerock.opendj.cli.ClientException;
 
-import static org.testng.Assert.*;
-
 /**
  * A set of test cases for the LDAP authentication handler.
  */
@@ -154,21 +157,14 @@
   public void testDoSimpleBindWithValidDNAndPWNoControls()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"),
-                             ByteString.valueOfUtf8("password"), requestControls,
-                             responseControls);
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"), ByteString.valueOfUtf8("password"),
+          requestControls, responseControls);
+    }
   }
 
 
@@ -183,19 +179,13 @@
   public void testDoSimpleBindWithNullDNAndPWNoControls()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSimpleBind(3, null, null, requestControls, responseControls);
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      authHandler.doSimpleBind(3, null, null, requestControls, responseControls);
+    }
   }
 
 
@@ -210,20 +200,13 @@
   public void testDoSimpleBindWithEmptyDNAndPWNoControls()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSimpleBind(3, ByteString.empty(), ByteString.empty(),
-                             requestControls, responseControls);
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      authHandler.doSimpleBind(3, ByteString.empty(), ByteString.empty(), requestControls, responseControls);
+    }
   }
 
 
@@ -238,27 +221,16 @@
   public void testDoSimpleBindWithDNButNoPassword()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = newSocket())
     {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
       authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"),
                                ByteString.empty(), requestControls,
                                responseControls);
     }
-    finally
-    {
-      s.close();
-    }
   }
 
 
@@ -273,27 +245,16 @@
   public void testDoSimpleBindWithDNButInvalidPassword()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = newSocket())
     {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
       authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"),
                                ByteString.valueOfUtf8("wrongPassword"),
                                requestControls, responseControls);
     }
-    finally
-    {
-      s.close();
-    }
   }
 
 
@@ -308,23 +269,15 @@
   public void testDoSimpleBindWithPasswordPolicyControl()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
-
     requestControls.add(new PasswordPolicyRequestControl());
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"),
-                             ByteString.valueOfUtf8("password"),
-                             requestControls, responseControls);
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"), ByteString.valueOfUtf8("password"),
+          requestControls, responseControls);
+    }
   }
 
 
@@ -338,25 +291,15 @@
   public void testDoSASLBindNullMechanism()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
 
-    try
+    try (Socket s = newSocket())
     {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
       authHandler.doSASLBind(null, null, null, saslProperties, requestControls, responseControls);
     }
-    finally
-    {
-      s.close();
-    }
   }
 
 
@@ -370,25 +313,15 @@
   public void testDoSASLBindEmptyMechanism()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
 
-    try
+    try (Socket s = newSocket())
     {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
       authHandler.doSASLBind(null, null, "", saslProperties, requestControls, responseControls);
     }
-    finally
-    {
-      s.close();
-    }
   }
 
 
@@ -402,27 +335,16 @@
   public void testDoSASLBindInvalidMechanism()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = newSocket())
     {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
       authHandler.doSASLBind(null, null, "invalid", saslProperties,
                              requestControls, responseControls);
     }
-    finally
-    {
-      s.close();
-    }
   }
 
 
@@ -437,30 +359,13 @@
   public void testDoSASLBindAnonymousDisabled()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("testDoSASLBindAnonymousDisabled");
-    saslProperties.put("trace", propList);
+    saslProperties.put("trace", newArrayList("testDoSASLBindAnonymousDisabled"));
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = newSocket())
     {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "ANONYMOUS", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      anonymous(authHandler, saslProperties);
     }
   }
 
@@ -479,30 +384,18 @@
     AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
     handler.initializeSASLMechanismHandler(null);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("testDoSASLBindAnonymous");
-    saslProperties.put("trace", propList);
+    saslProperties.put("trace", newArrayList("testDoSASLBindAnonymous"));
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      anonymous(authHandler, saslProperties);
+    }
 
-    authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                           "ANONYMOUS", saslProperties, requestControls,
-                           responseControls);
-    s.close();
     handler.finalizeSASLMechanismHandler();
   }
 
-
-
   /**
    * Tests the <CODE>doSASLBind</CODE> method for the case in which ANONYMOUS
    * authentication is enabled in the server and there is no trace information.
@@ -516,22 +409,12 @@
     AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
     handler.initializeSASLMechanismHandler(null);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                           "ANONYMOUS", saslProperties, requestControls,
-                           responseControls);
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      anonymous(authHandler, saslProperties);
+    }
     handler.finalizeSASLMechanismHandler();
   }
 
@@ -551,31 +434,17 @@
     AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
     handler.initializeSASLMechanismHandler(null);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("testDoSASLBindAnonymousMultivaluedTrace");
-    propList.add("aSecondTraceStringWhichIsInvalid");
-    saslProperties.put("trace", propList);
+    saslProperties.put("trace",
+        newArrayList("testDoSASLBindAnonymousMultivaluedTrace", "aSecondTraceStringWhichIsInvalid"));
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = newSocket())
     {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "ANONYMOUS", saslProperties, requestControls,
-                             responseControls);
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      anonymous(authHandler, saslProperties);
     }
     finally
     {
-      s.close();
       handler.finalizeSASLMechanismHandler();
     }
   }
@@ -596,30 +465,16 @@
     AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
     handler.initializeSASLMechanismHandler(null);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("testDoSASLBindAnonymousInvalidProperty");
-    saslProperties.put("invalid", propList);
+    saslProperties.put("invalid", newArrayList("testDoSASLBindAnonymousInvalidProperty"));
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = newSocket())
     {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "ANONYMOUS", saslProperties, requestControls,
-                             responseControls);
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      anonymous(authHandler, saslProperties);
     }
     finally
     {
-      s.close();
       handler.finalizeSASLMechanismHandler();
     }
   }
@@ -640,27 +495,17 @@
     AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
     handler.initializeSASLMechanismHandler(null);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
-
     requestControls.add(new PasswordPolicyRequestControl());
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("testDoSASLBindAnonymous");
-    saslProperties.put("trace", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                           "ANONYMOUS", saslProperties, requestControls,
-                           responseControls);
-    s.close();
+    saslProperties.put("trace", newArrayList("testDoSASLBindAnonymous"));
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(), "ANONYMOUS", saslProperties, requestControls,
+          responseControls);
+    }
     handler.finalizeSASLMechanismHandler();
   }
 
@@ -696,31 +541,15 @@
     DirectoryServer.deregisterSASLMechanismHandler("CRAM-MD5");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
 
     try
     {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "CRAM-MD5", saslProperties, requestControls,
-                             responseControls);
+      cramMd5SaslBind(saslProperties);
     }
     finally
     {
-      s.close();
       DirectoryServer.registerSASLMechanismHandler("CRAM-MD5", cramMD5Handler);
     }
   }
@@ -753,26 +582,9 @@
               "cn=Password Policies,cn=config");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"),
-                           "CRAM-MD5", saslProperties, requestControls,
-                           responseControls);
-    s.close();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    cramMd5SaslBind(saslProperties);
   }
 
 
@@ -789,32 +601,10 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "CRAM-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    cramMd5SaslBind(saslProperties);
   }
 
 
@@ -831,32 +621,10 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList(""));
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "CRAM-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    cramMd5SaslBind(saslProperties);
   }
 
 
@@ -887,31 +655,13 @@
               "cn=Password Policies,cn=config");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = newSocket())
     {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("invalidPassword"),
-                             "CRAM-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      doSASLBind("CRAM-MD5", "invalidPassword", authHandler, saslProperties);
     }
   }
 
@@ -941,32 +691,10 @@
          "userPassword: password");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "CRAM-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    cramMd5SaslBind(saslProperties);
   }
 
 
@@ -981,34 +709,12 @@
   public void testDoSASLBindCRAMMD5NullProperties()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
-
     LinkedHashMap<String,List<String>> saslProperties = null;
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "CRAM-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    cramMd5SaslBind(saslProperties);
   }
 
 
-
   /**
    * Tests the <CODE>doSASLBind</CODE> method using CRAM-MD5 for the case in
    * which the provided SASL properties were empty.
@@ -1019,29 +725,9 @@
   public void testDoSASLBindCRAMMD5EmptyProperties()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "CRAM-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    cramMd5SaslBind(saslProperties);
   }
 
 
@@ -1058,37 +744,12 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    propList.add("u:test.user");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test", "u:test.user"));
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "CRAM-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    cramMd5SaslBind(saslProperties);
   }
 
-
-
   /**
    * Tests the <CODE>doSASLBind</CODE> method using CRAM-MD5 for the case in
    * which an invalid SASL property was provided.
@@ -1101,36 +762,11 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("invalid", newArrayList("foo"));
 
-    propList = new ArrayList<>();
-    propList.add("foo");
-    saslProperties.put("invalid", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "CRAM-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    cramMd5SaslBind(saslProperties);
   }
 
 
@@ -1162,28 +798,18 @@
               "cn=Password Policies,cn=config");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
-
     requestControls.add(new PasswordPolicyRequestControl());
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"),
-                           "CRAM-MD5", saslProperties, requestControls,
-                           responseControls);
-    s.close();
+      authHandler.doSASLBind(ByteString.empty(), ByteString.valueOfUtf8("password"), "CRAM-MD5", saslProperties,
+          requestControls, responseControls);
+    }
   }
 
 
@@ -1219,37 +845,18 @@
     DirectoryServer.deregisterSASLMechanismHandler("DIGEST-MD5");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("realm", newArrayList("o=test"));
 
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    saslProperties.put("realm", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = newSocket())
     {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      digestMD5(authHandler, saslProperties);
     }
     finally
     {
-      s.close();
-      DirectoryServer.registerSASLMechanismHandler("DIGEST-MD5",
-                                                   digestMD5Handler);
+      DirectoryServer.registerSASLMechanismHandler("DIGEST-MD5", digestMD5Handler);
     }
   }
 
@@ -1281,28 +888,14 @@
               "cn=Password Policies,cn=config");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
 
-    propList = new ArrayList<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, this.hostname, messageID);
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"),
-                           "DIGEST-MD5", saslProperties, requestControls,
-                           responseControls);
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, hostname);
+      digestMD5(authHandler, saslProperties);
+    }
   }
 
 
@@ -1333,28 +926,14 @@
               "cn=Password Policies,cn=config");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
 
-    propList = new ArrayList<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, this.hostname, messageID);
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"),
-                           "DIGEST-MD5", saslProperties, requestControls,
-                           responseControls);
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, hostname);
+      digestMD5(authHandler, saslProperties);
+    }
   }
 
 
@@ -1369,30 +948,10 @@
   public void testDoSASLBindDigestMD5NullProperties()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
 
     LinkedHashMap<String,List<String>> saslProperties = null;
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -1407,29 +966,9 @@
   public void testDoSASLBindDigestMD5EmptyProperties()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -1444,32 +983,10 @@
   public void testDoSASLBindDigestMD5InvalidProperty()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("invalid", newArrayList("foo"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("foo");
-    saslProperties.put("invalid", propList);
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -1484,33 +1001,13 @@
   public void testDoSASLBindDigestMD5MultipleAuthIDs()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
+    ArrayList<String> propList = newArrayList("dn:uid=test.user,o=test");
     propList.add("u:test.user");
     saslProperties.put("authid", propList);
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
 
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -1525,32 +1022,10 @@
   public void testDoSASLBindDigestMD5MEmptyAuthID()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList(""));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("");
-    saslProperties.put("authid", propList);
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -1565,38 +1040,11 @@
   public void testDoSASLBindDigestMD5MultipleRealms()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("realm", newArrayList("o=test", "dc=example,dc=com"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    propList.add("dc=example,dc=com");
-    saslProperties.put("realm", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -1627,35 +1075,17 @@
               "cn=Password Policies,cn=config");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("qop", newArrayList("auth"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("auth");
-    saslProperties.put("qop", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, this.hostname, messageID);
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"),
-                           "DIGEST-MD5", saslProperties, requestControls,
-                           responseControls);
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, hostname);
+      digestMD5(authHandler, saslProperties);
+    }
   }
 
-
-
   /**
    * Tests the <CODE>doSASLBind</CODE> method for the case in which the
    * DIGEST-MD5 SASL properties contain the unsupported integrity quality of
@@ -1667,41 +1097,12 @@
   public void testDoSASLBindDigestMD5UnsupportedQoPAuthInt()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("realm", newArrayList("o=test"));
+    saslProperties.put("qop", newArrayList("auth-int"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    saslProperties.put("realm", propList);
-
-    propList = new ArrayList<>();
-    propList.add("auth-int");
-    saslProperties.put("qop", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -1717,41 +1118,12 @@
   public void testDoSASLBindDigestMD5UnsupportedQoPAuthConf()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("realm", newArrayList("o=test"));
+    saslProperties.put("qop", newArrayList("auth-conf"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    saslProperties.put("realm", propList);
-
-    propList = new ArrayList<>();
-    propList.add("auth-conf");
-    saslProperties.put("qop", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -1766,45 +1138,15 @@
   public void testDoSASLBindDigestMD5InvalidQoP()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("realm", newArrayList("o=test"));
+    saslProperties.put("qop", newArrayList("invalid"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    saslProperties.put("realm", propList);
-
-    propList = new ArrayList<>();
-    propList.add("invalid");
-    saslProperties.put("qop", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
-
   /**
    * Tests the <CODE>doSASLBind</CODE> method for the case in which the
    * DIGEST-MD5 SASL properties contain multiple quality of protection values.
@@ -1815,43 +1157,12 @@
   public void testDoSASLBindDigestMD5MultipleQoPs()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("realm", newArrayList("o=test"));
+    saslProperties.put("qop", newArrayList("auth", "auth-int", "auth-conf"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    saslProperties.put("realm", propList);
-
-    propList = new ArrayList<>();
-    propList.add("auth");
-    propList.add("auth-int");
-    propList.add("auth-conf");
-    saslProperties.put("qop", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -1866,46 +1177,15 @@
   public void testDoSASLBindDigestMD5MultipleDigestURIs()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("realm", newArrayList("o=test"));
+    saslProperties.put("digest-uri", newArrayList("ldap/value1", "ldap/value2"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    saslProperties.put("realm", propList);
-
-    propList = new ArrayList<>();
-    propList.add("ldap/value1");
-    propList.add("ldap/value2");
-    saslProperties.put("digest-uri", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
-
   /**
    * Tests the <CODE>doSASLBind</CODE> method for the case in which the
    * DIGEST-MD5 SASL properties contain multiple authorization IDs.
@@ -1916,42 +1196,12 @@
   public void testDoSASLBindDigestMD5MultipleAuthzIDs()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("realm", newArrayList("o=test"));
+    saslProperties.put("authzid", newArrayList("dn:uid=test.user,o=test", "u:test.user"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    saslProperties.put("realm", propList);
-
-    propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    propList.add("u:test.user");
-    saslProperties.put("authzid", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -1966,37 +1216,11 @@
   public void testDoSASLBindDigestMD5InvalidAuthDN()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:invalid"));
+    saslProperties.put("realm", newArrayList("o=test"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:invalid");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    saslProperties.put("realm", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -2013,37 +1237,11 @@
   {
     TestCaseUtils.initializeTestBackend(true);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:nosuchuser"));
+    saslProperties.put("realm", newArrayList("o=test"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("u:nosuchuser");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    saslProperties.put("realm", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -2074,36 +1272,14 @@
               "cn=Password Policies,cn=config");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:nosuchuser"));
+    saslProperties.put("realm", newArrayList("o=test"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("u:nosuchuser");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    saslProperties.put("realm", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = newSocket())
     {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("wrongPassword"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      doSASLBind("DIGEST-MD5", "wrongPassword", authHandler, saslProperties);
     }
   }
 
@@ -2133,37 +1309,11 @@
          "userPassword: password");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:nosuchuser"));
+    saslProperties.put("realm", newArrayList("o=test"));
 
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("u:nosuchuser");
-    saslProperties.put("authid", propList);
-
-    propList = new ArrayList<>();
-    propList.add("o=test");
-    saslProperties.put("realm", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"),
-                             "DIGEST-MD5", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    digestMd5SaslBind(saslProperties);
   }
 
 
@@ -2195,30 +1345,18 @@
               "cn=Password Policies,cn=config");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
-
     requestControls.add(new PasswordPolicyRequestControl());
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
 
-    propList = new ArrayList<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, this.hostname, messageID);
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"),
-                           "DIGEST-MD5", saslProperties, requestControls,
-                           responseControls);
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, hostname);
+      authHandler.doSASLBind(ByteString.empty(), ByteString.valueOfUtf8("password"), "DIGEST-MD5", saslProperties,
+          requestControls, responseControls);
+    }
   }
 
 
@@ -2262,27 +1400,14 @@
                  trustStorePath, "password");
 
 
-    Socket s = factory.createSocket("127.0.0.1",
-                                    TestCaseUtils.getServerLdapsPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = factory.createSocket("127.0.0.1", TestCaseUtils.getServerLdapsPort()))
     {
-      authHandler.doSASLBind(ByteString.empty(), null, "EXTERNAL",
-                             saslProperties, requestControls, responseControls);
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      doSASLBind("EXTERNAL", null, authHandler, saslProperties);
     }
     finally
     {
-      s.close();
       DirectoryServer.registerSASLMechanismHandler("EXTERNAL", externalHandler);
     }
   }
@@ -2323,22 +1448,12 @@
                  "password");
 
 
-    Socket s = factory.createSocket("127.0.0.1",
-                                    TestCaseUtils.getServerLdapsPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
-    LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSASLBind(ByteString.empty(), null, "EXTERNAL",
-                           saslProperties, requestControls, responseControls);
-
-    s.close();
+    try (Socket s = factory.createSocket("127.0.0.1", TestCaseUtils.getServerLdapsPort()))
+    {
+      LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      doSASLBind("EXTERNAL", null, authHandler, saslProperties);
+    }
   }
 
 
@@ -2382,36 +1497,20 @@
                  "password");
 
 
-    Socket s = factory.createSocket("127.0.0.1",
-                                    TestCaseUtils.getServerLdapsPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("foo");
-    saslProperties.put("invalid", valueList);
+    saslProperties.put("invalid", newArrayList("foo"));
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = factory.createSocket("127.0.0.1", TestCaseUtils.getServerLdapsPort());)
     {
-      authHandler.doSASLBind(ByteString.empty(), null, "EXTERNAL",
-                             saslProperties, requestControls, responseControls);
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      doSASLBind("EXTERNAL", null, authHandler, saslProperties);
     }
     finally
     {
-      s.close();
       DirectoryServer.registerSASLMechanismHandler("EXTERNAL", externalHandler);
     }
   }
 
-
-
   /**
    * Tests the <CODE>doSASLBind</CODE> method for the case in which EXTERNAL
    * authentication is enabled in the server and the password policy request
@@ -2447,24 +1546,16 @@
                  "password");
 
 
-    Socket s = factory.createSocket("127.0.0.1",
-                                    TestCaseUtils.getServerLdapsPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
-
     requestControls.add(new PasswordPolicyRequestControl());
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSASLBind(ByteString.empty(), null, "EXTERNAL",
-                           saslProperties, requestControls, responseControls);
-
-    s.close();
+    try (Socket s = factory.createSocket("127.0.0.1", TestCaseUtils.getServerLdapsPort()))
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      doSASLBind("EXTERNAL", null, authHandler, saslProperties);
+      authHandler.doSASLBind(ByteString.empty(), null, "EXTERNAL", saslProperties, requestControls, responseControls);
+    }
   }
 
 
@@ -2479,29 +1570,9 @@
   public void testDoSASLBindGSSAPINullProperties()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
-
     LinkedHashMap<String,List<String>> saslProperties = null;
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
@@ -2516,31 +1587,93 @@
   public void testDoSASLBindGSSAPIEmptyProperties()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
+    gssapiSaslBind(saslProperties);
+  }
 
-    try
+  private Socket newSocket() throws UnknownHostException, IOException
+  {
+    return new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
+  }
+
+  private LDAPAuthenticationHandler newLDAPAuthenticationHandler(Socket s, String hostName2) throws IOException
+  {
+    LDAPReader r = new LDAPReader(s);
+    LDAPWriter w = new LDAPWriter(s);
+    AtomicInteger messageID = new AtomicInteger(1);
+    return new LDAPAuthenticationHandler(r, w, hostName2, messageID);
+  }
+
+  private void anonymous(LDAPAuthenticationHandler authHandler, Map<String, List<String>> saslProperties)
+      throws ClientException, LDAPException
+  {
+    doSASLBind("ANONYMOUS", "", authHandler, saslProperties);
+  }
+
+  private void gssapi(LDAPAuthenticationHandler authHandler, Map<String, List<String>> saslProperties)
+      throws ClientException, LDAPException
+  {
+    doSASLBind("GSSAPI", "", authHandler, saslProperties);
+  }
+
+  private void cramMD5(LDAPAuthenticationHandler authHandler, Map<String, List<String>> saslProperties)
+      throws ClientException, LDAPException
+  {
+    doSASLBind("CRAM-MD5", "password", authHandler, saslProperties);
+  }
+
+  private void plain(LDAPAuthenticationHandler authHandler, Map<String, List<String>> saslProperties)
+      throws ClientException, LDAPException
+  {
+    doSASLBind("PLAIN", "password", authHandler, saslProperties);
+  }
+
+  private void digestMD5(LDAPAuthenticationHandler authHandler, Map<String, List<String>> saslProperties)
+      throws ClientException, LDAPException
+  {
+    doSASLBind("DIGEST-MD5", "password", authHandler, saslProperties);
+  }
+
+  private void doSASLBind(String mechanism, String bindPassword, LDAPAuthenticationHandler authHandler,
+      Map<String, List<String>> saslProperties) throws ClientException, LDAPException
+  {
+    ByteString bindPwd = bindPassword != null ? ByteString.valueOfUtf8(bindPassword) : null;
+    authHandler.doSASLBind(ByteString.empty(), bindPwd, mechanism, saslProperties,
+        new ArrayList<Control>(), new ArrayList<Control>());
+  }
+
+  private void plainSaslBind(Map<String, List<String>> saslProperties) throws Exception
+  {
+    try (Socket s = newSocket())
     {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
+      plain(newLDAPAuthenticationHandler(s, "localhost"), saslProperties);
     }
   }
 
+  private void cramMd5SaslBind(LinkedHashMap<String, List<String>> saslProperties) throws Exception
+  {
+    try (Socket s = newSocket())
+    {
+      cramMD5(newLDAPAuthenticationHandler(s, "localhost"), saslProperties);
+    }
+  }
 
+  private void digestMd5SaslBind(LinkedHashMap<String, List<String>> saslProperties) throws Exception
+  {
+    try (Socket s = newSocket())
+    {
+      digestMD5(newLDAPAuthenticationHandler(s, "localhost"), saslProperties);
+    }
+  }
+
+  private void gssapiSaslBind(LinkedHashMap<String, List<String>> saslProperties) throws Exception
+  {
+    try (Socket s = newSocket())
+    {
+      gssapi(newLDAPAuthenticationHandler(s, "localhost"), saslProperties);
+    }
+  }
 
   /**
    * Tests the <CODE>doSASLBind</CODE> method for GSSAPI authentication when the
@@ -2552,32 +1685,10 @@
   public void testDoSASLBindGSSAPIEmptyAuthID()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList(""));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("");
-    saslProperties.put("authid", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
@@ -2592,33 +1703,10 @@
   public void testDoSASLBindGSSAPIMultipleAuthIDs()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:test.user", "dn:uid=test.user,o=test"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("u:test.user");
-    valueList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
@@ -2633,37 +1721,11 @@
   public void testDoSASLBindGSSAPIMultipleAuthzIDs()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:test.user"));
+    saslProperties.put("authzid", newArrayList("u:test.user", "dn:uid=test.user,o=test"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("u:test.user");
-    saslProperties.put("authid", valueList);
-
-    valueList = new ArrayList<>();
-    valueList.add("u:test.user");
-    valueList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authzid", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
@@ -2678,37 +1740,11 @@
   public void testDoSASLBindGSSAPIMultipleKDCs()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:test.user"));
+    saslProperties.put("kdc", newArrayList("kdc1", "kdc2"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("u:test.user");
-    saslProperties.put("authid", valueList);
-
-    valueList = new ArrayList<>();
-    valueList.add("kdc1");
-    valueList.add("kdc2");
-    saslProperties.put("kdc", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
@@ -2723,38 +1759,11 @@
   public void testDoSASLBindGSSAPIMultipleQoPs()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:test.user"));
+    saslProperties.put("qop", newArrayList("auth", "auth-int", "auth-conf"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("u:test.user");
-    saslProperties.put("authid", valueList);
-
-    valueList = new ArrayList<>();
-    valueList.add("auth");
-    valueList.add("auth-int");
-    valueList.add("auth-conf");
-    saslProperties.put("qop", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
@@ -2770,36 +1779,11 @@
   public void testDoSASLBindGSSAPIUnsupportedQoPAuthInt()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:test.user"));
+    saslProperties.put("qop", newArrayList("auth-int"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("u:test.user");
-    saslProperties.put("authid", valueList);
-
-    valueList = new ArrayList<>();
-    valueList.add("auth-int");
-    saslProperties.put("qop", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
@@ -2815,36 +1799,11 @@
   public void testDoSASLBindGSSAPIUnsupportedQoPAuthConf()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:test.user"));
+    saslProperties.put("qop", newArrayList("auth-conf"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("u:test.user");
-    saslProperties.put("authid", valueList);
-
-    valueList = new ArrayList<>();
-    valueList.add("auth-conf");
-    saslProperties.put("qop", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
@@ -2859,36 +1818,11 @@
   public void testDoSASLBindGSSAPIInvalidQoP()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:test.user"));
+    saslProperties.put("qop", newArrayList("invalid"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("u:test.user");
-    saslProperties.put("authid", valueList);
-
-    valueList = new ArrayList<>();
-    valueList.add("invalid");
-    saslProperties.put("qop", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
@@ -2903,37 +1837,11 @@
   public void testDoSASLBindGSSAPIMultipleRealms()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:test.user"));
+    saslProperties.put("realm", newArrayList("realm1", "realm2"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("u:test.user");
-    saslProperties.put("authid", valueList);
-
-    valueList = new ArrayList<>();
-    valueList.add("realm1");
-    valueList.add("realm2");
-    saslProperties.put("realm", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
@@ -2948,40 +1856,14 @@
   public void testDoSASLBindGSSAPIInvalidProperty()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("u:test.user"));
+    saslProperties.put("invalid", newArrayList("foo"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("u:test.user");
-    saslProperties.put("authid", valueList);
-
-    valueList = new ArrayList<>();
-    valueList.add("foo");
-    saslProperties.put("invalid", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
-
   /**
    * Tests the <CODE>doSASLBind</CODE> method for GSSAPI authentication when the
    * provided properties isn't empty but doesn't contain an auth ID.
@@ -2992,32 +1874,10 @@
   public void testDoSASLBindGSSAPINoAuthID()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("qop", newArrayList("auth"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("auth");
-    saslProperties.put("qop", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                             "GSSAPI", saslProperties, requestControls,
-                             responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    gssapiSaslBind(saslProperties);
   }
 
 
@@ -3051,32 +1911,17 @@
     DirectoryServer.deregisterSASLMechanismHandler("PLAIN");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
+    try (Socket s = newSocket())
     {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"), "PLAIN",
-                             saslProperties, requestControls, responseControls);
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      plain(authHandler, saslProperties);
     }
     finally
     {
-      s.close();
-      DirectoryServer.registerSASLMechanismHandler("PLAIN",
-                                                   plainHandler);
+      DirectoryServer.registerSASLMechanismHandler("PLAIN", plainHandler);
     }
   }
 
@@ -3106,25 +1951,13 @@
          "userPassword: password");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"), "PLAIN",
-                           saslProperties, requestControls, responseControls);
-
-    s.close();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      plain(authHandler, saslProperties);
+    }
   }
 
 
@@ -3139,29 +1972,9 @@
   public void testDoSASLBindPlainNullProperties()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
-
     LinkedHashMap<String,List<String>> saslProperties = null;
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"), "PLAIN",
-                             saslProperties, requestControls, responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    plainSaslBind(saslProperties);
   }
 
 
@@ -3176,28 +1989,9 @@
   public void testDoSASLBindPlainEmptyProperties()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"), "PLAIN",
-                             saslProperties, requestControls, responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    plainSaslBind(saslProperties);
   }
 
 
@@ -3212,37 +2006,12 @@
   public void testDoSASLBindPlainMultipleAuthIDs()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test", "u:test.user"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("dn:uid=test.user,o=test");
-    valueList.add("u:test.user");
-    saslProperties.put("authid", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"), "PLAIN",
-                             saslProperties, requestControls, responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    plainSaslBind(saslProperties);
   }
 
-
-
   /**
    * Tests the <CODE>doSASLBind</CODE> method for the case in which the PLAIN
    * SASL properties have multiple auth ID values.
@@ -3253,32 +2022,10 @@
   public void testDoSASLBindPlainZeroLengthAuthID()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList(""));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("");
-    saslProperties.put("authid", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"), "PLAIN",
-                             saslProperties, requestControls, responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    plainSaslBind(saslProperties);
   }
 
 
@@ -3293,37 +2040,11 @@
   public void testDoSASLBindPlainMultipleAuthzIDs()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("authzid", newArrayList("dn:uid=test.user,o=test", "u:test.user"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", valueList);
-
-    valueList = new ArrayList<>();
-    valueList.add("dn:uid=test.user,o=test");
-    valueList.add("u:test.user");
-    saslProperties.put("authzid", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"), "PLAIN",
-                             saslProperties, requestControls, responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    plainSaslBind(saslProperties);
   }
 
 
@@ -3338,36 +2059,11 @@
   public void testDoSASLBindPlainInvalidProperty()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    saslProperties.put("invalid", newArrayList("foo"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", valueList);
-
-    valueList = new ArrayList<>();
-    valueList.add("foo");
-    saslProperties.put("invalid", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"), "PLAIN",
-                             saslProperties, requestControls, responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    plainSaslBind(saslProperties);
   }
 
 
@@ -3382,32 +2078,10 @@
   public void testDoSASLBindPlainNoAuthID()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+    saslProperties.put("authzid", newArrayList("dn:uid=test.user,o=test"));
 
-    ArrayList<String> valueList = new ArrayList<>();
-    valueList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authzid", valueList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    try
-    {
-      authHandler.doSASLBind(ByteString.empty(),
-                             ByteString.valueOfUtf8("password"), "PLAIN",
-                             saslProperties, requestControls, responseControls);
-    }
-    finally
-    {
-      s.close();
-    }
+    plainSaslBind(saslProperties);
   }
 
 
@@ -3425,34 +2099,21 @@
     TestCaseUtils.initializeTestBackend(true);
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
+    try (Socket s = newSocket())
+    {
+      LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
+      saslProperties.put("authid", newArrayList("dn:uid=does.not.exist,o=test"));
 
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
-    LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=does.not.exist,o=test");
-    saslProperties.put("authid", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"), "PLAIN",
-                           saslProperties, requestControls, responseControls);
-
-    s.close();
+      plain(newLDAPAuthenticationHandler(s, "localhost"), saslProperties);
+    }
   }
 
-
-
   /**
-   * Tests the <CODE>doSASLBind</CODE> method for PLAIN authentication in which
-   * the wrong password has been provided for the target user.
+   * Tests the <CODE>doSASLBind</CODE> method for PLAIN authentication in which the wrong password
+   * has been provided for the target user.
    *
-   * @throws  Exception  If an unexpected problem occurs.
+   * @throws Exception
+   *           If an unexpected problem occurs.
    */
   @Test(expectedExceptions = { LDAPException.class })
   public void testDoSASLBindPlainWrongPassword()
@@ -3472,25 +2133,13 @@
          "userPassword: password");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=does.not.exist,o=test");
-    saslProperties.put("authid", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("wrongPassword"), "PLAIN",
-                           saslProperties, requestControls, responseControls);
-
-    s.close();
+    saslProperties.put("authid", newArrayList("dn:uid=does.not.exist,o=test"));
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      doSASLBind("PLAIN", "wrongPassword", authHandler, saslProperties);
+    }
   }
 
 
@@ -3520,27 +2169,17 @@
          "userPassword: password");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
-
     requestControls.add(new PasswordPolicyRequestControl());
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"), "PLAIN",
-                           saslProperties, requestControls, responseControls);
-
-    s.close();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      authHandler.doSASLBind(ByteString.empty(), ByteString.valueOfUtf8("password"), "PLAIN", saslProperties,
+          requestControls, responseControls);
+    }
   }
 
 
@@ -3555,16 +2194,11 @@
   public void testRequestAuthorizationIdentityUnauthenticated()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    assertNull(authHandler.requestAuthorizationIdentity());
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      assertNull(authHandler.requestAuthorizationIdentity());
+    }
   }
 
 
@@ -3579,25 +2213,17 @@
   public void testRequestAuthorizationIdentitySimpleAnonymous()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
+    ArrayList<Control> requestControls = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
 
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSimpleBind(3, ByteString.empty(), ByteString.empty(),
-                             requestControls, responseControls);
-    assertNull(authHandler.requestAuthorizationIdentity());
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      authHandler.doSimpleBind(3, ByteString.empty(), ByteString.empty(), requestControls, responseControls);
+      assertNull(authHandler.requestAuthorizationIdentity());
+    }
   }
 
-
-
   /**
    * Tests the <CODE>requestAuthorizationIdentity</CODE> method for a a client
    * connection after a simple bind as a root user.
@@ -3608,22 +2234,15 @@
   public void testRequestAuthorizationIdentitySimpleRootUser()
          throws Exception
   {
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"),
-                             ByteString.valueOfUtf8("password"), requestControls,
-                             responseControls);
-    assertNotNull(authHandler.requestAuthorizationIdentity());
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"), ByteString.valueOfUtf8("password"),
+          requestControls, responseControls);
+      assertNotNull(authHandler.requestAuthorizationIdentity());
+    }
   }
 
 
@@ -3652,22 +2271,15 @@
          "userPassword: password");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
     ArrayList<Control> requestControls  = new ArrayList<>();
     ArrayList<Control> responseControls = new ArrayList<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSimpleBind(3, ByteString.valueOfUtf8("uid=test.user,o=test"),
-                             ByteString.valueOfUtf8("password"), requestControls,
-                             responseControls);
-    assertNotNull(authHandler.requestAuthorizationIdentity());
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      authHandler.doSimpleBind(3, ByteString.valueOfUtf8("uid=test.user,o=test"), ByteString.valueOfUtf8("password"),
+          requestControls, responseControls);
+      assertNotNull(authHandler.requestAuthorizationIdentity());
+    }
   }
 
 
@@ -3685,27 +2297,14 @@
     AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
     handler.initializeSASLMechanismHandler(null);
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("testDoSASLBindAnonymous");
-    saslProperties.put("trace", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    authHandler.doSASLBind(ByteString.empty(), ByteString.empty(),
-                           "ANONYMOUS", saslProperties, requestControls,
-                           responseControls);
-    assertNull(authHandler.requestAuthorizationIdentity());
-
-    s.close();
+    saslProperties.put("trace", newArrayList("testDoSASLBindAnonymous"));
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      anonymous(authHandler, saslProperties);
+      assertNull(authHandler.requestAuthorizationIdentity());
+    }
     handler.finalizeSASLMechanismHandler();
   }
 
@@ -3737,28 +2336,14 @@
               "cn=Password Policies,cn=config");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"),
-                           "CRAM-MD5", saslProperties, requestControls,
-                           responseControls);
-    assertNotNull(authHandler.requestAuthorizationIdentity());
-
-    s.close();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      cramMD5(authHandler, saslProperties);
+      assertNotNull(authHandler.requestAuthorizationIdentity());
+    }
   }
 
 
@@ -3789,29 +2374,15 @@
               "cn=Password Policies,cn=config");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
 
-    propList = new ArrayList<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, this.hostname, messageID);
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"),
-                           "DIGEST-MD5", saslProperties, requestControls,
-                           responseControls);
-    assertNotNull(authHandler.requestAuthorizationIdentity());
-
-    s.close();
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, hostname);
+      digestMD5(authHandler, saslProperties);
+      assertNotNull(authHandler.requestAuthorizationIdentity());
+    }
   }
 
 
@@ -3850,23 +2421,13 @@
                  "password");
 
 
-    Socket s = factory.createSocket("127.0.0.1",
-                                    TestCaseUtils.getServerLdapsPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSASLBind(ByteString.empty(), null, "EXTERNAL",
-                           saslProperties, requestControls, responseControls);
-    assertNotNull(authHandler.requestAuthorizationIdentity());
-
-    s.close();
+    try (Socket s = factory.createSocket("127.0.0.1", TestCaseUtils.getServerLdapsPort()))
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      doSASLBind("EXTERNAL", null, authHandler, saslProperties);
+      assertNotNull(authHandler.requestAuthorizationIdentity());
+    }
   }
 
 
@@ -3895,26 +2456,14 @@
          "userPassword: password");
 
 
-    Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
-    LDAPReader r = new LDAPReader(s);
-    LDAPWriter w = new LDAPWriter(s);
-
-    AtomicInteger          messageID        = new AtomicInteger(1);
-    ArrayList<Control> requestControls  = new ArrayList<>();
-    ArrayList<Control> responseControls = new ArrayList<>();
     LinkedHashMap<String, List<String>> saslProperties = new LinkedHashMap<>();
-    ArrayList<String> propList = new ArrayList<>();
-    propList.add("dn:uid=test.user,o=test");
-    saslProperties.put("authid", propList);
-
-    LDAPAuthenticationHandler authHandler =
-         new LDAPAuthenticationHandler(r, w, "localhost", messageID);
-    authHandler.doSASLBind(ByteString.empty(),
-                           ByteString.valueOfUtf8("password"), "PLAIN",
-                           saslProperties, requestControls, responseControls);
-    assertNotNull(authHandler.requestAuthorizationIdentity());
-
-    s.close();
+    saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
+    try (Socket s = newSocket())
+    {
+      LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "localhost");
+      plain(authHandler, saslProperties);
+      assertNotNull(authHandler.requestAuthorizationIdentity());
+    }
   }
 
   private void getFQDN() {
@@ -3924,6 +2473,4 @@
          this.hostname = "localhost";
       }
   }
-
 }
-
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/tools/RemoteConnection.java b/opendj-server-legacy/src/test/java/org/opends/server/tools/RemoteConnection.java
new file mode 100644
index 0000000..b2dbe0f
--- /dev/null
+++ b/opendj-server-legacy/src/test/java/org/opends/server/tools/RemoteConnection.java
@@ -0,0 +1,329 @@
+/*
+ * 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 2016 ForgeRock AS
+ */
+package org.opends.server.tools;
+
+import static org.forgerock.opendj.adapter.server3x.Converters.*;
+import static org.forgerock.opendj.ldap.requests.Requests.*;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.Socket;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.LdapException;
+import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.SearchScope;
+import org.forgerock.opendj.ldap.controls.Control;
+import org.forgerock.opendj.ldap.requests.AddRequest;
+import org.forgerock.opendj.ldap.requests.CompareRequest;
+import org.forgerock.opendj.ldap.requests.DeleteRequest;
+import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
+import org.forgerock.opendj.ldap.requests.ModifyRequest;
+import org.forgerock.opendj.ldap.requests.SearchRequest;
+import org.forgerock.opendj.ldap.requests.SimpleBindRequest;
+import org.opends.admin.ads.util.BlindTrustManager;
+import org.opends.server.TestCaseUtils;
+import org.opends.server.protocols.ldap.AddRequestProtocolOp;
+import org.opends.server.protocols.ldap.AddResponseProtocolOp;
+import org.opends.server.protocols.ldap.BindRequestProtocolOp;
+import org.opends.server.protocols.ldap.BindResponseProtocolOp;
+import org.opends.server.protocols.ldap.CompareRequestProtocolOp;
+import org.opends.server.protocols.ldap.CompareResponseProtocolOp;
+import org.opends.server.protocols.ldap.DeleteRequestProtocolOp;
+import org.opends.server.protocols.ldap.DeleteResponseProtocolOp;
+import org.opends.server.protocols.ldap.LDAPMessage;
+import org.opends.server.protocols.ldap.ModifyDNRequestProtocolOp;
+import org.opends.server.protocols.ldap.ModifyDNResponseProtocolOp;
+import org.opends.server.protocols.ldap.ModifyRequestProtocolOp;
+import org.opends.server.protocols.ldap.ModifyResponseProtocolOp;
+import org.opends.server.protocols.ldap.ProtocolOp;
+import org.opends.server.protocols.ldap.SearchRequestProtocolOp;
+import org.opends.server.protocols.ldap.SearchResultDoneProtocolOp;
+import org.opends.server.protocols.ldap.SearchResultEntryProtocolOp;
+import org.opends.server.types.LDAPException;
+
+/** Modeled like an SDK Connection, but implemented using the servers' ProtocolOp classes */
+@SuppressWarnings("javadoc")
+public final class RemoteConnection implements Closeable
+{
+  private final Socket socket;
+  private LDAPReader r;
+  private LDAPWriter w;
+  private int messageID;
+
+  public RemoteConnection(String host, int port) throws Exception
+  {
+    this(host, port, false);
+  }
+
+  public RemoteConnection(String host, int port, boolean secure) throws Exception
+  {
+    socket = secure ? getSslSocket(host, port) : new Socket(host, port);
+    r = new LDAPReader(socket);
+    w = new LDAPWriter(socket);
+    TestCaseUtils.configureSocket(socket);
+  }
+
+  private Socket getSslSocket(String host, int port) throws Exception
+  {
+    SSLContext sslCtx = SSLContext.getInstance("TLSv1");
+    TrustManager[] tm = new TrustManager[] { new BlindTrustManager() };
+    sslCtx.init(null, tm, new SecureRandom());
+    SSLSocketFactory socketFactory = sslCtx.getSocketFactory();
+    return socketFactory.createSocket(host, port);
+  }
+
+  public LDAPMessage bind(SimpleBindRequest bindRequest) throws IOException, LDAPException, LdapException
+  {
+    return bind(bindRequest, true);
+  }
+
+  public LDAPMessage bind(SimpleBindRequest bindRequest, boolean throwOnExceptionalResultCode) throws IOException,
+      LDAPException, LdapException
+  {
+    return bind(bindRequest.getName(), bindRequest.getPassword(), throwOnExceptionalResultCode, bindRequest
+        .getControls());
+  }
+
+  public LDAPMessage bind(String bindDN, String bindPassword, Control... controls)
+      throws IOException, LDAPException, LdapException
+  {
+    return bind(bindDN, bindPassword.getBytes(), true, Arrays.asList(controls));
+  }
+
+  private LDAPMessage bind(String bindDN, byte[] bindPassword, boolean throwOnExceptionalResultCode,
+      List<Control> controls) throws IOException, LDAPException, LdapException
+  {
+    writeMessage(new BindRequestProtocolOp(bs(bindDN), 3, bs(bindPassword)), to(controls));
+    LDAPMessage message = r.readMessage();
+    if (throwOnExceptionalResultCode)
+    {
+      BindResponseProtocolOp response = message.getBindResponseProtocolOp();
+      return validateNoException(message, response.getResultCode(), response.getErrorMessage());
+    }
+    return message;
+  }
+
+  public LDAPMessage add(AddRequest addRequest) throws IOException, LDAPException, LdapException
+  {
+    return add(addRequest, true);
+  }
+
+  public LDAPMessage add(AddRequest addRequest, boolean throwOnExceptionalResultCode) throws IOException,
+      LDAPException, LdapException
+  {
+    writeMessage(addProtocolOp(addRequest), to(addRequest.getControls()));
+    LDAPMessage message = r.readMessage();
+    if (throwOnExceptionalResultCode)
+    {
+      AddResponseProtocolOp response = message.getAddResponseProtocolOp();
+      return validateNoException(message, response.getResultCode(), response.getErrorMessage());
+    }
+    return message;
+  }
+
+  private AddRequestProtocolOp addProtocolOp(AddRequest add)
+  {
+    return new AddRequestProtocolOp(bs(add.getName()), to(add.getAllAttributes()));
+  }
+
+  public void search(String baseDN, SearchScope scope, String filterString, String... attributes) throws IOException,
+      LDAPException
+  {
+    search(newSearchRequest(baseDN, scope, filterString, attributes));
+  }
+
+  public void search(SearchRequest searchRequest) throws IOException, LDAPException, LdapException
+  {
+    writeMessage(searchProtocolOp(searchRequest), to(searchRequest.getControls()));
+  }
+
+  private SearchRequestProtocolOp searchProtocolOp(SearchRequest r) throws LDAPException
+  {
+    return new SearchRequestProtocolOp(bs(r.getName()), r.getScope(), r.getDereferenceAliasesPolicy(),
+        r.getSizeLimit(), r.getTimeLimit(), r.isTypesOnly(), to(r.getFilter()), new LinkedHashSet<>(r.getAttributes()));
+  }
+
+  public List<SearchResultEntryProtocolOp> readEntries() throws LDAPException, IOException
+  {
+    List<SearchResultEntryProtocolOp> entries = new ArrayList<>();
+    LDAPMessage msg;
+    while ((msg = r.readMessage()) != null)
+    {
+      ProtocolOp protocolOp = msg.getProtocolOp();
+      if (protocolOp instanceof SearchResultDoneProtocolOp)
+      {
+        SearchResultDoneProtocolOp done = (SearchResultDoneProtocolOp) protocolOp;
+        validateNoException(msg, done.getResultCode(), done.getErrorMessage());
+        return entries;
+      }
+      else if (protocolOp instanceof SearchResultEntryProtocolOp)
+      {
+        entries.add((SearchResultEntryProtocolOp) protocolOp);
+      }
+      else
+      {
+        throw new RuntimeException("Unexpected message " + protocolOp);
+      }
+    }
+    return entries;
+  }
+
+  public LDAPMessage modify(ModifyRequest modifyRequest) throws IOException, LDAPException, LdapException
+  {
+    return modify(modifyRequest, true);
+  }
+
+  public LDAPMessage modify(ModifyRequest modifyRequest, boolean throwOnExceptionalResultCode)
+      throws IOException, LDAPException, LdapException
+  {
+    writeMessage(modifyProtocolOp(modifyRequest), to(modifyRequest.getControls()));
+    LDAPMessage message = r.readMessage();
+    if (throwOnExceptionalResultCode)
+    {
+      ModifyResponseProtocolOp response = message.getModifyResponseProtocolOp();
+      return validateNoException(message, response.getResultCode(), response.getErrorMessage());
+    }
+    return message;
+  }
+
+  private ProtocolOp modifyProtocolOp(ModifyRequest r)
+  {
+    return new ModifyRequestProtocolOp(bs(r.getName()), toRawModifications(r.getModifications()));
+  }
+
+  public ModifyDNResponseProtocolOp modifyDN(String entryDN, String newRDN, boolean deleteOldRDN)
+      throws IOException, LDAPException, LdapException
+  {
+    writeMessage(new ModifyDNRequestProtocolOp(bs(entryDN), bs(newRDN), deleteOldRDN));
+    return r.readMessage().getModifyDNResponseProtocolOp();
+  }
+
+  public LDAPMessage modifyDN(ModifyDNRequest modifyDNRequest) throws IOException, LDAPException, LdapException
+  {
+    return modifyDN(modifyDNRequest, true);
+  }
+
+  public LDAPMessage modifyDN(ModifyDNRequest modifyDNRequest, boolean throwOnExceptionalResultCode)
+      throws IOException, LDAPException, LdapException
+  {
+    writeMessage(modDNProtocolOp(modifyDNRequest), to(modifyDNRequest.getControls()));
+    LDAPMessage message = r.readMessage();
+    if (throwOnExceptionalResultCode)
+    {
+      ModifyDNResponseProtocolOp response = message.getModifyDNResponseProtocolOp();
+      return validateNoException(message, response.getResultCode(), response.getErrorMessage());
+    }
+    return message;
+  }
+
+  private ModifyDNRequestProtocolOp modDNProtocolOp(ModifyDNRequest r)
+  {
+    return new ModifyDNRequestProtocolOp(bs(r.getName()), bs(r.getNewRDN()), r.isDeleteOldRDN(), bs(r.getNewSuperior()));
+  }
+
+  public LDAPMessage compare(CompareRequest compareRequest, boolean throwOnExceptionalResultCode) throws IOException,
+      LDAPException, LdapException
+  {
+    writeMessage(compareProtocolOp(compareRequest), to(compareRequest.getControls()));
+    LDAPMessage message = r.readMessage();
+    if (throwOnExceptionalResultCode)
+    {
+      CompareResponseProtocolOp response = message.getCompareResponseProtocolOp();
+      return validateNoException(message, response.getResultCode(), response.getErrorMessage());
+    }
+    return message;
+  }
+
+  private CompareRequestProtocolOp compareProtocolOp(CompareRequest r)
+  {
+    return new CompareRequestProtocolOp(bs(r.getName()), r.getAttributeDescription().toString(), r.getAssertionValue());
+  }
+
+  public LDAPMessage delete(DeleteRequest deleteRequest) throws IOException, LDAPException, LdapException
+  {
+    return delete(deleteRequest, true);
+  }
+
+  public LDAPMessage delete(DeleteRequest deleteRequest, boolean throwOnExceptionalResultCode) throws IOException,
+      LDAPException, LdapException
+  {
+    writeMessage(new DeleteRequestProtocolOp(bs(deleteRequest.getName())), to(deleteRequest.getControls()));
+    LDAPMessage message = r.readMessage();
+    if (throwOnExceptionalResultCode)
+    {
+      DeleteResponseProtocolOp response = message.getDeleteResponseProtocolOp();
+      return validateNoException(message, response.getResultCode(), response.getErrorMessage());
+    }
+    return message;
+  }
+
+  private ByteString bs(Object o)
+  {
+    return o != null ? ByteString.valueOfObject(o) : null;
+  }
+
+  public void writeMessage(ProtocolOp protocolOp) throws IOException
+  {
+    writeMessage(protocolOp, null);
+  }
+
+  public void writeMessage(ProtocolOp protocolOp, List<org.opends.server.types.Control> controls) throws IOException
+  {
+    w.writeMessage(new LDAPMessage(++messageID, protocolOp, controls));
+  }
+
+  public LDAPMessage readMessage() throws IOException, LDAPException
+  {
+    return r.readMessage();
+  }
+
+  private LDAPMessage validateNoException(LDAPMessage message, int resultCode, LocalizableMessage errorMessage)
+      throws LdapException
+  {
+    ResultCode rc = ResultCode.valueOf(resultCode);
+    if (rc.isExceptional())
+    {
+      throw LdapException.newLdapException(rc, errorMessage);
+    }
+    return message;
+  }
+
+  @Override
+  public void close() throws IOException
+  {
+    socket.close();
+  }
+}
\ No newline at end of file

--
Gitblit v1.10.0