From 45a05a46b927f19865e6a748873d70efe9a99ac5 Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 05 Aug 2016 18:41:17 +0000
Subject: [PATCH] Partial OPENDJ-2625 Convert all code that uses JNDI to use the SDK instead

---
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/LDAPEntryReader.java           |    8 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/LDAPConnectionPool.java     |   74 ++-
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java          |   38 -
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/DuplicateEntryPanel.java         |    6 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/DeleteEntryTask.java           |   18 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/BrowserController.java      |  306 +++++++----------
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractNewEntryPanel.java       |    3 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/ModifyEntryTask.java           |   12 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java  |   77 +--
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/NodeRefresher.java          |  135 +++----
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/AddToGroupTask.java            |    3 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AddToGroupPanel.java             |   25 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java          |   18 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/ConnectionWithControls.java |  211 ++++++++++++
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/ResetUserPasswordTask.java     |   11 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/NewEntryTask.java              |   41 +-
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewGroupPanel.java               |    9 
 17 files changed, 562 insertions(+), 433 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/BrowserController.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/BrowserController.java
index d201ebf..220fd83 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/BrowserController.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/BrowserController.java
@@ -20,11 +20,12 @@
 import static org.opends.server.util.ServerConstants.*;
 
 import java.awt.Font;
-import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
@@ -34,10 +35,6 @@
 import javax.naming.NameNotFoundException;
 import javax.naming.NamingException;
 import javax.naming.directory.SearchControls;
-import javax.naming.ldap.Control;
-import javax.naming.ldap.ManageReferralControl;
-import javax.naming.ldap.SortControl;
-import javax.naming.ldap.SortKey;
 import javax.swing.Icon;
 import javax.swing.JTree;
 import javax.swing.SwingUtilities;
@@ -49,6 +46,11 @@
 
 import org.forgerock.opendj.ldap.DN;
 import org.forgerock.opendj.ldap.Entry;
+import org.forgerock.opendj.ldap.Filter;
+import org.forgerock.opendj.ldap.SortKey;
+import org.forgerock.opendj.ldap.controls.Control;
+import org.forgerock.opendj.ldap.controls.ManageDsaITRequestControl;
+import org.forgerock.opendj.ldap.controls.ServerSideSortRequestControl;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
 import org.opends.admin.ads.ADSContext;
 import org.opends.admin.ads.util.ConnectionWrapper;
@@ -77,12 +79,20 @@
 public class BrowserController
 implements TreeExpansionListener, ReferralAuthenticationListener
 {
+  private static final Logger LOG = Logger.getLogger(BrowserController.class.getName());
+
   /** The mask used to display the number of ACIs or not. */
   private static final int DISPLAY_ACI_COUNT = 0x01;
 
   /** The list of attributes that are used to sort the entries (if the sorting option is used). */
-  private static final String[] SORT_ATTRIBUTES =
-      { "cn", "givenname", "o", "ou", "sn", "uid" };
+  private static final SortKey[] SORT_ATTRIBUTES = {
+    new SortKey("cn"),
+    new SortKey("givenname"),
+    new SortKey("o"),
+    new SortKey("ou"),
+    new SortKey("sn"),
+    new SortKey("uid")
+  };
 
   /**
    * This is a key value.  It is used to specify that the attribute that should
@@ -91,8 +101,8 @@
   private static final String RDN_ATTRIBUTE = "rdn attribute";
 
   /** The filter used to retrieve all the entries. */
-  public static final String ALL_OBJECTS_FILTER =
-    "(|(objectClass=*)(objectClass=ldapsubentry))";
+  public static final Filter ALL_OBJECTS_FILTER = Filter.valueOf(
+      "(|(objectClass=*)(objectClass=ldapsubentry))");
 
   private static final String NUMSUBORDINATES_ATTR = "numsubordinates";
   private static final String HASSUBORDINATES_ATTR = "hassubordinates";
@@ -101,17 +111,15 @@
   private final JTree tree;
   private final DefaultTreeModel treeModel;
   private final RootNode rootNode;
-  private int displayFlags;
-  private String displayAttribute;
-  private final boolean showAttributeName;
-  private ConnectionWrapper connConfig;
-  private ConnectionWrapper connUserData;
-  private boolean followReferrals;
-  private boolean sorted;
-  private boolean showContainerOnly;
+  private int displayFlags = DISPLAY_ACI_COUNT;
+  private String displayAttribute = RDN_ATTRIBUTE;
+  private final boolean showAttributeName = false;
+  private ConnectionWithControls connConfig;
+  private ConnectionWithControls connUserData;
+  private boolean showContainerOnly = true;
   private boolean automaticExpand;
   private boolean automaticallyExpandedNode;
-  private String[] containerClasses;
+  private String[] containerClasses = new String[0];
   private NumSubordinateHacker numSubordinateHacker;
   private int queueTotalSize;
   private int maxChildren;
@@ -121,10 +129,9 @@
 
   private final NodeSearcherQueue refreshQueue;
 
-  private String filter;
-
-  private static final Logger LOG =
-    Logger.getLogger(BrowserController.class.getName());
+  private ServerSideSortRequestControl sortControl;
+  private ManageDsaITRequestControl followReferralsControl;
+  private Filter filter;
 
   /**
    * Constructor of the BrowserController.
@@ -134,8 +141,7 @@
    * @param ipool the icon pool to be used to retrieve the icons that will be
    * used to render the nodes in the tree.
    */
-  public BrowserController(JTree tree, LDAPConnectionPool cpool,
-      IconPool ipool)
+  public BrowserController(JTree tree, LDAPConnectionPool cpool, IconPool ipool)
   {
     this.tree = tree;
     iconPool = ipool;
@@ -145,14 +151,6 @@
     tree.setModel(treeModel);
     tree.addTreeExpansionListener(this);
     tree.setCellRenderer(new BrowserCellRenderer());
-    displayFlags = DISPLAY_ACI_COUNT;
-    showAttributeName = false;
-    displayAttribute = RDN_ATTRIBUTE;
-    followReferrals = false;
-    sorted = false;
-    showContainerOnly = true;
-    containerClasses = new String[0];
-    queueTotalSize = 0;
     connectionPool = cpool;
     connectionPool.addReferralAuthenticationListener(this);
 
@@ -175,21 +173,18 @@
    * the configuration base DNs.
    * @param connUserData the connection to be used to retrieve the data in the
    * user base DNs.
-   * @throws NamingException if an error occurs.
    */
   public void setConnections(
       ServerDescriptor server,
       ConnectionWrapper connConfiguration,
-      ConnectionWrapper connUserData) throws NamingException {
+      ConnectionWrapper connUserData) {
     String rootNodeName;
     if (connConfiguration != null)
     {
-      this.connConfig = connConfiguration;
-      this.connUserData = connUserData;
-
-      connConfig.getLdapContext().setRequestControls(getConfigurationRequestControls());
-      connUserData.getLdapContext().setRequestControls(getRequestControls());
-      rootNodeName = new HostPort(server.getHostname(), connConfig.getHostPort().getPort()).toString();
+      this.connConfig = new ConnectionWithControls(connConfiguration, sortControl, followReferralsControl);
+      this.connUserData = new ConnectionWithControls(connUserData, sortControl, followReferralsControl);
+      rootNodeName = HostPort.toString(server.getHostname(),
+                                       connConfig.getConnectionWrapper().getHostPort().getPort());
     }
     else {
       rootNodeName = "";
@@ -202,7 +197,7 @@
    * Return the connection for accessing the directory configuration.
    * @return the connection for accessing the directory configuration.
    */
-  public ConnectionWrapper getConfigurationConnection() {
+  public ConnectionWithControls getConfigurationConnection() {
     return connConfig;
   }
 
@@ -210,7 +205,7 @@
    * Return the connection for accessing the directory user data.
    * @return the connection for accessing the directory user data.
    */
-  public ConnectionWrapper getUserDataConnection() {
+  public ConnectionWithControls getUserDataConnection() {
     return connUserData;
   }
 
@@ -342,6 +337,11 @@
    */
   public void setDisplayAttribute(String displayAttribute) {
     this.displayAttribute = displayAttribute;
+    restartRefresh();
+  }
+
+  private void restartRefresh()
+  {
     stopRefresh();
     removeAllChildNodes(rootNode, true /* Keep suffixes */);
     startRefresh(null);
@@ -384,55 +384,49 @@
 
   /**
    * Return true if this controller follows referrals.
-   * @return {@code true} if this controller follows referrals and
-   * {@code false} otherwise.
+   *
+   * @return {@code true} if this controller follows referrals, {@code false} otherwise.
    */
-  public boolean getFollowReferrals() {
-    return followReferrals;
+  public boolean isFollowReferrals() {
+    return followReferralsControl != null;
   }
 
   /**
    * Enable/display the following of referrals.
    * This routine starts a refresh on each referral node.
    * @param followReferrals whether to follow referrals or not.
-   * @throws NamingException if there is an error updating the request controls
-   * of the internal connections.
    */
-  public void setFollowReferrals(boolean followReferrals) throws NamingException
-  {
-    this.followReferrals = followReferrals;
-    stopRefresh();
-    removeAllChildNodes(rootNode, true /* Keep suffixes */);
-    connConfig.getLdapContext().setRequestControls(getConfigurationRequestControls());
-    connUserData.getLdapContext().setRequestControls(getRequestControls());
-    connectionPool.setRequestControls(getRequestControls());
-    startRefresh(null);
+  public void setFollowReferrals(boolean followReferrals) {
+    followReferralsControl = followReferrals ? ManageDsaITRequestControl.newControl(false) : null;
+    resetRequestControls();
+    restartRefresh();
   }
 
   /**
    * Return true if entries are displayed sorted.
-   * @return {@code true} if entries are displayed sorted and
-   * {@code false} otherwise.
+   *
+   * @return {@code true} if entries are displayed sorted, {@code false} otherwise.
    */
   public boolean isSorted() {
-    return sorted;
+    return sortControl != null;
   }
 
   /**
    * Enable/disable entry sort.
    * This routine collapses the JTree and invokes startRefresh().
    * @param sorted whether to sort the entries or not.
-   * @throws NamingException if there is an error updating the request controls
-   * of the internal connections.
    */
-  public void setSorted(boolean sorted) throws NamingException {
-    stopRefresh();
-    removeAllChildNodes(rootNode, true /* Keep suffixes */);
-    this.sorted = sorted;
-    connConfig.getLdapContext().setRequestControls(getConfigurationRequestControls());
-    connUserData.getLdapContext().setRequestControls(getRequestControls());
-    connectionPool.setRequestControls(getRequestControls());
-    startRefresh(null);
+  public void setSorted(boolean sorted) {
+    sortControl = sorted ? ServerSideSortRequestControl.newControl(false, SORT_ATTRIBUTES) : null;
+    resetRequestControls();
+    restartRefresh();
+  }
+
+  private void resetRequestControls()
+  {
+    this.connConfig.setRequestControls(sortControl, followReferralsControl);
+    this.connUserData.setRequestControls(sortControl, followReferralsControl);
+    this.connectionPool.setRequestControls(sortControl, followReferralsControl);
   }
 
   /**
@@ -531,7 +525,7 @@
     BasicNode parentNode = parentInfo.getNode();
     BasicNode childNode = new BasicNode(newEntryDn);
     int childIndex;
-    if (sorted) {
+    if (isSorted()) {
       childIndex = findChildNode(parentNode, newEntryDn);
       if (childIndex >= 0) {
         throw new IllegalArgumentException("Duplicate DN " + newEntryDn);
@@ -797,7 +791,7 @@
    * entries.
    * @param filter the LDAP filter.
    */
-  public void setFilter(String filter)
+  public void setFilter(Filter filter)
   {
     this.filter = filter;
   }
@@ -806,7 +800,7 @@
    * Returns the filter that is being used to search the entries.
    * @return the filter that is being used to search the entries.
    */
-  public String getFilter()
+  public Filter getFilter()
   {
     return filter;
   }
@@ -815,7 +809,7 @@
    * Returns the filter used to make a object base search.
    * @return the filter used to make a object base search.
    */
-  String getObjectSearchFilter()
+  Filter getObjectSearchFilter()
   {
     return ALL_OBJECTS_FILTER;
   }
@@ -826,43 +820,42 @@
    * container entries. If not, the filter will select all the children.
    * @return the LDAP search filter to use for searching child entries.
    */
-  String getChildSearchFilter() {
-    String result;
-    if (showContainerOnly) {
-      if (followReferrals) {
-        /* In the case we are following referrals, we have to consider referrals
-         as nodes.
-         Suppose the following scenario: a referral points to a remote entry
-         that has children (node), BUT the referral entry in the local server
-         has no children.  It won't be included in the filter and it won't
-         appear in the tree.  But what we are displaying is the remote entry,
-         the result is that we have a NODE that does not appear in the tree and
-         so the user cannot browse it.
-
-         This has some side effects:
-         If we cannot follow the referral, a leaf will appear on the tree (as it
-         if were a node).
-         If the referral points to a leaf entry, a leaf will appear on the tree
-         (as if it were a node).
-
-         This is minor compared to the impossibility of browsing a subtree with
-         the NODE/LEAF layout.
-         */
-        result = "(|(&(hasSubordinates=true)"+filter+")(objectClass=referral)";
-      } else {
-        result = "(|(&(hasSubordinates=true)"+filter+")";
-      }
-      for (String containerClass : containerClasses)
-      {
-        result += "(objectClass=" + containerClass + ")";
-      }
-      result += ")";
-    }
-    else {
-      result = filter;
+  Filter getChildSearchFilter()
+  {
+    if (!showContainerOnly)
+    {
+      return filter;
     }
 
-    return result;
+    String result = "(|(&(hasSubordinates=true)" + filter + ")";
+    if (isFollowReferrals()) {
+      /* In the case we are following referrals, we have to consider referrals
+       as nodes.
+       Suppose the following scenario: a referral points to a remote entry
+       that has children (node), BUT the referral entry in the local server
+       has no children.  It won't be included in the filter and it won't
+       appear in the tree.  But what we are displaying is the remote entry,
+       the result is that we have a NODE that does not appear in the tree and
+       so the user cannot browse it.
+
+       This has some side effects:
+       If we cannot follow the referral, a leaf will appear on the tree (as it
+       if were a node).
+       If the referral points to a leaf entry, a leaf will appear on the tree
+       (as if it were a node).
+
+       This is minor compared to the impossibility of browsing a subtree with
+       the NODE/LEAF layout.
+       */
+      result += "(objectClass=referral)";
+    }
+    for (String containerClass : containerClasses)
+    {
+      result += "(objectClass=" + containerClass + ")";
+    }
+    result += ")";
+
+    return Filter.valueOf(result);
   }
 
   /**
@@ -871,8 +864,7 @@
    * @throws NamingException if there is an error retrieving the connection.
    * @return the LDAP connection to reading the base entry of a node.
    */
-  ConnectionWrapper findConnectionForLocalEntry(BasicNode node)
-  throws NamingException {
+  ConnectionWithControls findConnectionForLocalEntry(BasicNode node) throws NamingException {
     return findConnectionForLocalEntry(node, isConfigurationNode(node));
   }
 
@@ -883,7 +875,7 @@
    * @throws NamingException if there is an error retrieving the connection.
    * @return the LDAP connection to reading the base entry of a node.
    */
-  private ConnectionWrapper findConnectionForLocalEntry(BasicNode node,
+  private ConnectionWithControls findConnectionForLocalEntry(BasicNode node,
       boolean isConfigurationNode) throws NamingException
   {
     if (node == rootNode) {
@@ -936,8 +928,7 @@
    * @return the LDAP connection to search the displayed entry.
    * @throws NamingException if there is an error retrieving the connection.
    */
-  public ConnectionWrapper findConnectionForDisplayedEntry(BasicNode node)
-  throws NamingException {
+  public ConnectionWithControls findConnectionForDisplayedEntry(BasicNode node) throws NamingException {
     return findConnectionForDisplayedEntry(node, isConfigurationNode(node));
   }
 
@@ -949,9 +940,9 @@
    * @return the LDAP connection to search the displayed entry.
    * @throws NamingException if there is an error retrieving the connection.
    */
-  private ConnectionWrapper findConnectionForDisplayedEntry(BasicNode node,
+  private ConnectionWithControls findConnectionForDisplayedEntry(BasicNode node,
       boolean isConfigurationNode) throws NamingException {
-    if (followReferrals && node.getRemoteUrl() != null)
+    if (isFollowReferrals() && node.getRemoteUrl() != null)
     {
       return connectionPool.getConnection(node.getRemoteUrl());
     }
@@ -963,7 +954,7 @@
    * selectConnectionForBaseEntry().
    * @param conn the connection to be released.
    */
-  void releaseLDAPConnection(ConnectionWrapper conn) {
+  void releaseLDAPConnection(ConnectionWithControls conn) {
     if (conn != connConfig && conn != connUserData)
     {
       // Thus it comes from the connection pool
@@ -977,8 +968,9 @@
    * @return the local entry URL for a given node.
    */
   LDAPURL findUrlForLocalEntry(BasicNode node) {
+    ConnectionWrapper conn = connConfig.getConnectionWrapper();
     if (node == rootNode) {
-      return LDAPConnectionPool.makeLDAPUrl(connConfig.getHostPort(), "", connConfig.isLdaps());
+      return LDAPConnectionPool.makeLDAPUrl(conn.getHostPort(), "", conn.isLdaps());
     }
     final BasicNode parent = (BasicNode) node.getParent();
     if (parent != null)
@@ -986,7 +978,7 @@
       final LDAPURL parentUrl = findUrlForDisplayedEntry(parent);
       return LDAPConnectionPool.makeLDAPUrl(parentUrl, node.getDN().toString());
     }
-    return LDAPConnectionPool.makeLDAPUrl(connConfig.getHostPort(), node.getDN().toString(), connConfig.isLdaps());
+    return LDAPConnectionPool.makeLDAPUrl(conn.getHostPort(), node.getDN().toString(), conn.isLdaps());
   }
 
   /**
@@ -996,7 +988,7 @@
    */
   private LDAPURL findUrlForDisplayedEntry(BasicNode node)
   {
-    if (followReferrals && node.getRemoteUrl() != null) {
+    if (isFollowReferrals() && node.getRemoteUrl() != null) {
       return node.getRemoteUrl();
     }
     return findUrlForLocalEntry(node);
@@ -1011,11 +1003,11 @@
    * @param node the node.
    * @return the DN to use for searching children of a given node.
    */
-  String findBaseDNForChildEntries(BasicNode node) {
-    if (followReferrals && node.getRemoteUrl() != null) {
-      return node.getRemoteUrl().getRawBaseDN();
+  DN findBaseDNForChildEntries(BasicNode node) {
+    if (isFollowReferrals() && node.getRemoteUrl() != null) {
+      return DN.valueOf(node.getRemoteUrl().getRawBaseDN());
     }
-    return node.getDN().toString();
+    return node.getDN();
   }
 
   /**
@@ -1025,7 +1017,7 @@
    * {@code false} otherwise.
    */
   private boolean isDisplayedEntryRemote(BasicNode node) {
-    if (followReferrals) {
+    if (isFollowReferrals()) {
       if (node == rootNode) {
         return false;
       }
@@ -1099,48 +1091,18 @@
    * Returns the request controls to search user data.
    * @return the request controls to search user data.
    */
-  private Control[] getRequestControls()
+  private List<Control> getRequestControls()
   {
-    Control ctls[];
-    if (followReferrals)
+    List<Control> controls = new LinkedList<>();
+    if (sortControl != null)
     {
-      ctls = new Control[sorted ? 2 : 1];
+      controls.add(sortControl);
     }
-    else
+    if (isFollowReferrals())
     {
-      ctls = new Control[sorted ? 1 : 0];
+      controls.add(followReferralsControl);
     }
-    if (sorted)
-    {
-      SortKey[] keys = new SortKey[SORT_ATTRIBUTES.length];
-      for (int i=0; i<keys.length; i++) {
-        keys[i] = new SortKey(SORT_ATTRIBUTES[i]);
-      }
-      try
-      {
-        ctls[0] = new SortControl(keys, false);
-      }
-      catch (IOException ioe)
-      {
-        // Bug
-        throw new RuntimeException("Unexpected encoding exception: "+ioe,
-            ioe);
-      }
-    }
-    if (followReferrals)
-    {
-      ctls[ctls.length - 1] = new ManageReferralControl(false);
-    }
-    return ctls;
-  }
-
-  /**
-   * Returns the request controls to search configuration data.
-   * @return the request controls to search configuration data.
-   */
-  private Control[] getConfigurationRequestControls()
-  {
-    return getRequestControls();
+    return controls;
   }
 
   /**
@@ -1165,11 +1127,10 @@
    * @param task the task that progressed.
    * @param oldState the previous state of the task.
    * @param newState the new state of the task.
-   * @throws NamingException if there is an error reading entries.
    */
   private void refreshTaskDidProgress(NodeRefresher task,
       NodeRefresher.State oldState,
-      NodeRefresher.State newState) throws NamingException {
+      NodeRefresher.State newState) {
     BasicNode node = task.getNode();
     boolean nodeChanged = false;
 
@@ -1344,9 +1305,8 @@
   /**
    * Updates the child nodes for a given task.
    * @param task the task.
-   * @throws NamingException if an error occurs.
    */
-  private void updateChildNodes(NodeRefresher task) throws NamingException {
+  private void updateChildNodes(NodeRefresher task) {
     BasicNode parent = task.getNode();
     ArrayList<Integer> insertIndex = new ArrayList<>();
     ArrayList<Integer> changedIndex = new ArrayList<>();
@@ -1454,8 +1414,7 @@
    * @param entry the search result for the entry that the node represents.
    * @return whether the node display changed
    */
-  private boolean updateNodeRendering(BasicNode node, SearchResultEntry entry)
-  throws NamingException {
+  private boolean updateNodeRendering(BasicNode node, SearchResultEntry entry) {
     if (entry != null) {
       node.setNumSubOrdinates(getNumSubOrdinates(entry));
       node.setHasSubOrdinates(
@@ -1545,7 +1504,7 @@
 
   private String getRDN(BasicNode node)
   {
-    if (followReferrals && node.getRemoteUrl() != null) {
+    if (isFollowReferrals() && node.getRemoteUrl() != null) {
       if (showAttributeName) {
         return node.getRemoteRDNWithAttributeName();
       } else {
@@ -1561,7 +1520,7 @@
     }
   }
 
-  private int getAciCount(SearchResultEntry entry) throws NamingException
+  private int getAciCount(SearchResultEntry entry)
   {
     if ((displayFlags & DISPLAY_ACI_COUNT) != 0 && entry != null) {
       return asSetOfString(entry, "aci").size();
@@ -1610,7 +1569,7 @@
    * @param childDn the DN of the entry that is being searched.
    * @return the index of the node matching childDn.
    */
-  public int findChildNode(BasicNode parent, DN childDn) {
+  public static int findChildNode(BasicNode parent, DN childDn) {
     int childCount = parent.getChildCount();
     int i = 0;
     while (i < childCount
@@ -1700,7 +1659,7 @@
    * @throws IllegalArgumentException if a node with the given dn exists but
    * is not a suffix node.
    */
-  private SuffixNode findSuffixNode(DN suffixDn, SuffixNode suffixNode)
+  private static SuffixNode findSuffixNode(DN suffixDn, SuffixNode suffixNode)
       throws IllegalArgumentException
   {
     if (suffixNode.getDN().equals(suffixDn)) {
@@ -1797,11 +1756,10 @@
    * Returns the value of the 'ref' attribute.
    * {@code null} if the attribute is not present.
    * @param entry the entry to analyze.
-   * @throws NamingException if an error occurs.
    * @return the value of the ref attribute.  {@code null} if the attribute
    * could not be found.
    */
-  public static String[] getReferral(SearchResultEntry entry) throws NamingException
+  public static String[] getReferral(SearchResultEntry entry)
   {
     Set<String> values = asSetOfString(entry, OBJECTCLASS_ATTRIBUTE_TYPE_NAME);
     for (String value : values)
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/ConnectionWithControls.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/ConnectionWithControls.java
new file mode 100644
index 0000000..6b7580a
--- /dev/null
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/ConnectionWithControls.java
@@ -0,0 +1,211 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development and
+ * Distribution License (the License). You may not use this file except in compliance with the
+ * License.
+ *
+ * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+ * specific language governing permission and limitations under the License.
+ *
+ * When distributing Covered Software, include this CDDL Header Notice in each file and include
+ * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+ * Header, with the fields enclosed by brackets [] replaced by your own identifying
+ * information: "Portions Copyright [year] [name of copyright owner]".
+ *
+ * Copyright 2016 ForgeRock AS.
+ */
+package org.opends.guitools.controlpanel.browser;
+
+import java.io.Closeable;
+
+import org.forgerock.opendj.ldap.LdapException;
+import org.forgerock.opendj.ldap.controls.ManageDsaITRequestControl;
+import org.forgerock.opendj.ldap.controls.ServerSideSortRequestControl;
+import org.forgerock.opendj.ldap.requests.AddRequest;
+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.Request;
+import org.forgerock.opendj.ldap.requests.SearchRequest;
+import org.forgerock.opendj.ldap.responses.SearchResultEntry;
+import org.forgerock.opendj.ldif.ConnectionEntryReader;
+import org.forgerock.util.Reject;
+import org.opends.admin.ads.util.ConnectionWrapper;
+
+/**
+ * Associates a {@link ConnectionWrapper} with the LDAP
+ * {@link org.forgerock.opendj.ldap.controls.Control Control}s it should use when performing
+ * operation.
+ * <p>
+ * The relevant controls are automatically added to the request when calling
+ * {@link #add(AddRequest)}, {@link #delete(DeleteRequest)}, {@link #modify(ModifyRequest)},
+ * {@link #modifyDN(ModifyDNRequest)}, {@link #search(SearchRequest)} or
+ * {@link #searchSingleEntry(SearchRequest)}.
+ */
+public final class ConnectionWithControls implements Closeable
+{
+  private final ConnectionWrapper conn;
+  private ServerSideSortRequestControl sortControl;
+  private ManageDsaITRequestControl followReferralsControl;
+
+  /**
+   * Constructor.
+   *
+   * @param conn
+   *          the connection wrapper
+   * @param sortControl
+   *          the sort control, may be {@code null}
+   * @param followReferralsControl
+   *          the manage dsa IT control, may be {@code null}
+   */
+  public ConnectionWithControls(ConnectionWrapper conn,
+                                ServerSideSortRequestControl sortControl,
+                                ManageDsaITRequestControl followReferralsControl)
+  {
+    this.conn = Reject.checkNotNull(conn);
+    setRequestControls(sortControl, followReferralsControl);
+  }
+
+  /**
+   * Returns the connection wrapper.
+   * <p>
+   * DO NOT USE TO PERFORM LDAP OPERATIONS!
+   * <p>
+   * This getter is only used to allow to query its state.
+   *
+   * @return the read-only connection wrapper.
+   */
+  public ConnectionWrapper getConnectionWrapper()
+  {
+    return conn;
+  }
+
+  /**
+   * Sets the sort and manage dsa it controls to use when making LDAP operations.
+   *
+   * @param sortControl
+   *          the sort control, may be {@code null}
+   * @param followReferralsControl
+   *          the manage dsa IT control, may be {@code null}
+   */
+  public void setRequestControls(
+      ServerSideSortRequestControl sortControl,
+      ManageDsaITRequestControl followReferralsControl)
+  {
+    this.sortControl = sortControl;
+    this.followReferralsControl = followReferralsControl;
+  }
+
+  /**
+   * Adds the sort and referral controls if needed.
+   *
+   * @param request
+   *          the request
+   */
+  void addControls(Request request)
+  {
+    if (sortControl != null && request instanceof SearchRequest)
+    {
+      request.addControl(sortControl);
+    }
+    if (followReferralsControl != null)
+    {
+      request.addControl(followReferralsControl);
+    }
+  }
+
+  /**
+   * Searches a single entry.
+   *
+   * @param request
+   *          the request
+   * @return the non-{@code null} single SearchResultEntry
+   * @throws LdapException
+   *           if an error occurred.
+   * @see org.forgerock.opendj.ldap.Connection#searchSingleEntry(SearchRequest)
+   */
+  public SearchResultEntry searchSingleEntry(SearchRequest request) throws LdapException
+  {
+    addControls(request);
+    return conn.getConnection().searchSingleEntry(request);
+  }
+
+  /**
+   * Searches using the provided request.
+   *
+   * @param request
+   *          the request
+   * @return a non-{@code null} {@link ConnectionEntryReader}
+   * @see org.forgerock.opendj.ldap.Connection#search(SearchRequest)
+   */
+  public ConnectionEntryReader search(SearchRequest request)
+  {
+    addControls(request);
+    return conn.getConnection().search(request);
+  }
+
+  /**
+   * Adds with the provided request.
+   *
+   * @param request
+   *          the request
+   * @throws LdapException
+   *           if an error occurred.
+   * @see org.forgerock.opendj.ldap.Connection#add(AddRequest)
+   */
+  public void add(AddRequest request) throws LdapException
+  {
+    addControls(request);
+    conn.getConnection().add(request);
+  }
+
+  /**
+   * Deletes with the provided request.
+   *
+   * @param request
+   *          the request
+   * @throws LdapException
+   *           if an error occurred.
+   * @see org.forgerock.opendj.ldap.Connection#delete(DeleteRequest)
+   */
+  public void delete(DeleteRequest request) throws LdapException
+  {
+    addControls(request);
+    conn.getConnection().delete(request);
+  }
+
+  /**
+   * Modifies with the provided request.
+   *
+   * @param request
+   *          the request
+   * @throws LdapException
+   *           if an error occurred.
+   * @see org.forgerock.opendj.ldap.Connection#modify(ModifyRequest)
+   */
+  public void modify(ModifyRequest request) throws LdapException
+  {
+    addControls(request);
+    conn.getConnection().modify(request);
+  }
+
+  /**
+   * modifies a DN with the provided request.
+   *
+   * @param request
+   *          the request
+   * @throws LdapException
+   *           if an error occurred.
+   * @see org.forgerock.opendj.ldap.Connection#modifyDN(ModifyDNRequest)
+   */
+  public void modifyDN(ModifyDNRequest request) throws LdapException
+  {
+    addControls(request);
+    conn.getConnection().modifyDN(request);
+  }
+
+  @Override
+  public void close()
+  {
+    conn.close();
+  }
+}
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/LDAPConnectionPool.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/LDAPConnectionPool.java
index 3e79cb1..5e3a443 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/LDAPConnectionPool.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/LDAPConnectionPool.java
@@ -22,11 +22,12 @@
 import java.util.HashMap;
 
 import javax.naming.NamingException;
-import javax.naming.ldap.Control;
 import javax.net.ssl.KeyManager;
 
 import org.forgerock.opendj.ldap.DN;
 import org.forgerock.opendj.ldap.SearchScope;
+import org.forgerock.opendj.ldap.controls.ManageDsaITRequestControl;
+import org.forgerock.opendj.ldap.controls.ServerSideSortRequestControl;
 import org.opends.admin.ads.util.ApplicationTrustManager;
 import org.opends.admin.ads.util.ConnectionWrapper;
 import org.opends.admin.ads.util.PreferredConnection.Type;
@@ -70,28 +71,33 @@
 
   private ArrayList<ReferralAuthenticationListener> listeners;
 
-  private Control[] requestControls = new Control[] {};
+  private ServerSideSortRequestControl sortControl;
+  private ManageDsaITRequestControl followReferralsControl;
   private ApplicationTrustManager trustManager;
   private int connectTimeout = CliConstants.DEFAULT_LDAP_CONNECT_TIMEOUT;
 
   /**
-   * Returns <CODE>true</CODE> if the connection passed is registered in the
-   * connection pool, <CODE>false</CODE> otherwise.
-   * @param conn the connection.
-   * @return <CODE>true</CODE> if the connection passed is registered in the
-   * connection pool, <CODE>false</CODE> otherwise.
+   * Returns whether the connection passed is registered in the connection pool.
+   *
+   * @param conn
+   *          the connection.
+   * @return {@code true} if the connection passed is registered in the connection pool,
+   *         {@code false} otherwise.
    */
   public boolean isConnectionRegistered(ConnectionWrapper conn) {
     for (String key : connectionTable.keySet())
     {
-      ConnectionRecord cr = connectionTable.get(key);
-      if (cr.conn != null
-          && cr.conn.getHostPort().equals(conn.getHostPort())
-          && cr.conn.getBindDn().equals(conn.getBindDn())
-          && cr.conn.getBindPassword().equals(conn.getBindPassword())
-          && cr.conn.getConnectionType() == conn.getConnectionType())
+      final ConnectionRecord cr = connectionTable.get(key);
+      if (cr.conn != null)
       {
-        return true;
+        final ConnectionWrapper c = cr.conn.getConnectionWrapper();
+        if (c.getHostPort().equals(conn.getHostPort())
+            && c.getBindDn().equals(conn.getBindDn())
+            && c.getBindPassword().equals(conn.getBindPassword())
+            && c.getConnectionType() == conn.getConnectionType())
+        {
+          return true;
+        }
       }
     }
     return false;
@@ -106,7 +112,7 @@
     LDAPURL url = makeLDAPUrl(conn);
     String key = makeKeyFromLDAPUrl(url);
     ConnectionRecord cr = new ConnectionRecord();
-    cr.conn = conn;
+    cr.conn = new ConnectionWithControls(conn, sortControl, followReferralsControl);
     cr.counter = 1;
     cr.disconnectAfterUse = false;
     connectionTable.put(key, cr);
@@ -155,8 +161,8 @@
    * @return a connection to the provided LDAP URL.
    * @throws NamingException if there was an error connecting.
    */
-  public ConnectionWrapper getConnection(LDAPURL ldapUrl)
-  throws NamingException {
+  public ConnectionWithControls getConnection(LDAPURL ldapUrl) throws NamingException
+  {
     String key = makeKeyFromLDAPUrl(ldapUrl);
     ConnectionRecord cr;
 
@@ -186,7 +192,6 @@
             registerAuth = true;
           }
           cr.conn = createLDAPConnection(ldapUrl, authRecord);
-          cr.conn.getLdapContext().setRequestControls(requestControls);
           if (registerAuth)
           {
             authTable.put(key, authRecord);
@@ -208,20 +213,24 @@
   }
 
   /**
-   * Sets the request controls to be used by the connections of this connection
-   * pool.
-   * @param ctls the request controls.
-   * @throws NamingException if an error occurs updating the connections.
+   * Sets the request controls to be used by the connections of this connection pool.
+   *
+   * @param sortControl
+   *          the sort control.
+   * @param followReferralsControl
+   *          the manage dsa it control.
    */
-  public synchronized void setRequestControls(Control[] ctls)
-  throws NamingException
+  public synchronized void setRequestControls(
+      ServerSideSortRequestControl sortControl,
+      ManageDsaITRequestControl followReferralsControl)
   {
-    requestControls = ctls;
+    this.sortControl = sortControl;
+    this.followReferralsControl = followReferralsControl;
     for (ConnectionRecord cr : connectionTable.values())
     {
       if (cr.conn != null)
       {
-        cr.conn.getLdapContext().setRequestControls(requestControls);
+        cr.conn.setRequestControls(sortControl, followReferralsControl);
       }
     }
   }
@@ -234,7 +243,7 @@
    * @param conn
    *          the connection to be released.
    */
-  public synchronized void releaseConnection(ConnectionWrapper conn) {
+  public synchronized void releaseConnection(ConnectionWithControls conn) {
     String targetKey = null;
     ConnectionRecord targetRecord = null;
     synchronized(this) {
@@ -377,7 +386,8 @@
    * @return the key to be used in Maps for the provided connection record.
    */
   private static String makeKeyFromRecord(ConnectionRecord rec) {
-    return (rec.conn.isLdaps() ? "LDAPS" : "LDAP") + ":" + rec.conn.getHostPort();
+    ConnectionWrapper conn = rec.conn.getConnectionWrapper();
+    return (conn.isLdaps() ? "LDAPS" : "LDAP") + ":" + conn.getHostPort();
   }
 
   /**
@@ -388,12 +398,13 @@
    * @return a connection.
    * @throws NamingException if an error occurs when connecting.
    */
-  private ConnectionWrapper createLDAPConnection(LDAPURL ldapUrl, AuthRecord ar) throws NamingException
+  private ConnectionWithControls createLDAPConnection(LDAPURL ldapUrl, AuthRecord ar) throws NamingException
   {
     final HostPort hostPort = new HostPort(ldapUrl.getHost(), ldapUrl.getPort());
     final Type connectiontype = isSecureLDAPUrl(ldapUrl) ? LDAPS : LDAP;
-    return new ConnectionWrapper(hostPort, connectiontype, ar.dn, ar.password,
+    final ConnectionWrapper conn = new ConnectionWrapper(hostPort, connectiontype, ar.dn, ar.password,
         getConnectTimeout(), getTrustManager(), getKeyManager());
+    return new ConnectionWithControls(conn, sortControl, followReferralsControl);
   }
 
   /**
@@ -496,7 +507,6 @@
         null, // No filter
         null); // No extensions
   }
-
 }
 
 /** A structure representing authentication data. */
@@ -507,7 +517,7 @@
 
 /** A structure representing an active connection. */
 class ConnectionRecord {
-  ConnectionWrapper conn;
+  ConnectionWithControls conn;
   int counter;
   boolean disconnectAfterUse;
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/NodeRefresher.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/NodeRefresher.java
index aefdafe..8dd1954 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/NodeRefresher.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/browser/NodeRefresher.java
@@ -36,6 +36,7 @@
 
 import org.forgerock.i18n.LocalizedIllegalArgumentException;
 import org.forgerock.opendj.ldap.DN;
+import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.LdapException;
 import org.forgerock.opendj.ldap.RDN;
 import org.forgerock.opendj.ldap.ResultCode;
@@ -187,7 +188,7 @@
    * BrowserController is following referrals and the local entry otherwise.
    */
   public SearchResultEntry getDisplayedEntry() {
-    if (controller.getFollowReferrals() && remoteEntry != null)
+    if (controller.isFollowReferrals() && remoteEntry != null)
     {
       return remoteEntry;
     }
@@ -204,7 +205,7 @@
    * otherwise.
    */
   public LDAPURL getDisplayedUrl() {
-    if (controller.getFollowReferrals() && remoteUrl != null)
+    if (controller.isFollowReferrals() && remoteUrl != null)
     {
       return remoteUrl;
     }
@@ -235,7 +236,7 @@
         runReadLocalEntry();
       }
       if (!isInFinalState()) {
-        if (controller.getFollowReferrals() && isReferralEntry(localEntry)) {
+        if (controller.isFollowReferrals() && isReferralEntry(localEntry)) {
           changeStateTo(State.SOLVING_REFERRAL);
           runSolveReferral();
         }
@@ -302,12 +303,12 @@
    * @throws IOException
    *           if a problem occurred.
    */
-  private void searchForCustomFilter(BasicNode node, ConnectionWrapper conn) throws IOException
+  private void searchForCustomFilter(BasicNode node, ConnectionWithControls conn) throws IOException
   {
     SearchRequest request =
-        newSearchRequest(node.getDN().toString(), WHOLE_SUBTREE, controller.getFilter(), NO_ATTRIBUTES)
-        .setSizeLimit(1);
-    try (ConnectionEntryReader s = conn.getConnection().search(request))
+        newSearchRequest(node.getDN(), WHOLE_SUBTREE, controller.getFilter(), NO_ATTRIBUTES)
+            .setSizeLimit(1);
+    try (ConnectionEntryReader s = conn.search(request))
     {
       if (!s.hasNext())
       {
@@ -342,11 +343,11 @@
    * @param conn the connection to be used.
    * @throws IOException if a problem occurred.
    */
-  private void searchForCustomFilter(String dn, ConnectionWrapper conn) throws IOException
+  private void searchForCustomFilter(DN dn, ConnectionWithControls conn) throws IOException
   {
     SearchRequest request = newSearchRequest(dn, WHOLE_SUBTREE, controller.getFilter())
         .setSizeLimit(1);
-    try (ConnectionEntryReader entryReader = conn.getConnection().search(request))
+    try (ConnectionEntryReader entryReader = conn.search(request))
     {
       if (!entryReader.hasNext())
       {
@@ -375,7 +376,7 @@
   /** Read the local entry associated to the current node. */
   private void runReadLocalEntry() throws SearchAbandonException {
     BasicNode node = getNode();
-    ConnectionWrapper conn = null;
+    ConnectionWithControls conn = null;
     try {
       conn = controller.findConnectionForLocalEntry(node);
 
@@ -386,15 +387,10 @@
           searchForCustomFilter(node, conn);
         }
 
-        String filter = controller.getObjectSearchFilter();
         SearchRequest request =
-            newSearchRequest(node.getDN().toString(), BASE_OBJECT, filter, controller.getAttrsForRedSearch())
-            .setSizeLimit(controller.getMaxChildren());
-        localEntry = conn.getConnection().searchSingleEntry(request);
-        if (localEntry == null) {
-          /* Not enough rights to read the entry or the entry simply does not exist */
-          throw newLdapException(ResultCode.NO_SUCH_OBJECT, "Can't find entry: " + node.getDN());
-        }
+            newSearchRequest(node.getDN(), BASE_OBJECT, controller.getObjectSearchFilter(), controller
+                .getAttrsForRedSearch()).setSizeLimit(controller.getMaxChildren());
+        localEntry = conn.searchSingleEntry(request);
         throwAbandonIfNeeded(null);
       } else {
           changeStateTo(State.FINISHED);
@@ -447,40 +443,40 @@
     LDAPConnectionPool connectionPool = controller.getConnectionPool();
     LDAPURL url = null;
     SearchResultEntry entry = null;
-    String remoteDn = null;
+    DN remoteDn = null;
     Exception lastException = null;
     Object lastExceptionArg = null;
 
     int i = 0;
     while (i < referral.length && entry == null)
     {
-      ConnectionWrapper conn = null;
+      ConnectionWithControls conn = null;
       try {
         url = LDAPURL.decode(referral[i], false);
         if (url.getHost() == null)
         {
           // Use the local server connection.
-          ConnectionWrapper userConn = controller.getUserDataConnection();
+          ConnectionWrapper userConn = controller.getUserDataConnection().getConnectionWrapper();
           HostPort hostPort = userConn.getHostPort();
           url.setHost(hostPort.getHost());
           url.setPort(hostPort.getPort());
           url.setScheme(userConn.isLdaps() ? "ldaps" : "ldap");
         }
         conn = connectionPool.getConnection(url);
-        remoteDn = url.getRawBaseDN();
+        remoteDn = DN.valueOf(url.getRawBaseDN());
         if (remoteDn == null || "".equals(remoteDn))
         {
           /* The referral has not a target DN specified: we
              have to use the DN of the entry that contains the
              referral... */
           if (remoteEntry != null) {
-            remoteDn = remoteEntry.getName().toString();
+            remoteDn = remoteEntry.getName();
           } else {
-            remoteDn = localEntry.getName().toString();
+            remoteDn = localEntry.getName();
           }
           /* We have to recreate the url including the target DN we are using */
           url = new LDAPURL(url.getScheme(), url.getHost(), url.getPort(),
-              remoteDn, url.getAttributes(), url.getScope(), url.getRawFilter(),
+              remoteDn.toString(), url.getAttributes(), url.getScope(), url.getRawFilter(),
                  url.getExtensions());
         }
         if (useCustomFilter() && url.getScope() == SearchScope.BASE_OBJECT)
@@ -489,11 +485,12 @@
           searchForCustomFilter(remoteDn, conn);
         }
 
-        String filter = getFilter(url);
+        Filter filter = getFilter(url);
 
-        SearchRequest request = newSearchRequest(remoteDn, url.getScope(), filter, controller.getAttrsForBlackSearch())
-            .setSizeLimit(controller.getMaxChildren());
-        try (ConnectionEntryReader sr = conn.getConnection().search(request))
+        SearchRequest request =
+            newSearchRequest(remoteDn, url.getScope(), filter, controller.getAttrsForBlackSearch()).setSizeLimit(
+                controller.getMaxChildren());
+        try (ConnectionEntryReader sr = conn.search(request))
         {
           boolean found = false;
           while (sr.hasNext())
@@ -607,20 +604,19 @@
    */
   private void runDetectChildrenManually() throws SearchAbandonException {
     BasicNode parentNode = getNode();
-    ConnectionWrapper conn = null;
+    ConnectionWithControls conn = null;
 
     try {
       // We set the search constraints so that only one entry is returned.
       // It's enough to know if the entry has children or not.
-      // Send an LDAP search
       conn = controller.findConnectionForDisplayedEntry(parentNode);
       SearchRequest request = newSearchRequest(
-              controller.findBaseDNForChildEntries(parentNode),
-              useCustomFilter() ? WHOLE_SUBTREE : BASE_OBJECT,
-              controller.getChildSearchFilter(),
-              NO_ATTRIBUTES)
+          controller.findBaseDNForChildEntries(parentNode),
+          useCustomFilter() ? WHOLE_SUBTREE : BASE_OBJECT,
+          controller.getChildSearchFilter(),
+          NO_ATTRIBUTES)
           .setSizeLimit(1);
-      try (ConnectionEntryReader searchResults = conn.getConnection().search(request))
+      try (ConnectionEntryReader searchResults = conn.search(request))
       {
         throwAbandonIfNeeded(null);
         // Check if parentNode has children
@@ -676,32 +672,24 @@
    * @throws SearchAbandonException if an error occurs.
    */
   private void runSearchChildren() throws SearchAbandonException {
-    ConnectionWrapper conn = null;
+    ConnectionWithControls conn = null;
     BasicNode parentNode = getNode();
     parentNode.setSizeLimitReached(false);
 
     try {
       // Send an LDAP search
       conn = controller.findConnectionForDisplayedEntry(parentNode);
-      String parentDn = controller.findBaseDNForChildEntries(parentNode);
-      int parentComponents;
-      try
-      {
-        DN dn = DN.valueOf(parentDn);
-        parentComponents = dn.size();
-      }
-      catch (Throwable t)
-      {
-        throw new RuntimeException("Error decoding dn: "+parentDn+" . "+t,
-            t);
-      }
+      DN parentDn = controller.findBaseDNForChildEntries(parentNode);
+      int parentComponents = parentDn.size();
 
-      SearchScope scope = useCustomFilter() ? WHOLE_SUBTREE : SINGLE_LEVEL;
-      SearchRequest request =
-          newSearchRequest(parentDn, scope, controller.getChildSearchFilter(), controller.getAttrsForRedSearch())
-              .setSizeLimit(controller.getMaxChildren());
+      SearchRequest request = newSearchRequest(
+          parentDn,
+          useCustomFilter() ? WHOLE_SUBTREE : SINGLE_LEVEL,
+          controller.getChildSearchFilter(),
+          controller.getAttrsForRedSearch())
+          .setSizeLimit(controller.getMaxChildren());
 
-      try (ConnectionEntryReader entries = conn.getConnection().search(request))
+      try (ConnectionEntryReader entries = conn.search(request))
       {
         while (entries.hasNext())
         {
@@ -728,7 +716,7 @@
               boolean mustAddParent = mustAddParent(parentToAddDN) && mustAddParent2(parentToAddDN);
               if (mustAddParent)
               {
-                SearchResultEntry parentResult = searchManuallyEntry(conn, parentToAddDN.toString());
+                SearchResultEntry parentResult = searchManuallyEntry(conn, parentToAddDN);
                 childEntries.add(parentResult);
               }
             }
@@ -829,13 +817,13 @@
    * @param dn the DN of the entry to be searched.
    * @throws NamingException if an error occurs.
    */
-  private SearchResultEntry searchManuallyEntry(ConnectionWrapper conn, String dn) throws IOException
+  private SearchResultEntry searchManuallyEntry(ConnectionWithControls conn, DN dn) throws IOException
   {
     SearchRequest request =
         newSearchRequest(dn, BASE_OBJECT, controller.getObjectSearchFilter(), controller.getAttrsForRedSearch())
-        .setSizeLimit(controller.getMaxChildren());
+            .setSizeLimit(controller.getMaxChildren());
 
-    SearchResultEntry sr = conn.getConnection().searchSingleEntry(request);
+    SearchResultEntry sr = conn.searchSingleEntry(request);
     sr.setName(dn);
     return sr;
   }
@@ -921,14 +909,10 @@
    *          the LDAP URL.
    * @return the filter.
    */
-  private String getFilter(LDAPURL url)
+  private Filter getFilter(LDAPURL url)
   {
     String filter = url.getRawFilter();
-    if (filter == null)
-    {
-      filter = controller.getObjectSearchFilter();
-    }
-    return filter;
+    return filter != null ? Filter.valueOf(filter) : controller.getObjectSearchFilter();
   }
 
   /**
@@ -941,31 +925,26 @@
    * is actually an entry in the same server as the local entry but above in the
    * DIT).
    */
-  private void checkLoopInReferral(LDAPURL url,
-      String referral) throws SearchAbandonException
+  private void checkLoopInReferral(LDAPURL url, String referral) throws SearchAbandonException
   {
-    boolean checkSucceeded = true;
     try
     {
       if (url.getBaseDN().isSuperiorOrEqualTo(getNode().getDN()))
       {
-        HostPort urlHostPort = new HostPort(url.getHost(), url.getPort());
-        checkSucceeded = urlHostPort.equals(controller.getConfigurationConnection().getHostPort());
-        if (checkSucceeded)
+        HostPort hp = new HostPort(url.getHost(), url.getPort());
+        boolean checkSucceeded =
+            hp.equals(controller.getConfigurationConnection().getConnectionWrapper().getHostPort())
+            && hp.equals(controller.getUserDataConnection().getConnectionWrapper().getHostPort());
+        if (!checkSucceeded)
         {
-          checkSucceeded = urlHostPort.equals(controller.getUserDataConnection().getHostPort());
+          Exception cause = new ReferralLimitExceededException(ERR_CTRL_PANEL_REFERRAL_LOOP.get(url.getRawBaseDN()));
+          throw new SearchAbandonException(State.FAILED, cause, referral);
         }
       }
     }
-    catch (OpenDsException odse)
+    catch (OpenDsException ignore)
     {
       // Ignore
     }
-    if (!checkSucceeded)
-    {
-      throw new SearchAbandonException(
-          State.FAILED, new ReferralLimitExceededException(
-              ERR_CTRL_PANEL_REFERRAL_LOOP.get(url.getRawBaseDN())), referral);
-    }
   }
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/AddToGroupTask.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/AddToGroupTask.java
index 02bdb3a..b64e23e 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/AddToGroupTask.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/AddToGroupTask.java
@@ -37,7 +37,6 @@
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.opendj.ldap.DN;
-import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.Modification;
 import org.forgerock.opendj.ldap.requests.ModifyRequest;
 import org.forgerock.opendj.ldap.requests.SearchRequest;
@@ -207,7 +206,7 @@
   private void addModifications(DN groupDn, Set<DN> dns, ModifyRequest modRequest) throws IOException
   {
     // Search for the group entry
-    SearchRequest searchRequest = newSearchRequest(groupDn, BASE_OBJECT, Filter.valueOf(ALL_OBJECTS_FILTER),
+    SearchRequest searchRequest = newSearchRequest(groupDn, BASE_OBJECT, ALL_OBJECTS_FILTER,
         OBJECTCLASS_ATTRIBUTE_TYPE_NAME,
         ATTR_MEMBER,
         ATTR_UNIQUE_MEMBER);
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/DeleteEntryTask.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/DeleteEntryTask.java
index 04584e2..9100be8 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/DeleteEntryTask.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/DeleteEntryTask.java
@@ -47,6 +47,7 @@
 import org.forgerock.opendj.ldif.ConnectionEntryReader;
 import org.opends.admin.ads.util.ConnectionWrapper;
 import org.opends.guitools.controlpanel.browser.BrowserController;
+import org.opends.guitools.controlpanel.browser.ConnectionWithControls;
 import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
 import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor;
 import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
@@ -187,7 +188,7 @@
         DN dn = node.getDN();
         if (!isAlreadyDeleted(alreadyDeleted, dn))
         {
-          ConnectionWrapper conn = controller.findConnectionForDisplayedEntry(node);
+          ConnectionWithControls conn = controller.findConnectionForDisplayedEntry(node);
           useAdminCtx = controller.isConfigurationNode(node);
           if (node.hasSubOrdinates())
           {
@@ -279,7 +280,7 @@
     }
   }
 
-  private void deleteSubtreeRecursively(ConnectionWrapper conn, DN dnToRemove, TreePath path,
+  private void deleteSubtreeRecursively(ConnectionWithControls conn, DN dnToRemove, TreePath path,
       List<BrowserNodeInfo> toNotify) throws NamingException, IOException, DirectoryException
   {
     lastDn = dnToRemove;
@@ -313,7 +314,7 @@
 
     String filter = "(|(objectClass=*)(objectclass=ldapsubentry))";
     SearchRequest request = newSearchRequest(dnToRemove, SINGLE_LEVEL, Filter.valueOf(filter), NO_ATTRIBUTES);
-    try (ConnectionEntryReader entryDNs = conn.getConnection().search(request))
+    try (ConnectionEntryReader entryDNs = conn.search(request))
     {
       while (entryDNs.hasNext())
       {
@@ -331,7 +332,7 @@
 
     try
     {
-      conn.getConnection().delete(dnToRemove.toString());
+      conn.delete(newDeleteRequest(dnToRemove));
       if (path != null)
       {
         toNotify.add(controller.getNodeInfoFromPath(path));
@@ -372,8 +373,8 @@
     }
   }
 
-  private void deleteSubtreeWithControl(ConnectionWrapper conn, DN dn, TreePath path, List<BrowserNodeInfo> toNotify)
-      throws LdapException, NamingException
+  private void deleteSubtreeWithControl(ConnectionWithControls conn, DN dn, TreePath path,
+      List<BrowserNodeInfo> toNotify) throws LdapException, NamingException
   {
     lastDn = dn;
     long t = System.currentTimeMillis();
@@ -395,11 +396,12 @@
                     ColorAndFontConstants.defaultFont)));
       }
     });
-    //  Use a copy of the dir context since we are using an specific
+    // Use a copy of the connection since we are using a specific
     // control to delete the subtree and this can cause
     // synchronization problems when the tree is refreshed.
     ControlPanelInfo info = getInfo();
-    try (ConnectionWrapper conn1 = cloneConnectionWrapper(conn, info.getConnectTimeout(), info.getTrustManager(), null))
+    try (ConnectionWrapper conn1 =
+        cloneConnectionWrapper(conn.getConnectionWrapper(), info.getConnectTimeout(), info.getTrustManager(), null))
     {
       DeleteRequest request = newDeleteRequest(dn).addControl(SubtreeDeleteRequestControl.newControl(true));
       conn1.getConnection().delete(request);
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/ModifyEntryTask.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/ModifyEntryTask.java
index 1ee977b..5ca6fdf 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/ModifyEntryTask.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/ModifyEntryTask.java
@@ -43,8 +43,8 @@
 import org.forgerock.opendj.ldap.RDN;
 import org.forgerock.opendj.ldap.requests.ModifyRequest;
 import org.forgerock.opendj.ldap.schema.AttributeType;
-import org.opends.admin.ads.util.ConnectionWrapper;
 import org.opends.guitools.controlpanel.browser.BrowserController;
+import org.opends.guitools.controlpanel.browser.ConnectionWithControls;
 import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
 import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor;
 import org.opends.guitools.controlpanel.datamodel.CannotRenameException;
@@ -205,7 +205,7 @@
     try
     {
       BasicNode node = (BasicNode)treePath.getLastPathComponent();
-      ConnectionWrapper conn = controller.findConnectionForDisplayedEntry(node);
+      ConnectionWithControls conn = controller.findConnectionForDisplayedEntry(node);
       useAdminCtx = controller.isConfigurationNode(node);
       if (!mustRename)
       {
@@ -224,7 +224,7 @@
             }
           });
 
-          conn.getConnection().modify(newModifyRequest0(oldEntry.getName(), modifications));
+          conn.modify(newModifyRequest0(oldEntry.getName(), modifications));
 
           SwingUtilities.invokeLater(new Runnable()
           {
@@ -295,7 +295,7 @@
    * @throws CannotRenameException if we cannot perform the modification.
    * @throws LdapException if an error performing the modification occurs.
    */
-  private void modifyAndRename(ConnectionWrapper conn, final DN oldDN,
+  private void modifyAndRename(ConnectionWithControls conn, final DN oldDN,
       org.forgerock.opendj.ldap.Entry originalEntry,
       final Entry newEntry, final List<Modification> originalMods)
       throws CannotRenameException, LdapException
@@ -325,7 +325,7 @@
       }
     });
 
-    conn.getConnection().modifyDN(newModifyDNRequest(oldDn, newRDN));
+    conn.modifyDN(newModifyDNRequest(oldDn, newRDN));
 
     final TreePath[] newPath = {null};
 
@@ -361,7 +361,7 @@
         }
       });
 
-      conn.getConnection().modify(newModifyRequest0(newEntry.getName(), originalMods));
+      conn.modify(newModifyRequest0(newEntry.getName(), originalMods));
 
       SwingUtilities.invokeLater(new Runnable()
       {
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/NewEntryTask.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/NewEntryTask.java
index 8279219..ab32bea 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/NewEntryTask.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/NewEntryTask.java
@@ -16,6 +16,7 @@
  */
 package org.opends.guitools.controlpanel.task;
 
+import static org.forgerock.opendj.ldap.requests.Requests.*;
 import static org.opends.messages.AdminToolMessages.*;
 
 import java.util.ArrayList;
@@ -32,6 +33,7 @@
 import org.forgerock.opendj.ldap.DN;
 import org.opends.admin.ads.util.ConnectionWrapper;
 import org.opends.guitools.controlpanel.browser.BrowserController;
+import org.opends.guitools.controlpanel.browser.ConnectionWithControls;
 import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
 import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor;
 import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
@@ -152,33 +154,22 @@
 
     try
     {
-      ConnectionWrapper conn;
-
       if (parentNode != null)
       {
-        conn = controller.findConnectionForDisplayedEntry(parentNode);
+        ConnectionWithControls conn = controller.findConnectionForDisplayedEntry(parentNode);
         useAdminCtx = controller.isConfigurationNode(parentNode);
+        printProgressCreatingEntry();
+        conn.add(newAddRequest(Converters.from(newEntry)));
       }
       else
       {
-        conn = getInfo().getConnection();
+        ConnectionWrapper conn = getInfo().getConnection();
         useAdminCtx = true;
+        printProgressCreatingEntry();
+        conn.getConnection().add(Converters.from(newEntry));
       }
 
-      SwingUtilities.invokeLater(new Runnable()
-      {
-        @Override
-        public void run()
-        {
-          printEquivalentCommand();
-          getProgressDialog().appendProgressHtml(
-              Utilities.getProgressWithPoints(
-                  INFO_CTRL_PANEL_CREATING_ENTRY.get(dn),
-                  ColorAndFontConstants.progressFont));
-        }
-      });
 
-      conn.getConnection().add(Converters.from(newEntry));
 
       SwingUtilities.invokeLater(new Runnable()
       {
@@ -227,6 +218,22 @@
     }
   }
 
+  private void printProgressCreatingEntry()
+  {
+    SwingUtilities.invokeLater(new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        printEquivalentCommand();
+        getProgressDialog().appendProgressHtml(
+            Utilities.getProgressWithPoints(
+                INFO_CTRL_PANEL_CREATING_ENTRY.get(dn),
+                ColorAndFontConstants.progressFont));
+      }
+    });
+  }
+
   /** Prints the equivalent command-line in the progress dialog. */
   private void printEquivalentCommand()
   {
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/ResetUserPasswordTask.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/ResetUserPasswordTask.java
index 1c39d62..40bcc04 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/ResetUserPasswordTask.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/ResetUserPasswordTask.java
@@ -38,6 +38,7 @@
 import org.forgerock.opendj.ldif.ConnectionEntryReader;
 import org.opends.admin.ads.util.ConnectionWrapper;
 import org.opends.guitools.controlpanel.browser.BrowserController;
+import org.opends.guitools.controlpanel.browser.ConnectionWithControls;
 import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
 import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor;
 import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
@@ -86,10 +87,10 @@
 
     try
     {
-      ConnectionWrapper conn = controller.findConnectionForDisplayedEntry(node);
+      ConnectionWithControls conn = controller.findConnectionForDisplayedEntry(node);
       if (conn != null && isBoundAs(dn, conn))
       {
-        currentPassword = conn.getBindPassword().toCharArray();
+        currentPassword = conn.getConnectionWrapper().getBindPassword().toCharArray();
       }
     }
     catch (Throwable t)
@@ -225,16 +226,16 @@
    * @param conn the connection that we are using to modify the password.
    * @return {@code true} if we are bound using the provided entry.
    */
-  private boolean isBoundAs(DN dn, ConnectionWrapper conn)
+  private boolean isBoundAs(DN dn, ConnectionWithControls conn)
   {
-    final DN bindDN = conn.getBindDn();
+    final DN bindDN = conn.getConnectionWrapper().getBindDn();
     boolean isBoundAs = dn.equals(bindDN);
     if (!isBoundAs)
     {
       String attrName = ATTR_ROOTDN_ALTERNATE_BIND_DN;
       Filter filter = Filter.valueOf("(|(objectClass=*)(objectclass=ldapsubentry))");
       SearchRequest request = newSearchRequest(dn, BASE_OBJECT, filter, attrName);
-      try (ConnectionEntryReader entries = conn.getConnection().search(request))
+      try (ConnectionEntryReader entries = conn.search(request))
       {
         while (entries.hasNext())
         {
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java
index 43fb5ce..e859501 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java
@@ -18,6 +18,7 @@
 
 import static com.forgerock.opendj.cli.Utils.*;
 
+import static org.opends.guitools.controlpanel.browser.BrowserController.*;
 import static org.opends.messages.AdminToolMessages.*;
 import static org.opends.messages.QuickSetupMessages.*;
 
@@ -69,13 +70,14 @@
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.LocalizableMessageBuilder;
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
-import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.DN;
-import org.forgerock.opendj.ldap.schema.AttributeType;
+import org.forgerock.opendj.ldap.Filter;
 import org.opends.admin.ads.util.ApplicationTrustManager;
 import org.opends.admin.ads.util.ConnectionWrapper;
 import org.opends.guitools.controlpanel.browser.BrowserController;
+import org.opends.guitools.controlpanel.browser.ConnectionWithControls;
 import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
 import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor;
 import org.opends.guitools.controlpanel.datamodel.CategorizedComboBoxElement;
@@ -96,10 +98,6 @@
 import org.opends.quicksetup.UserDataCertificateException;
 import org.opends.quicksetup.ui.CertificateDialog;
 import org.opends.quicksetup.util.UIKeyStore;
-import org.opends.server.protocols.ldap.LDAPFilter;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.LDAPException;
-import org.opends.server.types.SearchFilter;
 import org.opends.server.util.ServerConstants;
 
 /**
@@ -614,14 +612,14 @@
     {
       errors.add(INFO_CTRL_PANEL_NO_BASE_DN_SELECTED.get());
     }
-    String filterValue = getFilter();
+    Filter filterValue = null;
     try
     {
-      LDAPFilter.decode(filterValue);
+      filterValue = getFilter();
     }
-    catch (LDAPException le)
+    catch (LocalizedIllegalArgumentException e)
     {
-      errors.add(INFO_CTRL_PANEL_INVALID_FILTER_DETAILS.get(le.getMessageObject()));
+      errors.add(INFO_CTRL_PANEL_INVALID_FILTER_DETAILS.get(e.getMessageObject()));
       setPrimaryInvalid(lFilter);
     }
     if (errors.isEmpty())
@@ -672,7 +670,7 @@
           else
           {
             BasicNode rootNode = (BasicNode) controller.getTree().getModel().getRoot();
-            if (controller.findChildNode(rootNode, theDN) == -1)
+            if (findChildNode(rootNode, theDN) == -1)
             {
               controller.addNodeUnderRoot(theDN);
             }
@@ -710,7 +708,7 @@
    *
    * @return the LDAP filter built based in the parameters provided by the user.
    */
-  private String getFilter()
+  private Filter getFilter()
   {
     String filterText = filter.getText();
     if (filterText.length() == 0)
@@ -727,39 +725,41 @@
         return BrowserController.ALL_OBJECTS_FILTER;
       }
 
-      return filterText;
+      return Filter.valueOf(filterText);
     }
     else if (USER_FILTER.equals(attr))
     {
       if ("*".equals(filterText))
       {
-        return "(objectClass=person)";
+        return Filter.valueOf("(objectClass=person)");
       }
 
-      return "(&(objectClass=person)(|" + "(cn=" + filterText + ")(sn=" + filterText + ")(uid=" + filterText + ")))";
+      return Filter.valueOf(
+          "(&(objectClass=person)"
+              + "(|(cn=" + filterText + ")"
+                  + "(sn=" + filterText + ")"
+                  + "(uid=" + filterText + ")))");
     }
     else if (GROUP_FILTER.equals(attr))
     {
       if ("*".equals(filterText))
       {
-        return "(|(objectClass=groupOfUniqueNames)(objectClass=groupOfURLs))";
+        return Filter.valueOf("(|(objectClass=groupOfUniqueNames)(objectClass=groupOfURLs))");
       }
 
-      return "(&(|(objectClass=groupOfUniqueNames)(objectClass=groupOfURLs))" + "(cn=" + filterText + "))";
+      return Filter.valueOf(
+          "(&(|(objectClass=groupOfUniqueNames)(objectClass=groupOfURLs))" + "(cn=" + filterText + "))");
     }
     else if (attr != null)
     {
       try
       {
-        return new LDAPFilter(SearchFilter.createFilterFromString("(" + attr + "=" + filterText + ")")).toString();
+        return Filter.valueOf("(" + attr + "=" + filterText + ")");
       }
-      catch (DirectoryException de)
+      catch (LocalizedIllegalArgumentException ignored)
       {
         // Try this alternative:
-        AttributeType attrType =
-            getInfo().getServerDescriptor().getSchema().getAttributeType(attr.toString().toLowerCase());
-        ByteString filterBytes = ByteString.valueOfUtf8(filterText);
-        return new LDAPFilter(SearchFilter.createEqualityFilter(attrType, filterBytes)).toString();
+        return Filter.equality(attr.toString(), filterText);
       }
     }
     else
@@ -835,7 +835,7 @@
                 }
                 else
                 {
-                  int index = controller.findChildNode(rootNode, baseDN);
+                  int index = findChildNode(rootNode, baseDN);
                   if (index >= 0)
                   {
                     TreeNode node = rootNode.getChildAt(index);
@@ -857,7 +857,7 @@
             }
           }
         }
-        if (isSubordinate && controller.findChildNode(rootNode, theDN) == -1)
+        if (isSubordinate && findChildNode(rootNode, theDN) == -1)
         {
           controller.addNodeUnderRoot(theDN);
         }
@@ -1189,8 +1189,8 @@
         try
         {
           ConnectionWrapper conn = getInfo().getConnection();
-          ConnectionWrapper conn1 = controller.getConfigurationConnection();
-          boolean setConnection = conn != conn1;
+          ConnectionWithControls conn1 = controller.getConfigurationConnection();
+          boolean setConnection = conn1 == null || conn1.getConnectionWrapper() != conn;
           updateNumSubordinateHacker(desc);
           if (setConnection)
           {
@@ -1199,23 +1199,15 @@
               ConnectionWrapper connUserData = createUserDataDirContext(conn.getBindDn(), conn.getBindPassword());
               getInfo().setUserDataDirContext(connUserData);
             }
-            final NamingException[] fNe = { null };
             Runnable runnable = new Runnable()
             {
               @Override
               public void run()
               {
-                try
-                {
-                  ControlPanelInfo info = getInfo();
-                  controller.setConnections(
-                      info.getServerDescriptor(), info.getConnection(), info.getUserDataDirContext());
-                  applyButtonClicked();
-                }
-                catch (NamingException ne)
-                {
-                  fNe[0] = ne;
-                }
+                ControlPanelInfo info = getInfo();
+                controller.setConnections(
+                    info.getServerDescriptor(), info.getConnection(), info.getUserDataDirContext());
+                applyButtonClicked();
               }
             };
             if (!SwingUtilities.isEventDispatchThread())
@@ -1230,11 +1222,6 @@
             {
               runnable.run();
             }
-
-            if (fNe[0] != null)
-            {
-              throw fNe[0];
-            }
           }
           displayNodes = true;
         }
@@ -1341,7 +1328,7 @@
               if (!added && !displayAll)
               {
                 BasicNode rootNode = (BasicNode) controller.getTree().getModel().getRoot();
-                if (controller.findChildNode(rootNode, theDN) == -1)
+                if (findChildNode(rootNode, theDN) == -1)
                 {
                   controller.addNodeUnderRoot(theDN);
                 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractNewEntryPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractNewEntryPanel.java
index c375bbb..cd1cce4 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractNewEntryPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractNewEntryPanel.java
@@ -25,6 +25,7 @@
 import javax.swing.SwingUtilities;
 
 import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.opendj.ldap.DN;
 import org.opends.guitools.controlpanel.browser.BrowserController;
 import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
 import org.opends.guitools.controlpanel.task.NewEntryTask;
@@ -156,7 +157,7 @@
         // Unexpected error: getEntry() should work after calling checkSyntax
         throw new RuntimeException("Unexpected error: "+t, t);
       }
-      String dn = entry.getName().toString();
+      DN dn = entry.getName();
       // Checking for the existence of an entry is fast enough so we can do
       // it on the event thread.
       if (entryExists(dn))
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AddToGroupPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AddToGroupPanel.java
index 32ec3cf..2a56ddb 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AddToGroupPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AddToGroupPanel.java
@@ -43,6 +43,9 @@
 import javax.swing.JTextArea;
 import javax.swing.SwingUtilities;
 
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
+import org.forgerock.opendj.ldap.DN;
 import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
 import org.opends.guitools.controlpanel.task.AddToGroupTask;
 import org.opends.guitools.controlpanel.task.Task;
@@ -50,9 +53,6 @@
 import org.opends.guitools.controlpanel.ui.nodes.DndBrowserNodes;
 import org.opends.guitools.controlpanel.util.BackgroundTask;
 import org.opends.guitools.controlpanel.util.Utilities;
-import org.forgerock.i18n.LocalizableMessage;
-import org.forgerock.i18n.LocalizedIllegalArgumentException;
-import org.forgerock.opendj.ldap.DN;
 import org.opends.server.util.ServerConstants;
 
 /** The dialog that is displayed when we want to add entries to a set of groups. */
@@ -327,24 +327,23 @@
 
     String[] grs = groups.getText().split("\n");
     boolean oneGroupDefined = false;
-    for (String groupDn : grs)
+    for (String groupDnStr : grs)
     {
-      groupDn = groupDn.trim();
-      if (groupDn.length() > 0)
+      groupDnStr = groupDnStr.trim();
+      if (groupDnStr.length() > 0)
       {
         try
         {
-          DN.valueOf(groupDn);
-          if (!entryExists(groupDn))
+          DN groupDN = DN.valueOf(groupDnStr);
+          if (!entryExists(groupDN))
           {
-            errors.add(
-                ERR_CTRL_PANEL_GROUP_COULD_NOT_BE_FOUND.get(groupDn));
+            errors.add(ERR_CTRL_PANEL_GROUP_COULD_NOT_BE_FOUND.get(groupDnStr));
           }
-          else if (!hasObjectClass(groupDn, ServerConstants.OC_GROUP_OF_NAMES,
+          else if (!hasObjectClass(groupDN, ServerConstants.OC_GROUP_OF_NAMES,
             ServerConstants.OC_GROUP_OF_ENTRIES,
             ServerConstants.OC_GROUP_OF_UNIQUE_NAMES))
           {
-            errors.add(ERR_CTRL_PANEL_NOT_A_STATIC_GROUP.get(groupDn));
+            errors.add(ERR_CTRL_PANEL_NOT_A_STATIC_GROUP.get(groupDnStr));
           }
           else
           {
@@ -353,7 +352,7 @@
         }
         catch (LocalizedIllegalArgumentException e)
         {
-          errors.add(INFO_CTRL_PANEL_INVALID_DN_DETAILS.get(groupDn, e.getMessageObject()));
+          errors.add(INFO_CTRL_PANEL_INVALID_DN_DETAILS.get(groupDnStr, e.getMessageObject()));
         }
       }
     }
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
index bfded4b..12ba993 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
@@ -43,7 +43,6 @@
 import java.util.LinkedHashSet;
 
 import javax.naming.InterruptedNamingException;
-import javax.naming.NamingException;
 import javax.swing.ButtonGroup;
 import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JComponent;
@@ -66,7 +65,7 @@
 import org.forgerock.opendj.ldap.Entry;
 import org.forgerock.opendj.ldap.schema.AttributeType;
 import org.forgerock.opendj.ldap.schema.ObjectClass;
-import org.opends.admin.ads.util.ConnectionWrapper;
+import org.opends.guitools.controlpanel.browser.ConnectionWithControls;
 import org.opends.guitools.controlpanel.browser.NodeRefresher;
 import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
 import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
@@ -503,7 +502,7 @@
     if (node != null)
     {
       DN dn;
-      if (controller.getFollowReferrals() &&
+      if (controller.isFollowReferrals() &&
           node.getReferral() != null &&
           node.getRemoteUrl() == null &&
           node.getError() != null &&
@@ -514,7 +513,7 @@
         entryPane.referralSolveError(node.getDN(), node.getReferral(), node.getError());
         dn = null;
       }
-      else if (controller.getFollowReferrals() && node.getRemoteUrl() != null)
+      else if (controller.isFollowReferrals() && node.getRemoteUrl() != null)
       {
         dn = DN.valueOf(node.getRemoteUrl().getRawBaseDN());
       }
@@ -527,11 +526,10 @@
       {
         try
         {
-          ConnectionWrapper conn = controller.findConnectionForDisplayedEntry(node);
+          ConnectionWithControls conn = controller.findConnectionForDisplayedEntry(node);
           LDAPEntryReader reader = new LDAPEntryReader(dn, conn);
           reader.addEntryReadListener(entryPane);
-          // Required to update the browser controller properly if the entry is
-          // deleted.
+          // Required to update the browser controller properly if the entry is deleted.
           entryPane.setTreePath(path);
           stopCurrentReader();
           startReader(reader);
@@ -1246,23 +1244,13 @@
       menu.add(sortUserData);
       menu.add(followReferrals);
       sortUserData.setSelected(entryPane.getController().isSorted());
-      followReferrals.setSelected(
-          entryPane.getController().getFollowReferrals());
+      followReferrals.setSelected(entryPane.getController().isFollowReferrals());
       sortUserData.addActionListener(new ActionListener()
       {
         @Override
         public void actionPerformed(ActionEvent ev)
         {
-          try
-          {
-            entryPane.getController().setSorted(sortUserData.isSelected());
-          }
-          catch (NamingException ne)
-          {
-            // Bug
-            System.err.println("Unexpected error updating sorting.");
-            ne.printStackTrace();
-          }
+          entryPane.getController().setSorted(sortUserData.isSelected());
         }
       });
       followReferrals.addActionListener(new ActionListener()
@@ -1270,17 +1258,7 @@
         @Override
         public void actionPerformed(ActionEvent ev)
         {
-          try
-          {
-            entryPane.getController().setFollowReferrals(
-                followReferrals.isSelected());
-          }
-          catch (NamingException ne)
-          {
-            // Bug
-            System.err.println("Unexpected error updating referral state.");
-            ne.printStackTrace();
-          }
+          entryPane.getController().setFollowReferrals(followReferrals.isSelected());
         }
       });
       // Add the refresh menu
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/DuplicateEntryPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/DuplicateEntryPanel.java
index ef93c8c..a48c9f2 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/DuplicateEntryPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/DuplicateEntryPanel.java
@@ -44,8 +44,8 @@
 import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.DN;
 import org.forgerock.opendj.ldap.Entry;
-import org.opends.admin.ads.util.ConnectionWrapper;
 import org.opends.guitools.controlpanel.browser.BrowserController;
+import org.opends.guitools.controlpanel.browser.ConnectionWithControls;
 import org.opends.guitools.controlpanel.ui.nodes.BasicNode;
 import org.opends.guitools.controlpanel.util.BackgroundTask;
 import org.opends.guitools.controlpanel.util.LDAPEntryReader;
@@ -307,7 +307,7 @@
       errors.add(ERR_CTRL_PANEL_DUPLICATE_ENTRY_PARENT_DN_NOT_VALID.get());
       setPrimaryInvalid(lParentDN);
     }
-    else if (!entryExists(parentDN))
+    else if (!entryExists(DN.valueOf(parentDN)))
     {
       errors.add(ERR_CTRL_PANEL_DUPLICATE_ENTRY_PARENT_DOES_NOT_EXIST.get());
       setPrimaryInvalid(lParentDN);
@@ -447,7 +447,7 @@
       @Override
       public Entry processBackgroundTask() throws Throwable
       {
-        ConnectionWrapper conn = controller.findConnectionForDisplayedEntry(node);
+        ConnectionWithControls conn = controller.findConnectionForDisplayedEntry(node);
         LDAPEntryReader reader = new LDAPEntryReader(node.getDN(), conn);
         sleepIfRequired(700, t1);
         return reader.processBackgroundTask();
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewGroupPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewGroupPanel.java
index 3bd5aa2..0f4fd49 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewGroupPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewGroupPanel.java
@@ -190,8 +190,7 @@
         {
           try
           {
-            DN.valueOf(member);
-            if (!entryExists(member))
+            if (!entryExists(DN.valueOf(member)))
             {
               errorFound = true;
               errors.add(ERR_CTRL_PANEL_MEMBER_NOT_FOUND.get(member));
@@ -258,13 +257,13 @@
       String ref = referenceGroup.getText().trim();
       try
       {
-        DN.valueOf(ref);
-        if (!entryExists(ref))
+        DN refDN = DN.valueOf(ref);
+        if (!entryExists(refDN))
         {
           errorFound = true;
           errors.add(ERR_CTRL_PANEL_REFERENCE_GROUP_NOT_FOUND.get());
         }
-        else if (!hasObjectClass(ref, ServerConstants.OC_GROUP_OF_URLS))
+        else if (!hasObjectClass(refDN, ServerConstants.OC_GROUP_OF_URLS))
         {
           errorFound = true;
           errors.add(ERR_CTRL_PANEL_REFERENCE_GROUP_NOT_DYNAMIC.get());
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
index a9359a0..585376b 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
@@ -71,6 +71,7 @@
 import org.forgerock.i18n.LocalizableMessageBuilder;
 import org.forgerock.i18n.LocalizableMessageDescriptor;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
+import org.forgerock.opendj.ldap.DN;
 import org.forgerock.opendj.ldap.LdapException;
 import org.forgerock.opendj.ldap.requests.SearchRequest;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
@@ -1999,15 +2000,13 @@
   }
 
   /**
-   * Tells whether an entry exists or not. Actually it tells if we could find a
-   * given entry or not.
+   * Tells whether an entry exists or not. Actually it tells if we could find a given entry or not.
    *
    * @param dn
    *          the DN of the entry to look for.
-   * @return <CODE>true</CODE> if the entry with the provided DN could be found
-   *         and <CODE>false</CODE> otherwise.
+   * @return {@code true} if the entry with the provided DN could be found, {@code false} otherwise.
    */
-  protected boolean entryExists(final String dn)
+  protected boolean entryExists(final DN dn)
   {
     try
     {
@@ -2021,17 +2020,16 @@
   }
 
   /**
-   * Tells whether a given entry exists and contains one of the specified object
-   * classes.
+   * Tells whether a given entry exists and contains one of the specified object classes.
    *
    * @param dn
    *          the DN of the entry.
    * @param objectClasses
    *          the object classes to check.
-   * @return <CODE>true</CODE> if the entry exists and contains one of the
-   *         specified object classes and <CODE>false</CODE> otherwise.
+   * @return {@code true} if the entry exists and contains one of the specified object classes,
+   *         {@code false} otherwise.
    */
-  protected boolean hasObjectClass(final String dn, final String... objectClasses)
+  protected boolean hasObjectClass(final DN dn, final String... objectClasses)
   {
     SearchRequest request = newSearchRequest(dn, BASE_OBJECT, ALL_OBJECTS_FILTER, OBJECTCLASS_ATTRIBUTE_TYPE_NAME);
     try (ConnectionEntryReader entryReader = getInfo().getConnection().getConnection().search(request))
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/LDAPEntryReader.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/LDAPEntryReader.java
index 999b805..6517c39 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/LDAPEntryReader.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/LDAPEntryReader.java
@@ -28,7 +28,7 @@
 import org.forgerock.opendj.ldap.requests.Requests;
 import org.forgerock.opendj.ldap.requests.SearchRequest;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
-import org.opends.admin.ads.util.ConnectionWrapper;
+import org.opends.guitools.controlpanel.browser.ConnectionWithControls;
 import org.opends.guitools.controlpanel.event.EntryReadErrorEvent;
 import org.opends.guitools.controlpanel.event.EntryReadEvent;
 import org.opends.guitools.controlpanel.event.EntryReadListener;
@@ -41,7 +41,7 @@
 public class LDAPEntryReader extends BackgroundTask<Entry>
 {
   private final DN dn;
-  private final ConnectionWrapper conn;
+  private final ConnectionWithControls conn;
   private final Set<EntryReadListener> listeners = new HashSet<>();
   private boolean isOver;
   private boolean notifyListeners;
@@ -51,7 +51,7 @@
    * @param dn the DN of the entry.
    * @param conn the connection to the server.
    */
-  public LDAPEntryReader(DN dn, ConnectionWrapper conn)
+  public LDAPEntryReader(DN dn, ConnectionWithControls conn)
   {
     this.dn = dn;
     this.conn = conn;
@@ -64,7 +64,7 @@
     isOver = false;
     final Filter filter = Filter.valueOf("(|(objectclass=*)(objectclass=ldapsubentry))");
     SearchRequest request = Requests.newSearchRequest(dn, BASE_OBJECT, filter, "*", "+");
-    SearchResultEntry sr = conn.getConnection().searchSingleEntry(request);
+    SearchResultEntry sr = conn.searchSingleEntry(request);
     if (isInterrupted())
     {
       isOver = true;

--
Gitblit v1.10.0