From cab0b20204866c68b0cce38b4492f707187cc128 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Mon, 15 Jul 2013 08:17:58 +0000
Subject: [PATCH] Refactoring on the LocalBackend*Operation classes: - Extracted process*() methods from the processLocal*() methods for the LocalBackend*Operation classes. - Transformed plain comments into javadocs. - Used interfaces instead of concrete classes. - Made all protected members be private.

---
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java   |  372 ++++++------
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java |  841 +++++++++++++----------------
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java  |  447 +++++++--------
 3 files changed, 775 insertions(+), 885 deletions(-)

diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
index f322a76..48a1fbf 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
@@ -68,22 +68,22 @@
   /**
    * The backend in which the comparison is to be performed.
    */
-  protected Backend backend;
+  private Backend backend;
 
   /**
    * The client connection for this operation.
    */
-  protected ClientConnection clientConnection;
+  private ClientConnection clientConnection;
 
   /**
    * The DN of the entry to compare.
    */
-  protected DN entryDN;
+  private DN entryDN;
 
   /**
    * The entry to be compared.
    */
-  protected Entry entry = null;
+  private Entry entry;
 
 
 
@@ -125,242 +125,26 @@
   public void processLocalCompare(LocalBackendWorkflowElement wfe)
       throws CanceledOperationException
   {
-    boolean executePostOpPlugins = false;
-
     this.backend = wfe.getBackend();
 
     clientConnection  = getClientConnection();
 
-    // Get the plugin config manager that will be used for invoking plugins.
-    PluginConfigManager pluginConfigManager =
-         DirectoryServer.getPluginConfigManager();
-
-
-    // Get a reference to the client connection
-    ClientConnection clientConnection = getClientConnection();
-
-
     // Check for a request to cancel this operation.
     checkIfCanceled(false);
 
 
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-compareProcessing:
-    {
-      // Process the entry DN to convert it from the raw form to the form
-      // required for the rest of the compare processing.
-      entryDN = getEntryDN();
-      if (entryDN == null)
-      {
-        break compareProcessing;
-      }
-
-
-      // If the target entry is in the server configuration, then make sure the
-      // requester has the CONFIG_READ privilege.
-      if (DirectoryServer.getConfigHandler().handlesEntry(entryDN) &&
-          (! clientConnection.hasPrivilege(Privilege.CONFIG_READ, this)))
-      {
-        appendErrorMessage(ERR_COMPARE_CONFIG_INSUFFICIENT_PRIVILEGES.get());
-        setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-        break compareProcessing;
-      }
-
-
-      // Check for a request to cancel this operation.
-      checkIfCanceled(false);
-
-
-      // Grab a read lock on the entry.
-      final Lock readLock = LockManager.lockRead(entryDN);
-      if (readLock == null)
-      {
-        setResultCode(ResultCode.BUSY);
-        appendErrorMessage(ERR_COMPARE_CANNOT_LOCK_ENTRY.get(
-                                String.valueOf(entryDN)));
-        break compareProcessing;
-      }
-
-      try
-      {
-        // Get the entry.  If it does not exist, then fail.
-        try
-        {
-          entry = DirectoryServer.getEntry(entryDN);
-
-          if (entry == null)
-          {
-            setResultCode(ResultCode.NO_SUCH_OBJECT);
-            appendErrorMessage(
-                    ERR_COMPARE_NO_SUCH_ENTRY.get(String.valueOf(entryDN)));
-
-            // See if one of the entry's ancestors exists.
-            DN parentDN = entryDN.getParentDNInSuffix();
-            while (parentDN != null)
-            {
-              try
-              {
-                if (DirectoryServer.entryExists(parentDN))
-                {
-                  setMatchedDN(parentDN);
-                  break;
-                }
-              }
-              catch (Exception e)
-              {
-                if (debugEnabled())
-                {
-                  TRACER.debugCaught(DebugLogLevel.ERROR, e);
-                }
-                break;
-              }
-
-              parentDN = parentDN.getParentDNInSuffix();
-            }
-
-            break compareProcessing;
-          }
-        }
-        catch (DirectoryException de)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, de);
-          }
-
-          setResultCode(de.getResultCode());
-          appendErrorMessage(de.getMessageObject());
-          break compareProcessing;
-        }
-
-        // Check to see if there are any controls in the request.  If so, then
-        // see if there is any special processing required.
-        try
-        {
-          handleRequestControls();
-        }
-        catch (DirectoryException de)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, de);
-          }
-
-          setResponseData(de);
-          break compareProcessing;
-        }
-
-
-        // Check to see if the client has permission to perform the
-        // compare.
-
-        // FIXME: for now assume that this will check all permission
-        // pertinent to the operation. This includes proxy authorization
-        // and any other controls specified.
-
-        // FIXME: earlier checks to see if the entry already exists may
-        // have already exposed sensitive information to the client.
-        try
-        {
-          if (!AccessControlConfigManager.getInstance()
-              .getAccessControlHandler().isAllowed(this))
-          {
-            setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-            appendErrorMessage(ERR_COMPARE_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS
-                .get(String.valueOf(entryDN)));
-            break compareProcessing;
-          }
-        }
-        catch (DirectoryException e)
-        {
-          setResultCode(e.getResultCode());
-          appendErrorMessage(e.getMessageObject());
-          break compareProcessing;
-        }
-
-        // Check for a request to cancel this operation.
-        checkIfCanceled(false);
-
-
-        // Invoke the pre-operation compare plugins.
-        executePostOpPlugins = true;
-        PluginResult.PreOperation preOpResult =
-             pluginConfigManager.invokePreOperationComparePlugins(this);
-          if (!preOpResult.continueProcessing())
-          {
-            setResultCode(preOpResult.getResultCode());
-            appendErrorMessage(preOpResult.getErrorMessage());
-            setMatchedDN(preOpResult.getMatchedDN());
-            setReferralURLs(preOpResult.getReferralURLs());
-            break compareProcessing;
-          }
-
-
-        // Get the base attribute type and set of options.
-        Set<String> options = getAttributeOptions();
-
-        // Actually perform the compare operation.
-        AttributeType attrType = getAttributeType();
-
-        List<Attribute> attrList = entry.getAttribute(attrType, options);
-        if ((attrList == null) || attrList.isEmpty())
-        {
-          setResultCode(ResultCode.NO_SUCH_ATTRIBUTE);
-          if (options == null)
-          {
-            appendErrorMessage(WARN_COMPARE_OP_NO_SUCH_ATTR.get(
-                                    String.valueOf(entryDN),
-                                    getRawAttributeType()));
-          }
-          else
-          {
-            appendErrorMessage(WARN_COMPARE_OP_NO_SUCH_ATTR_WITH_OPTIONS.get(
-                                    String.valueOf(entryDN),
-                                    getRawAttributeType()));
-          }
-        }
-        else
-        {
-          AttributeValue value = AttributeValues.create(attrType,
-                                                    getAssertionValue());
-
-          boolean matchFound = false;
-          for (Attribute a : attrList)
-          {
-            if (a.contains(value))
-            {
-              matchFound = true;
-              break;
-            }
-          }
-
-          if (matchFound)
-          {
-            setResultCode(ResultCode.COMPARE_TRUE);
-          }
-          else
-          {
-            setResultCode(ResultCode.COMPARE_FALSE);
-          }
-        }
-      }
-      finally
-      {
-        LockManager.unlock(entryDN, readLock);
-      }
-    }
-
+    BooleanHolder executePostOpPlugins = new BooleanHolder();
+    processCompare(executePostOpPlugins);
 
     // Check for a request to cancel this operation.
     checkIfCanceled(false);
 
-
     // Invoke the post-operation compare plugins.
-    if (executePostOpPlugins)
+    if (executePostOpPlugins.value)
     {
       PluginResult.PostOperation postOpResult =
-           pluginConfigManager.invokePostOperationComparePlugins(this);
+          DirectoryServer.getPluginConfigManager()
+              .invokePostOperationComparePlugins(this);
       if (!postOpResult.continueProcessing())
       {
         setResultCode(postOpResult.getResultCode());
@@ -371,23 +155,223 @@
     }
   }
 
+  private void processCompare(BooleanHolder executePostOpPlugins)
+      throws CanceledOperationException
+  {
+    // Process the entry DN to convert it from the raw form to the form
+    // required for the rest of the compare processing.
+    entryDN = getEntryDN();
+    if (entryDN == null)
+    {
+      return;
+    }
 
 
+    // If the target entry is in the server configuration, then make sure the
+    // requester has the CONFIG_READ privilege.
+    if (DirectoryServer.getConfigHandler().handlesEntry(entryDN)
+        && (!clientConnection.hasPrivilege(Privilege.CONFIG_READ, this)))
+    {
+      appendErrorMessage(ERR_COMPARE_CONFIG_INSUFFICIENT_PRIVILEGES.get());
+      setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+      return;
+    }
+
+    // Check for a request to cancel this operation.
+    checkIfCanceled(false);
+
+
+    // Grab a read lock on the entry.
+    final Lock readLock = LockManager.lockRead(entryDN);
+    if (readLock == null)
+    {
+      setResultCode(ResultCode.BUSY);
+      appendErrorMessage(ERR_COMPARE_CANNOT_LOCK_ENTRY.get(String
+          .valueOf(entryDN)));
+      return;
+    }
+
+    try
+    {
+      // Get the entry. If it does not exist, then fail.
+      try
+      {
+        entry = DirectoryServer.getEntry(entryDN);
+
+        if (entry == null)
+        {
+          setResultCode(ResultCode.NO_SUCH_OBJECT);
+          appendErrorMessage(ERR_COMPARE_NO_SUCH_ENTRY.get(String
+              .valueOf(entryDN)));
+
+          // See if one of the entry's ancestors exists.
+          DN parentDN = entryDN.getParentDNInSuffix();
+          while (parentDN != null)
+          {
+            try
+            {
+              if (DirectoryServer.entryExists(parentDN))
+              {
+                setMatchedDN(parentDN);
+                break;
+              }
+            }
+            catch (Exception e)
+            {
+              if (debugEnabled())
+              {
+                TRACER.debugCaught(DebugLogLevel.ERROR, e);
+              }
+              break;
+            }
+
+            parentDN = parentDN.getParentDNInSuffix();
+          }
+
+          return;
+        }
+      }
+      catch (DirectoryException de)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, de);
+        }
+
+        setResultCode(de.getResultCode());
+        appendErrorMessage(de.getMessageObject());
+        return;
+      }
+
+      // Check to see if there are any controls in the request. If so, then
+      // see if there is any special processing required.
+      try
+      {
+        handleRequestControls();
+      }
+      catch (DirectoryException de)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, de);
+        }
+
+        setResponseData(de);
+        return;
+      }
+
+
+      // Check to see if the client has permission to perform the
+      // compare.
+
+      // FIXME: for now assume that this will check all permission
+      // pertinent to the operation. This includes proxy authorization
+      // and any other controls specified.
+
+      // FIXME: earlier checks to see if the entry already exists may
+      // have already exposed sensitive information to the client.
+      try
+      {
+        if (!AccessControlConfigManager.getInstance().getAccessControlHandler()
+            .isAllowed(this))
+        {
+          setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+          appendErrorMessage(ERR_COMPARE_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS
+              .get(String.valueOf(entryDN)));
+          return;
+        }
+      }
+      catch (DirectoryException e)
+      {
+        setResultCode(e.getResultCode());
+        appendErrorMessage(e.getMessageObject());
+        return;
+      }
+
+      // Check for a request to cancel this operation.
+      checkIfCanceled(false);
+
+
+      // Invoke the pre-operation compare plugins.
+      executePostOpPlugins.value = true;
+      PluginResult.PreOperation preOpResult =
+          DirectoryServer.getPluginConfigManager()
+              .invokePreOperationComparePlugins(this);
+      if (!preOpResult.continueProcessing())
+      {
+        setResultCode(preOpResult.getResultCode());
+        appendErrorMessage(preOpResult.getErrorMessage());
+        setMatchedDN(preOpResult.getMatchedDN());
+        setReferralURLs(preOpResult.getReferralURLs());
+        return;
+      }
+
+
+      // Get the base attribute type and set of options.
+      Set<String> options = getAttributeOptions();
+
+      // Actually perform the compare operation.
+      AttributeType attrType = getAttributeType();
+
+      List<Attribute> attrList = entry.getAttribute(attrType, options);
+      if ((attrList == null) || attrList.isEmpty())
+      {
+        setResultCode(ResultCode.NO_SUCH_ATTRIBUTE);
+        if (options == null)
+        {
+          appendErrorMessage(WARN_COMPARE_OP_NO_SUCH_ATTR.get(String
+              .valueOf(entryDN), getRawAttributeType()));
+        }
+        else
+        {
+          appendErrorMessage(WARN_COMPARE_OP_NO_SUCH_ATTR_WITH_OPTIONS.get(
+              String.valueOf(entryDN), getRawAttributeType()));
+        }
+      }
+      else
+      {
+        AttributeValue value =
+            AttributeValues.create(attrType, getAssertionValue());
+
+        boolean matchFound = false;
+        for (Attribute a : attrList)
+        {
+          if (a.contains(value))
+          {
+            matchFound = true;
+            break;
+          }
+        }
+
+        if (matchFound)
+        {
+          setResultCode(ResultCode.COMPARE_TRUE);
+        }
+        else
+        {
+          setResultCode(ResultCode.COMPARE_FALSE);
+        }
+      }
+    }
+    finally
+    {
+      LockManager.unlock(entryDN, readLock);
+    }
+  }
+
   /**
    * Performs any processing required for the controls included in the request.
    *
    * @throws  DirectoryException  If a problem occurs that should prevent the
    *                              operation from succeeding.
    */
-  protected void handleRequestControls()
-          throws DirectoryException
+  private void handleRequestControls() throws DirectoryException
   {
     List<Control> requestControls = getRequestControls();
     if ((requestControls != null) && (! requestControls.isEmpty()))
     {
-      for (int i=0; i < requestControls.size(); i++)
+      for (Control c : requestControls)
       {
-        Control c   = requestControls.get(i);
         String  oid = c.getOID();
 
         if (!LocalBackendWorkflowElement.isControlAllowed(entryDN, this, c))
@@ -462,7 +446,7 @@
           addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
               "obsoleteProxiedAuthzV1Control"));
 
-          // The requester must have the PROXIED_AUTH privilige in order to
+          // The requester must have the PROXIED_AUTH privilege in order to
           // be able to use this control.
           if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
           {
@@ -486,7 +470,7 @@
         }
         else if (oid.equals(OID_PROXIED_AUTH_V2))
         {
-          // The requester must have the PROXIED_AUTH privilige in order to
+          // The requester must have the PROXIED_AUTH privilege in order to
           // be able to use this control.
           if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
           {
@@ -524,4 +508,3 @@
     }
   }
 }
-
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
index d747a18..f829e42 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
@@ -74,43 +74,43 @@
   /**
    * The backend in which the operation is to be processed.
    */
-  protected Backend backend;
+  private Backend backend;
 
   /**
    * Indicates whether the no-op control was included in the request.
    */
-  protected boolean noOp;
+  private boolean noOp;
 
   /**
    * The client connection on which this operation was requested.
    */
-  protected ClientConnection clientConnection;
+  private ClientConnection clientConnection;
 
   /**
    * The original DN of the entry.
    */
-  protected DN entryDN;
+  private DN entryDN;
 
   /**
    * The current entry, before it is renamed.
    */
-  protected Entry currentEntry;
+  private Entry currentEntry;
 
   /**
    * The new entry, as it will appear after it has been renamed.
    */
-  protected Entry newEntry;
+  private Entry newEntry;
 
-  // The LDAP post-read request control, if present in the request.
+  /** The LDAP post-read request control, if present in the request. */
   private LDAPPostReadRequestControl postReadRequest;
 
-  // The LDAP pre-read request control, if present in the request.
+  /** The LDAP pre-read request control, if present in the request. */
   private LDAPPreReadRequestControl preReadRequest;
 
   /**
    * The new RDN for the entry.
    */
-  protected RDN newRDN;
+  private RDN newRDN;
 
 
 
@@ -171,447 +171,19 @@
   public void processLocalModifyDN(final LocalBackendWorkflowElement wfe)
       throws CanceledOperationException
   {
-    boolean executePostOpPlugins = false;
     this.backend = wfe.getBackend();
 
     clientConnection = getClientConnection();
 
-    // Get the plugin config manager that will be used for invoking plugins.
-    PluginConfigManager pluginConfigManager =
-         DirectoryServer.getPluginConfigManager();
-
     // Check for a request to cancel this operation.
     checkIfCanceled(false);
 
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-modifyDNProcessing:
-    {
-      // Process the entry DN, newRDN, and newSuperior elements from their raw
-      // forms as provided by the client to the forms required for the rest of
-      // the modify DN processing.
-      entryDN = getEntryDN();
-
-      newRDN = getNewRDN();
-      if (newRDN == null)
-      {
-        break modifyDNProcessing;
-      }
-
-      DN newSuperior = getNewSuperior();
-      if ((newSuperior == null) &&
-          (getRawNewSuperior() != null))
-      {
-        break modifyDNProcessing;
-      }
-
-      // Construct the new DN to use for the entry.
-      DN parentDN;
-      if (newSuperior == null)
-      {
-        parentDN = entryDN.getParentDNInSuffix();
-      }
-      else
-      {
-        if(newSuperior.isDescendantOf(entryDN))
-        {
-          setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-          appendErrorMessage(ERR_MODDN_NEW_SUPERIOR_IN_SUBTREE.get(
-              String.valueOf(entryDN), String.valueOf(newSuperior)));
-          break modifyDNProcessing;
-        }
-        parentDN = newSuperior;
-      }
-
-      if ((parentDN == null) || parentDN.isNullDN())
-      {
-        setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-        appendErrorMessage(ERR_MODDN_NO_PARENT.get(String.valueOf(entryDN)));
-        break modifyDNProcessing;
-      }
-
-      DN newDN = parentDN.concat(newRDN);
-
-      // Get the backend for the current entry, and the backend for the new
-      // entry.  If either is null, or if they are different, then fail.
-      Backend currentBackend = backend;
-      if (currentBackend == null)
-      {
-        setResultCode(ResultCode.NO_SUCH_OBJECT);
-        appendErrorMessage(ERR_MODDN_NO_BACKEND_FOR_CURRENT_ENTRY.get(
-                                String.valueOf(entryDN)));
-        break modifyDNProcessing;
-      }
-
-      Backend newBackend = DirectoryServer.getBackend(newDN);
-      if (newBackend == null)
-      {
-        setResultCode(ResultCode.NO_SUCH_OBJECT);
-        appendErrorMessage(ERR_MODDN_NO_BACKEND_FOR_NEW_ENTRY.get(
-                                String.valueOf(entryDN),
-                                String.valueOf(newDN)));
-        break modifyDNProcessing;
-      }
-      else if (! currentBackend.equals(newBackend))
-      {
-        setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-        appendErrorMessage(ERR_MODDN_DIFFERENT_BACKENDS.get(
-                                String.valueOf(entryDN),
-                                String.valueOf(newDN)));
-        break modifyDNProcessing;
-      }
-
-
-      // Check for a request to cancel this operation.
-      checkIfCanceled(false);
-
-
-      // Acquire write locks for the current and new DN.
-      final Lock currentLock = LockManager.lockWrite(entryDN);
-      if (currentLock == null)
-      {
-        setResultCode(ResultCode.BUSY);
-        appendErrorMessage(ERR_MODDN_CANNOT_LOCK_CURRENT_DN.get(
-                                String.valueOf(entryDN)));
-        break modifyDNProcessing;
-      }
-
-      Lock newLock = null;
-      try
-      {
-        newLock = LockManager.lockWrite(newDN);
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-
-        LockManager.unlock(entryDN, currentLock);
-
-        if (newLock != null)
-        {
-          LockManager.unlock(newDN, newLock);
-        }
-
-        setResultCode(DirectoryServer.getServerErrorResultCode());
-        appendErrorMessage(ERR_MODDN_EXCEPTION_LOCKING_NEW_DN.get(
-                                String.valueOf(entryDN), String.valueOf(newDN),
-                                getExceptionMessage(e)));
-        break modifyDNProcessing;
-      }
-
-      if (newLock == null)
-      {
-        LockManager.unlock(entryDN, currentLock);
-
-        setResultCode(ResultCode.BUSY);
-        appendErrorMessage(ERR_MODDN_CANNOT_LOCK_NEW_DN.get(
-                                String.valueOf(entryDN),
-                                String.valueOf(newDN)));
-        break modifyDNProcessing;
-      }
-
-      try
-      {
-        // Check for a request to cancel this operation.
-        checkIfCanceled(false);
-
-
-        // Get the current entry from the appropriate backend.  If it doesn't
-        // exist, then fail.
-        try
-        {
-          currentEntry = currentBackend.getEntry(entryDN);
-        }
-        catch (DirectoryException de)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, de);
-          }
-
-          setResponseData(de);
-          break modifyDNProcessing;
-        }
-
-        if (getOriginalEntry() == null)
-        {
-          // See if one of the entry's ancestors exists.
-          parentDN = entryDN.getParentDNInSuffix();
-          while (parentDN != null)
-          {
-            try
-            {
-              if (DirectoryServer.entryExists(parentDN))
-              {
-                setMatchedDN(parentDN);
-                break;
-              }
-            }
-            catch (Exception e)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, e);
-              }
-              break;
-            }
-
-            parentDN = parentDN.getParentDNInSuffix();
-          }
-
-          setResultCode(ResultCode.NO_SUCH_OBJECT);
-          appendErrorMessage(ERR_MODDN_NO_CURRENT_ENTRY.get(
-                                  String.valueOf(entryDN)));
-          break modifyDNProcessing;
-        }
-
-
-        // Check to see if there are any controls in the request.  If so, then
-        // see if there is any special processing required.
-        try
-        {
-          handleRequestControls();
-        }
-        catch (DirectoryException de)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, de);
-          }
-
-          setResponseData(de);
-          break modifyDNProcessing;
-        }
-
-
-        // Check to see if the client has permission to perform the
-        // modify DN.
-
-        // FIXME: for now assume that this will check all permission
-        // pertinent to the operation. This includes proxy authorization
-        // and any other controls specified.
-
-        // FIXME: earlier checks to see if the entry or new superior
-        // already exists may have already exposed sensitive information
-        // to the client.
-        try
-        {
-          if (!AccessControlConfigManager.getInstance()
-              .getAccessControlHandler().isAllowed(this))
-          {
-            setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-            appendErrorMessage(ERR_MODDN_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS
-                .get(String.valueOf(entryDN)));
-            break modifyDNProcessing;
-          }
-        }
-        catch (DirectoryException e)
-        {
-          setResultCode(e.getResultCode());
-          appendErrorMessage(e.getMessageObject());
-          break modifyDNProcessing;
-        }
-
-        // Duplicate the entry and set its new DN.  Also, create an empty list
-        // to hold the attribute-level modifications.
-        newEntry = currentEntry.duplicate(false);
-        newEntry.setDN(newDN);
-
-        // init the modifications
-        addModification(null);
-        List<Modification> modifications = this.getModifications();
-
-        if(!handleConflictResolution()) {
-            break modifyDNProcessing;
-        }
-
-        // If the operation is not a synchronization operation,
-        //  - Apply the RDN changes.
-        //  - Invoke the pre-operation modify DN plugins.
-        //  - apply additional modifications provided by the plugins.
-        // If the operation is a synchronization operation
-        //  - apply the operation as it was originally done on the master.
-        if (! isSynchronizationOperation())
-        {
-          // Apply any changes to the entry based on the change in its RDN.
-          // Also perform schema checking on the updated entry.
-          try
-          {
-            applyRDNChanges(modifications);
-          }
-          catch (DirectoryException de)
-          {
-            if (debugEnabled())
-            {
-              TRACER.debugCaught(DebugLogLevel.ERROR, de);
-            }
-
-            setResponseData(de);
-            break modifyDNProcessing;
-          }
-
-
-          // Check for a request to cancel this operation.
-          checkIfCanceled(false);
-
-
-          // Get a count of the current number of modifications.  The
-          // pre-operation plugins may alter this list, and we need to be able
-          // to identify which changes were made after they're done.
-          int modCount = modifications.size();
-
-          executePostOpPlugins = true;
-          PluginResult.PreOperation preOpResult =
-            pluginConfigManager.invokePreOperationModifyDNPlugins(this);
-          if (!preOpResult.continueProcessing())
-          {
-            setResultCode(preOpResult.getResultCode());
-            appendErrorMessage(preOpResult.getErrorMessage());
-            setMatchedDN(preOpResult.getMatchedDN());
-            setReferralURLs(preOpResult.getReferralURLs());
-            break modifyDNProcessing;
-          }
-
-
-          // Check to see if any of the pre-operation plugins made any changes
-          // to the entry.  If so, then apply them.
-          if (modifications.size() > modCount)
-          {
-            try
-            {
-              applyPreOpModifications(modifications, modCount, true);
-            }
-            catch (DirectoryException de)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, de);
-              }
-
-              setResponseData(de);
-              break modifyDNProcessing;
-            }
-          }
-        }
-        else
-        {
-          // This is a synchronization operation
-          // Apply the modifications as they were originally done.
-          try
-          {
-            applyRDNChanges(modifications);
-            applyPreOpModifications(modifications, 0, false);
-          }
-          catch (DirectoryException de)
-          {
-            if (debugEnabled())
-            {
-              TRACER.debugCaught(DebugLogLevel.ERROR, de);
-            }
-
-            setResponseData(de);
-            break modifyDNProcessing;
-          }
-        }
-
-
-        // Actually perform the modify DN operation.
-        // This should include taking
-        // care of any synchronization that might be needed.
-        try
-        {
-          // If it is not a private backend, then check to see if the server or
-          // backend is operating in read-only mode.
-          if (! currentBackend.isPrivateBackend())
-          {
-            switch (DirectoryServer.getWritabilityMode())
-            {
-              case DISABLED:
-                setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-                appendErrorMessage(ERR_MODDN_SERVER_READONLY.get(
-                                        String.valueOf(entryDN)));
-                break modifyDNProcessing;
-
-              case INTERNAL_ONLY:
-                if (! (isInternalOperation() || isSynchronizationOperation()))
-                {
-                  setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-                  appendErrorMessage(ERR_MODDN_SERVER_READONLY.get(
-                                          String.valueOf(entryDN)));
-                  break modifyDNProcessing;
-                }
-            }
-
-            switch (currentBackend.getWritabilityMode())
-            {
-              case DISABLED:
-                setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-                appendErrorMessage(ERR_MODDN_BACKEND_READONLY.get(
-                                        String.valueOf(entryDN)));
-                break modifyDNProcessing;
-
-              case INTERNAL_ONLY:
-                if (! (isInternalOperation() || isSynchronizationOperation()))
-                {
-                  setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-                  appendErrorMessage(ERR_MODDN_BACKEND_READONLY.get(
-                                          String.valueOf(entryDN)));
-                  break modifyDNProcessing;
-                }
-            }
-          }
-
-
-          if (noOp)
-          {
-            appendErrorMessage(INFO_MODDN_NOOP.get());
-            setResultCode(ResultCode.NO_OPERATION);
-          }
-          else
-          {
-              if(!processPreOperation()) {
-                  break modifyDNProcessing;
-              }
-              currentBackend.renameEntry(entryDN, newEntry, this);
-          }
-
-
-          // Attach the pre-read and/or post-read controls to the response if
-          // appropriate.
-          LocalBackendWorkflowElement.addPreReadResponse(this,
-              preReadRequest, currentEntry);
-          LocalBackendWorkflowElement.addPostReadResponse(this,
-              postReadRequest, newEntry);
-
-
-          if (! noOp)
-          {
-            setResultCode(ResultCode.SUCCESS);
-          }
-        }
-        catch (DirectoryException de)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, de);
-          }
-
-          setResponseData(de);
-          break modifyDNProcessing;
-        }
-      }
-      finally
-      {
-        LockManager.unlock(entryDN, currentLock);
-        LockManager.unlock(newDN, newLock);
-        processSynchPostOperationPlugins();
-      }
-    }
+    BooleanHolder executePostOpPlugins = new BooleanHolder();
+    processModifyDN(executePostOpPlugins);
 
     // Invoke the post-operation or post-synchronization modify DN plugins.
+    PluginConfigManager pluginConfigManager =
+        DirectoryServer.getPluginConfigManager();
     if (isSynchronizationOperation())
     {
       if (getResultCode() == ResultCode.SUCCESS)
@@ -619,10 +191,10 @@
         pluginConfigManager.invokePostSynchronizationModifyDNPlugins(this);
       }
     }
-    else if (executePostOpPlugins)
+    else if (executePostOpPlugins.value)
     {
       PluginResult.PostOperation postOpResult =
-           pluginConfigManager.invokePostOperationModifyDNPlugins(this);
+          pluginConfigManager.invokePostOperationModifyDNPlugins(this);
       if (!postOpResult.continueProcessing())
       {
         setResultCode(postOpResult.getResultCode());
@@ -646,8 +218,8 @@
           // Notify persistent searches.
           for (PersistentSearch psearch : wfe.getPersistentSearches())
           {
-            psearch.processModifyDN(newEntry, getChangeNumber(),
-                currentEntry.getDN());
+            psearch.processModifyDN(newEntry, getChangeNumber(), currentEntry
+                .getDN());
           }
 
           // Notify change listeners.
@@ -666,8 +238,9 @@
                 TRACER.debugCaught(DebugLogLevel.ERROR, e);
               }
 
-              Message message = ERR_MODDN_ERROR_NOTIFYING_CHANGE_LISTENER
-                  .get(getExceptionMessage(e));
+              Message message =
+                  ERR_MODDN_ERROR_NOTIFYING_CHANGE_LISTENER
+                      .get(getExceptionMessage(e));
               logError(message);
             }
           }
@@ -676,7 +249,350 @@
     }
   }
 
+  private void processModifyDN(BooleanHolder executePostOpPlugins)
+      throws CanceledOperationException
+  {
+    // Process the entry DN, newRDN, and newSuperior elements from their raw
+    // forms as provided by the client to the forms required for the rest of
+    // the modify DN processing.
+    entryDN = getEntryDN();
 
+    newRDN = getNewRDN();
+    if (newRDN == null)
+    {
+      return;
+    }
+
+    DN newSuperior = getNewSuperior();
+    if (newSuperior == null && getRawNewSuperior() != null)
+    {
+      return;
+    }
+
+    // Construct the new DN to use for the entry.
+    DN parentDN;
+    if (newSuperior == null)
+    {
+      parentDN = entryDN.getParentDNInSuffix();
+    }
+    else
+    {
+      if (newSuperior.isDescendantOf(entryDN))
+      {
+        setResultCode(ResultCode.UNWILLING_TO_PERFORM);
+        appendErrorMessage(ERR_MODDN_NEW_SUPERIOR_IN_SUBTREE.get(String
+            .valueOf(entryDN), String.valueOf(newSuperior)));
+        return;
+      }
+      parentDN = newSuperior;
+    }
+
+    if (parentDN == null || parentDN.isNullDN())
+    {
+      setResultCode(ResultCode.UNWILLING_TO_PERFORM);
+      appendErrorMessage(ERR_MODDN_NO_PARENT.get(String.valueOf(entryDN)));
+      return;
+    }
+
+    DN newDN = parentDN.concat(newRDN);
+
+    // Get the backend for the current entry, and the backend for the new
+    // entry. If either is null, or if they are different, then fail.
+    Backend currentBackend = backend;
+    if (currentBackend == null)
+    {
+      setResultCode(ResultCode.NO_SUCH_OBJECT);
+      appendErrorMessage(ERR_MODDN_NO_BACKEND_FOR_CURRENT_ENTRY.get(String
+          .valueOf(entryDN)));
+      return;
+    }
+
+    Backend newBackend = DirectoryServer.getBackend(newDN);
+    if (newBackend == null)
+    {
+      setResultCode(ResultCode.NO_SUCH_OBJECT);
+      appendErrorMessage(ERR_MODDN_NO_BACKEND_FOR_NEW_ENTRY.get(String
+          .valueOf(entryDN), String.valueOf(newDN)));
+      return;
+    }
+    else if (!currentBackend.equals(newBackend))
+    {
+      setResultCode(ResultCode.UNWILLING_TO_PERFORM);
+      appendErrorMessage(ERR_MODDN_DIFFERENT_BACKENDS.get(String
+          .valueOf(entryDN), String.valueOf(newDN)));
+      return;
+    }
+
+    // Check for a request to cancel this operation.
+    checkIfCanceled(false);
+
+    // Acquire write locks for the current and new DN.
+    final Lock currentLock = LockManager.lockWrite(entryDN);
+    if (currentLock == null)
+    {
+      setResultCode(ResultCode.BUSY);
+      appendErrorMessage(ERR_MODDN_CANNOT_LOCK_CURRENT_DN.get(String
+          .valueOf(entryDN)));
+      return;
+    }
+
+    Lock newLock = null;
+    try
+    {
+      newLock = LockManager.lockWrite(newDN);
+    }
+    catch (Exception e)
+    {
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, e);
+      }
+
+      LockManager.unlock(entryDN, currentLock);
+
+      if (newLock != null)
+      {
+        LockManager.unlock(newDN, newLock);
+      }
+
+      setResultCode(DirectoryServer.getServerErrorResultCode());
+      appendErrorMessage(ERR_MODDN_EXCEPTION_LOCKING_NEW_DN.get(String
+          .valueOf(entryDN), String.valueOf(newDN), getExceptionMessage(e)));
+      return;
+    }
+
+    if (newLock == null)
+    {
+      LockManager.unlock(entryDN, currentLock);
+
+      setResultCode(ResultCode.BUSY);
+      appendErrorMessage(ERR_MODDN_CANNOT_LOCK_NEW_DN.get(String
+          .valueOf(entryDN), String.valueOf(newDN)));
+      return;
+    }
+
+    try
+    {
+      // Check for a request to cancel this operation.
+      checkIfCanceled(false);
+
+      // Get the current entry from the appropriate backend. If it doesn't
+      // exist, then fail.
+      currentEntry = currentBackend.getEntry(entryDN);
+
+      if (getOriginalEntry() == null)
+      {
+        // See if one of the entry's ancestors exists.
+        parentDN = entryDN.getParentDNInSuffix();
+        while (parentDN != null)
+        {
+          try
+          {
+            if (DirectoryServer.entryExists(parentDN))
+            {
+              setMatchedDN(parentDN);
+              break;
+            }
+          }
+          catch (Exception e)
+          {
+            if (debugEnabled())
+            {
+              TRACER.debugCaught(DebugLogLevel.ERROR, e);
+            }
+            break;
+          }
+
+          parentDN = parentDN.getParentDNInSuffix();
+        }
+
+        setResultCode(ResultCode.NO_SUCH_OBJECT);
+        appendErrorMessage(ERR_MODDN_NO_CURRENT_ENTRY.get(String
+            .valueOf(entryDN)));
+        return;
+      }
+
+      // Check to see if there are any controls in the request. If so, then
+      // see if there is any special processing required.
+      handleRequestControls();
+
+      // Check to see if the client has permission to perform the
+      // modify DN.
+
+      // FIXME: for now assume that this will check all permission
+      // pertinent to the operation. This includes proxy authorization
+      // and any other controls specified.
+
+      // FIXME: earlier checks to see if the entry or new superior
+      // already exists may have already exposed sensitive information
+      // to the client.
+      try
+      {
+        if (!AccessControlConfigManager.getInstance().getAccessControlHandler()
+            .isAllowed(this))
+        {
+          setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+          appendErrorMessage(ERR_MODDN_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS
+              .get(String.valueOf(entryDN)));
+          return;
+        }
+      }
+      catch (DirectoryException e)
+      {
+        setResultCode(e.getResultCode());
+        appendErrorMessage(e.getMessageObject());
+        return;
+      }
+
+      // Duplicate the entry and set its new DN. Also, create an empty list
+      // to hold the attribute-level modifications.
+      newEntry = currentEntry.duplicate(false);
+      newEntry.setDN(newDN);
+
+      // init the modifications
+      addModification(null);
+      List<Modification> modifications = this.getModifications();
+
+      if (!handleConflictResolution())
+      {
+        return;
+      }
+
+      // If the operation is not a synchronization operation,
+      // - Apply the RDN changes.
+      // - Invoke the pre-operation modify DN plugins.
+      // - apply additional modifications provided by the plugins.
+      // If the operation is a synchronization operation
+      // - apply the operation as it was originally done on the master.
+      if (!isSynchronizationOperation())
+      {
+        // Apply any changes to the entry based on the change in its RDN.
+        // Also perform schema checking on the updated entry.
+        applyRDNChanges(modifications);
+
+        // Check for a request to cancel this operation.
+        checkIfCanceled(false);
+
+        // Get a count of the current number of modifications. The
+        // pre-operation plugins may alter this list, and we need to be able
+        // to identify which changes were made after they're done.
+        int modCount = modifications.size();
+
+        executePostOpPlugins.value = true;
+        PluginResult.PreOperation preOpResult =
+            DirectoryServer.getPluginConfigManager()
+                .invokePreOperationModifyDNPlugins(this);
+        if (!preOpResult.continueProcessing())
+        {
+          setResultCode(preOpResult.getResultCode());
+          appendErrorMessage(preOpResult.getErrorMessage());
+          setMatchedDN(preOpResult.getMatchedDN());
+          setReferralURLs(preOpResult.getReferralURLs());
+          return;
+        }
+
+        // Check to see if any of the pre-operation plugins made any changes
+        // to the entry. If so, then apply them.
+        if (modifications.size() > modCount)
+        {
+          applyPreOpModifications(modifications, modCount, true);
+        }
+      }
+      else
+      {
+        // This is a synchronization operation
+        // Apply the modifications as they were originally done.
+        applyRDNChanges(modifications);
+        applyPreOpModifications(modifications, 0, false);
+      }
+
+      // Actually perform the modify DN operation.
+      // This should include taking
+      // care of any synchronization that might be needed.
+      // If it is not a private backend, then check to see if the server or
+      // backend is operating in read-only mode.
+      if (!currentBackend.isPrivateBackend())
+      {
+        switch (DirectoryServer.getWritabilityMode())
+        {
+        case DISABLED:
+          setResultCode(ResultCode.UNWILLING_TO_PERFORM);
+          appendErrorMessage(ERR_MODDN_SERVER_READONLY.get(String
+              .valueOf(entryDN)));
+          return;
+
+        case INTERNAL_ONLY:
+          if (!(isInternalOperation() || isSynchronizationOperation()))
+          {
+            setResultCode(ResultCode.UNWILLING_TO_PERFORM);
+            appendErrorMessage(ERR_MODDN_SERVER_READONLY.get(String
+                .valueOf(entryDN)));
+            return;
+          }
+        }
+
+        switch (currentBackend.getWritabilityMode())
+        {
+        case DISABLED:
+          setResultCode(ResultCode.UNWILLING_TO_PERFORM);
+          appendErrorMessage(ERR_MODDN_BACKEND_READONLY.get(String
+              .valueOf(entryDN)));
+          return;
+
+        case INTERNAL_ONLY:
+          if (!(isInternalOperation() || isSynchronizationOperation()))
+          {
+            setResultCode(ResultCode.UNWILLING_TO_PERFORM);
+            appendErrorMessage(ERR_MODDN_BACKEND_READONLY.get(String
+                .valueOf(entryDN)));
+            return;
+          }
+        }
+      }
+
+      if (noOp)
+      {
+        appendErrorMessage(INFO_MODDN_NOOP.get());
+        setResultCode(ResultCode.NO_OPERATION);
+      }
+      else
+      {
+        if (!processPreOperation())
+        {
+          return;
+        }
+        currentBackend.renameEntry(entryDN, newEntry, this);
+      }
+
+      // Attach the pre-read and/or post-read controls to the response if
+      // appropriate.
+      LocalBackendWorkflowElement.addPreReadResponse(this, preReadRequest,
+          currentEntry);
+      LocalBackendWorkflowElement.addPostReadResponse(this, postReadRequest,
+          newEntry);
+
+      if (!noOp)
+      {
+        setResultCode(ResultCode.SUCCESS);
+      }
+    }
+    catch (DirectoryException de)
+    {
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, de);
+      }
+
+      setResponseData(de);
+      return;
+    }
+    finally
+    {
+      LockManager.unlock(entryDN, currentLock);
+      LockManager.unlock(newDN, newLock);
+      processSynchPostOperationPlugins();
+    }
+  }
 
   /**
    * Processes the set of controls included in the request.
@@ -684,8 +600,7 @@
    * @throws  DirectoryException  If a problem occurs that should cause the
    *                              modify DN operation to fail.
    */
-  protected void handleRequestControls()
-          throws DirectoryException
+  private void handleRequestControls() throws DirectoryException
   {
     List<Control> requestControls = getRequestControls();
     if ((requestControls != null) && (! requestControls.isEmpty()))
@@ -790,7 +705,7 @@
           addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
               "obsoleteProxiedAuthzV1Control"));
 
-          // The requester must have the PROXIED_AUTH privilige in order to
+          // The requester must have the PROXIED_AUTH privilege in order to
           // be able to use this control.
           if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
           {
@@ -814,7 +729,7 @@
         }
         else if (oid.equals(OID_PROXIED_AUTH_V2))
         {
-          // The requester must have the PROXIED_AUTH privilige in order to
+          // The requester must have the PROXIED_AUTH privilege in order to
           // be able to use this control.
           if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
           {
@@ -864,7 +779,7 @@
    * @throws  DirectoryException  If a problem occurs that should cause the
    *                              modify DN operation to fail.
    */
-  protected void applyRDNChanges(List<Modification> modifications)
+  private void applyRDNChanges(List<Modification> modifications)
           throws DirectoryException
   {
     // If we should delete the old RDN values from the entry, then do so.
@@ -891,8 +806,7 @@
           }
         }
 
-        LinkedList<AttributeValue> missingValues =
-             new LinkedList<AttributeValue>();
+        List<AttributeValue> missingValues = new LinkedList<AttributeValue>();
         newEntry.removeAttribute(a, missingValues);
 
         if (missingValues.isEmpty())
@@ -912,8 +826,7 @@
           newRDN.getAttributeName(i),
           newRDN.getAttributeValue(i));
 
-      LinkedList<AttributeValue> duplicateValues =
-           new LinkedList<AttributeValue>();
+      List<AttributeValue> duplicateValues = new LinkedList<AttributeValue>();
       newEntry.addAttribute(a, duplicateValues);
 
       if (duplicateValues.isEmpty())
@@ -981,7 +894,7 @@
    * @throws  DirectoryException  If a problem occurs that should cause the
    *                              modify DN operation to fail.
    */
-  protected void applyPreOpModifications(List<Modification> modifications,
+  private void applyPreOpModifications(List<Modification> modifications,
                                        int startPos, boolean checkSchema)
           throws DirectoryException
   {
@@ -993,14 +906,13 @@
       switch (m.getModificationType())
       {
         case ADD:
-          LinkedList<AttributeValue> duplicateValues =
+          List<AttributeValue> duplicateValues =
                new LinkedList<AttributeValue>();
           newEntry.addAttribute(a, duplicateValues);
           break;
 
         case DELETE:
-          LinkedList<AttributeValue> missingValues =
-               new LinkedList<AttributeValue>();
+          List<AttributeValue> missingValues = new LinkedList<AttributeValue>();
           newEntry.removeAttribute(a, missingValues);
           break;
 
@@ -1038,7 +950,8 @@
    * @return  {@code true} if processing should continue for the operation, or
    *          {@code false} if not.
    */
-  protected boolean handleConflictResolution() {
+  private boolean handleConflictResolution()
+  {
       boolean returnVal = true;
 
       for (SynchronizationProvider<?> provider :
@@ -1075,7 +988,8 @@
    * @return  {@code true} if processing should continue for the operation, or
    *          {@code false} if not.
    */
-  protected boolean processPreOperation() {
+  private boolean processPreOperation()
+  {
       boolean returnVal = true;
 
       for (SynchronizationProvider<?> provider :
@@ -1108,7 +1022,8 @@
   /**
    * Invoke post operation synchronization providers.
    */
-  protected void processSynchPostOperationPlugins() {
+  private void processSynchPostOperationPlugins()
+  {
       for (SynchronizationProvider<?> provider : DirectoryServer
               .getSynchronizationProviders()) {
           try {
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
index 52b155c..f568cdc 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
@@ -27,8 +27,6 @@
  */
 package org.opends.server.workflowelement.localbackend;
 
-
-
 import java.util.List;
 
 import org.opends.server.api.Backend;
@@ -43,7 +41,6 @@
 import org.opends.server.core.AccessControlConfigManager;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.PersistentSearch;
-import org.opends.server.core.PluginConfigManager;
 import org.opends.server.core.SearchOperationWrapper;
 import org.opends.server.core.SearchOperation;
 import org.opends.server.loggers.debug.DebugTracer;
@@ -58,8 +55,6 @@
 import static org.opends.server.util.ServerConstants.*;
 import static org.opends.server.util.StaticUtils.*;
 
-
-
 /**
  * This class defines an operation used to search for entries in a local backend
  * of the Directory Server.
@@ -79,33 +74,33 @@
   /**
    * The backend in which the search is to be performed.
    */
-  protected Backend backend;
+  private Backend backend;
 
   /**
    * Indicates whether we should actually process the search.  This should
    * only be false if it's a persistent search with changesOnly=true.
    */
-  protected boolean processSearch;
+  private boolean processSearch;
 
   /**
    * The client connection for the search operation.
    */
-  protected ClientConnection clientConnection;
+  private ClientConnection clientConnection;
 
   /**
    * The base DN for the search.
    */
-  protected DN baseDN;
+  private DN baseDN;
 
   /**
    * The persistent search request, if applicable.
    */
-  protected PersistentSearch persistentSearch;
+  private PersistentSearch persistentSearch;
 
   /**
    * The filter for the search.
    */
-  protected SearchFilter filter;
+  private SearchFilter filter;
 
 
 
@@ -134,195 +129,27 @@
   public void processLocalSearch(LocalBackendWorkflowElement wfe)
       throws CanceledOperationException
   {
-    boolean executePostOpPlugins = false;
     this.backend = wfe.getBackend();
 
     clientConnection = getClientConnection();
 
-    // Get the plugin config manager that will be used for invoking plugins.
-    PluginConfigManager pluginConfigManager =
-      DirectoryServer.getPluginConfigManager();
     processSearch = true;
 
     // Check for a request to cancel this operation.
     checkIfCanceled(false);
 
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-searchProcessing:
-    {
-      // Process the search base and filter to convert them from their raw forms
-      // as provided by the client to the forms required for the rest of the
-      // search processing.
-      baseDN = getBaseDN();
-      filter = getFilter();
-
-      if ((baseDN == null) || (filter == null)){
-        break searchProcessing;
-      }
-
-      // Check to see if there are any controls in the request.  If so, then
-      // see if there is any special processing required.
-      try
-      {
-        handleRequestControls();
-      }
-      catch (DirectoryException de)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, de);
-        }
-
-        setResponseData(de);
-        break searchProcessing;
-      }
-
-
-      // Check to see if the client has permission to perform the
-      // search.
-
-      // FIXME: for now assume that this will check all permission
-      // pertinent to the operation. This includes proxy authorization
-      // and any other controls specified.
-      try
-      {
-        if (!AccessControlConfigManager.getInstance()
-            .getAccessControlHandler().isAllowed(this))
-        {
-          setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-          appendErrorMessage(ERR_SEARCH_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS
-              .get(String.valueOf(baseDN)));
-          break searchProcessing;
-        }
-      }
-      catch (DirectoryException e)
-      {
-        setResultCode(e.getResultCode());
-        appendErrorMessage(e.getMessageObject());
-        break searchProcessing;
-      }
-
-      // Check for a request to cancel this operation.
-      checkIfCanceled(false);
-
-
-      // Invoke the pre-operation search plugins.
-      executePostOpPlugins = true;
-      PluginResult.PreOperation preOpResult =
-          pluginConfigManager.invokePreOperationSearchPlugins(this);
-      if (!preOpResult.continueProcessing())
-      {
-        setResultCode(preOpResult.getResultCode());
-        appendErrorMessage(preOpResult.getErrorMessage());
-        setMatchedDN(preOpResult.getMatchedDN());
-        setReferralURLs(preOpResult.getReferralURLs());
-        break searchProcessing;
-      }
-
-
-      // Check for a request to cancel this operation.
-      checkIfCanceled(false);
-
-
-      // Get the backend that should hold the search base.  If there is none,
-      // then fail.
-      if (backend == null)
-      {
-        setResultCode(ResultCode.NO_SUCH_OBJECT);
-        appendErrorMessage(ERR_SEARCH_BASE_DOESNT_EXIST.get(
-                                String.valueOf(baseDN)));
-        break searchProcessing;
-      }
-
-
-      // We'll set the result code to "success".  If a problem occurs, then it
-      // will be overwritten.
-      setResultCode(ResultCode.SUCCESS);
-
-
-      // If there's a persistent search, then register it with the server.
-      if (persistentSearch != null)
-      {
-        //The Core server maintains the count of concurrent persistent searches
-        //so that all the backends (Remote and Local)  are aware of it. Verify
-        //with the core if we have already reached the threshold.
-        if(!DirectoryServer.allowNewPersistentSearch())
-        {
-          setResultCode(ResultCode.ADMIN_LIMIT_EXCEEDED);
-          appendErrorMessage(ERR_MAX_PSEARCH_LIMIT_EXCEEDED.get());
-          break searchProcessing;
-        }
-        wfe.registerPersistentSearch(persistentSearch);
-        persistentSearch.enable();
-      }
-
-
-      // Process the search in the backend and all its subordinates.
-      try
-      {
-        if (processSearch)
-        {
-          backend.search(this);
-        }
-      }
-      catch (DirectoryException de)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.VERBOSE, de);
-        }
-
-        setResponseData(de);
-
-        if (persistentSearch != null)
-        {
-          persistentSearch.cancel();
-          setSendResponse(true);
-        }
-
-        break searchProcessing;
-      }
-      catch (CanceledOperationException coe)
-      {
-        if (persistentSearch != null)
-        {
-          persistentSearch.cancel();
-          setSendResponse(true);
-        }
-
-        throw coe;
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-
-        setResultCode(DirectoryServer.getServerErrorResultCode());
-        appendErrorMessage(ERR_SEARCH_BACKEND_EXCEPTION.get(
-                                getExceptionMessage(e)));
-
-        if (persistentSearch != null)
-        {
-          persistentSearch.cancel();
-          setSendResponse(true);
-        }
-
-        break searchProcessing;
-      }
-    }
-
+    BooleanHolder executePostOpPlugins = new BooleanHolder();
+    processSearch(wfe, executePostOpPlugins);
 
     // Check for a request to cancel this operation.
     checkIfCanceled(false);
 
     // Invoke the post-operation search plugins.
-    if (executePostOpPlugins)
+    if (executePostOpPlugins.value)
     {
       PluginResult.PostOperation postOpResult =
-           pluginConfigManager.invokePostOperationSearchPlugins(this);
+          DirectoryServer.getPluginConfigManager()
+              .invokePostOperationSearchPlugins(this);
       if (!postOpResult.continueProcessing())
       {
         setResultCode(postOpResult.getResultCode());
@@ -333,15 +160,180 @@
     }
   }
 
+  private void processSearch(LocalBackendWorkflowElement wfe,
+      BooleanHolder executePostOpPlugins) throws CanceledOperationException
+  {
+    // Process the search base and filter to convert them from their raw forms
+    // as provided by the client to the forms required for the rest of the
+    // search processing.
+    baseDN = getBaseDN();
+    filter = getFilter();
+
+    if ((baseDN == null) || (filter == null))
+    {
+      return;
+    }
+
+    // Check to see if there are any controls in the request. If so, then
+    // see if there is any special processing required.
+    try
+    {
+      handleRequestControls();
+    }
+    catch (DirectoryException de)
+    {
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, de);
+      }
+
+      setResponseData(de);
+      return;
+    }
+
+
+    // Check to see if the client has permission to perform the
+    // search.
+
+    // FIXME: for now assume that this will check all permission
+    // pertinent to the operation. This includes proxy authorization
+    // and any other controls specified.
+    try
+    {
+      if (!AccessControlConfigManager.getInstance().getAccessControlHandler()
+          .isAllowed(this))
+      {
+        setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+        appendErrorMessage(ERR_SEARCH_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS
+            .get(String.valueOf(baseDN)));
+        return;
+      }
+    }
+    catch (DirectoryException e)
+    {
+      setResultCode(e.getResultCode());
+      appendErrorMessage(e.getMessageObject());
+      return;
+    }
+
+    // Check for a request to cancel this operation.
+    checkIfCanceled(false);
+
+
+    // Invoke the pre-operation search plugins.
+    executePostOpPlugins.value = true;
+    PluginResult.PreOperation preOpResult =
+        DirectoryServer.getPluginConfigManager()
+            .invokePreOperationSearchPlugins(this);
+    if (!preOpResult.continueProcessing())
+    {
+      setResultCode(preOpResult.getResultCode());
+      appendErrorMessage(preOpResult.getErrorMessage());
+      setMatchedDN(preOpResult.getMatchedDN());
+      setReferralURLs(preOpResult.getReferralURLs());
+      return;
+    }
+
+
+    // Check for a request to cancel this operation.
+    checkIfCanceled(false);
+
+
+    // Get the backend that should hold the search base. If there is none,
+    // then fail.
+    if (backend == null)
+    {
+      setResultCode(ResultCode.NO_SUCH_OBJECT);
+      appendErrorMessage(ERR_SEARCH_BASE_DOESNT_EXIST.get(String
+          .valueOf(baseDN)));
+      return;
+    }
+
+
+    // We'll set the result code to "success". If a problem occurs, then it
+    // will be overwritten.
+    setResultCode(ResultCode.SUCCESS);
+
+
+    // If there's a persistent search, then register it with the server.
+    if (persistentSearch != null)
+    {
+      // The Core server maintains the count of concurrent persistent searches
+      // so that all the backends (Remote and Local) are aware of it. Verify
+      // with the core if we have already reached the threshold.
+      if (!DirectoryServer.allowNewPersistentSearch())
+      {
+        setResultCode(ResultCode.ADMIN_LIMIT_EXCEEDED);
+        appendErrorMessage(ERR_MAX_PSEARCH_LIMIT_EXCEEDED.get());
+        return;
+      }
+      wfe.registerPersistentSearch(persistentSearch);
+      persistentSearch.enable();
+    }
+
+
+    // Process the search in the backend and all its subordinates.
+    try
+    {
+      if (processSearch)
+      {
+        backend.search(this);
+      }
+    }
+    catch (DirectoryException de)
+    {
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.VERBOSE, de);
+      }
+
+      setResponseData(de);
+
+      if (persistentSearch != null)
+      {
+        persistentSearch.cancel();
+        setSendResponse(true);
+      }
+
+      return;
+    }
+    catch (CanceledOperationException coe)
+    {
+      if (persistentSearch != null)
+      {
+        persistentSearch.cancel();
+        setSendResponse(true);
+      }
+
+      throw coe;
+    }
+    catch (Exception e)
+    {
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, e);
+      }
+
+      setResultCode(DirectoryServer.getServerErrorResultCode());
+      appendErrorMessage(ERR_SEARCH_BACKEND_EXCEPTION
+          .get(getExceptionMessage(e)));
+
+      if (persistentSearch != null)
+      {
+        persistentSearch.cancel();
+        setSendResponse(true);
+      }
+    }
+  }
+
 
   /**
    * Handles any controls contained in the request.
    *
-   * @throws  DirectoryException  If there is a problem with any of the request
-   *                              controls.
+   * @throws DirectoryException
+   *           If there is a problem with any of the request controls.
    */
-  protected void handleRequestControls()
-          throws DirectoryException
+  private void handleRequestControls() throws DirectoryException
   {
     List<Control> requestControls  = getRequestControls();
     if ((requestControls != null) && (! requestControls.isEmpty()))
@@ -443,7 +435,7 @@
           addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
               "obsoleteProxiedAuthzV1Control"));
 
-          // The requester must have the PROXIED_AUTH privilige in order to be
+          // The requester must have the PROXIED_AUTH privilege in order to be
           // able to use this control.
           if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
           {
@@ -467,7 +459,7 @@
         }
         else if (oid.equals(OID_PROXIED_AUTH_V2))
         {
-          // The requester must have the PROXIED_AUTH privilige in order to be
+          // The requester must have the PROXIED_AUTH privilege in order to be
           // able to use this control.
           if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
           {

--
Gitblit v1.10.0