From 35a408038c1de64a6f13f0e7b246a645e9945e3c Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Tue, 18 Mar 2008 22:44:58 +0000
Subject: [PATCH] With this refactoring:

---
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java                            |  192 
 opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java                                   |   68 
 opends/src/server/org/opends/server/types/CancelRequest.java                                                                 |   63 
 opends/src/server/org/opends/server/types/operation/PluginOperation.java                                                     |   35 
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java                              |  106 
 opends/src/server/org/opends/server/extensions/TraditionalWorkQueue.java                                                     |    4 
 opends/src/server/org/opends/server/core/CompareOperationBasis.java                                                          |  220 
 opends/src/server/org/opends/server/extensions/PasswordPolicyStateExtendedOperation.java                                     |    2 
 opends/src/server/org/opends/server/types/AbstractOperation.java                                                             |  170 
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java                           |  118 
 opends/src/server/org/opends/server/api/plugin/PluginResult.java                                                             | 1477 ++++++++
 opends/src/server/org/opends/server/core/DeleteOperationBasis.java                                                           |  223 
 opends/src/server/org/opends/server/extensions/TraditionalWorkerThread.java                                                  |   17 
 opends/src/server/org/opends/server/plugins/profiler/ProfilerPlugin.java                                                     |    6 
 opends/src/server/org/opends/server/core/ModifyOperationBasis.java                                                           |  228 
 opends/src/server/org/opends/server/plugins/ReferentialIntegrityPlugin.java                                                  |   21 
 opends/src/server/org/opends/server/protocols/jmx/RmiAuthenticator.java                                                      |   19 
 opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DelayPreOpPlugin.java                                    |   68 
 opends/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java                                              |    2 
 opends/src/server/org/opends/server/core/PasswordPolicyState.java                                                            | 1115 ++----
 opends/src/server/org/opends/server/types/CanceledOperationException.java                                                    |   26 
 opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java                                  |   30 
 opends/src/server/org/opends/server/api/SynchronizationProvider.java                                                         |    8 
 opends/src/server/org/opends/server/core/WorkflowTopologyNode.java                                                           |   23 
 opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java         |    2 
 opends/src/server/org/opends/server/backends/RootDSEBackend.java                                                             |   15 
 opends/tests/unit-tests-testng/src/server/org/opends/server/core/BindOperationTestCase.java                                  |   47 
 opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java                                                 |   32 
 opends/src/server/org/opends/server/types/operation/PreOperationOperation.java                                               |   80 
 opends/src/server/org/opends/server/api/plugin/DirectoryServerPlugin.java                                                    |  175 
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java                          |  188 
 opends/src/server/org/opends/server/core/PluginConfigManager.java                                                            | 1494 ++++----
 opends/src/server/org/opends/server/types/operation/PreParseOperation.java                                                   |   82 
 opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CancelExtendedOperationTestCase.java                  |   67 
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java                            |  130 
 opends/src/server/org/opends/server/plugins/LastModPlugin.java                                                               |   26 
 opends/src/server/org/opends/server/backends/jeb/EntryContainer.java                                                         |   17 
 opends/src/server/org/opends/server/core/OperationWrapper.java                                                               |   66 
 opends/src/server/org/opends/server/extensions/PlainSASLMechanismHandler.java                                                |    2 
 opends/src/server/org/opends/server/util/LDIFReader.java                                                                     |    8 
 opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/UpdatePreOpPlugin.java                                   |   15 
 opends/src/server/org/opends/server/plugins/UniqueAttributePlugin.java                                                       |   97 
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java                            |  169 
 opends/src/server/org/opends/server/backends/task/TaskBackend.java                                                           |    5 
 opends/src/server/org/opends/server/core/AbandonOperationBasis.java                                                          |  127 
 opends/tests/unit-tests-testng/src/server/org/opends/server/core/AbandonOperationTestCase.java                               |    5 
 opends/src/messages/messages/core.properties                                                                                 |    4 
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java                            |   12 
 opends/src/server/org/opends/server/plugins/SevenBitCleanPlugin.java                                                         |   96 
 opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/NullPlugin.java                                          |   10 
 opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/DirectoryServerPluginTestCase.java                    |  150 
 opends/src/server/org/opends/server/core/UnbindOperationBasis.java                                                           |   60 
 opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java                                                         |  227 
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java                               |  189 
 opends/src/server/org/opends/server/core/SearchOperationBasis.java                                                           |  294 -
 opends/src/server/org/opends/server/plugins/EntryUUIDPlugin.java                                                             |   21 
 opends/src/server/org/opends/server/core/ExtendedOperationBasis.java                                                         |  342 -
 opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java                                                |   11 
 opends/src/server/org/opends/server/plugins/LDAPADListPlugin.java                                                            |    8 
 opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java                                |   44 
 opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java |    2 
 opends/src/server/org/opends/server/extensions/CancelExtendedOperation.java                                                  |    7 
 opends/src/server/org/opends/server/replication/plugin/ReplicationDomain.java                                                |   74 
 opends/src/server/org/opends/server/controls/ProxiedAuthV1Control.java                                                       |    3 
 opends/src/server/org/opends/server/api/Backend.java                                                                         |   22 
 opends/src/server/org/opends/server/types/Entry.java                                                                         |    6 
 opends/src/server/org/opends/server/core/AddOperationBasis.java                                                              |  235 -
 opends/src/server/org/opends/server/plugins/PasswordPolicyImportPlugin.java                                                  |   12 
 opends/src/server/org/opends/server/core/BindOperationBasis.java                                                             |  185 
 opends/src/server/org/opends/server/types/SynchronizationProviderResult.java                                                 |  237 
 opends/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandler.java                                            |    2 
 opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java                                           |   20 
 opends/src/server/org/opends/server/core/Workflow.java                                                                       |    7 
 opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java                                                   |    4 
 opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java                                |  102 
 opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java                                                       |    4 
 opends/src/server/org/opends/server/types/CancelResult.java                                                                  |   65 
 opends/src/server/org/opends/server/core/DirectoryServer.java                                                                |    6 
 opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java                                          |    2 
 opends/tests/unit-tests-testng/src/server/org/opends/server/core/UnbindOperationTestCase.java                                |   13 
 opends/src/server/org/opends/server/api/ClientConnection.java                                                                |    8 
 /dev/null                                                                                                                    |  139 
 opends/src/server/org/opends/server/tools/VerifyIndex.java                                                                   |   13 
 opends/src/server/org/opends/server/backends/jeb/BackendImpl.java                                                            |    3 
 opends/src/server/org/opends/server/types/Operation.java                                                                     |   64 
 opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/SevenBitCleanPluginTestCase.java                         |   13 
 opends/src/server/org/opends/server/workflowelement/WorkflowElement.java                                                     |    7 
 opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/ShortCircuitPlugin.java                                  |  190 
 opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java                                         |    4 
 opends/src/server/org/opends/server/core/RootDseWorkflowTopology.java                                                        |   23 
 opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DisconnectClientPlugin.java                              |  429 -
 opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/InvocationCounterPlugin.java                             |  197 
 opends/src/server/org/opends/server/core/WorkflowImpl.java                                                                   |   13 
 93 files changed, 4,969 insertions(+), 5,700 deletions(-)

diff --git a/opends/src/messages/messages/core.properties b/opends/src/messages/messages/core.properties
index 86ca354..fed3c05 100644
--- a/opends/src/messages/messages/core.properties
+++ b/opends/src/messages/messages/core.properties
@@ -1764,3 +1764,7 @@
  Directory Server
 NOTICE_VERSION_698=%s
 NOTICE_BUILD_ID_699=Build ID:                 %s
+MILD_ERR_CANNOT_CANCEL_START_TLS_700=Start TLS extended operations cannot be \
+  canceled
+MILD_ERR_CANNOT_CANCEL_CANCEL_701=Cancel extended operations can not be \
+  canceled
diff --git a/opends/src/server/org/opends/server/api/Backend.java b/opends/src/server/org/opends/server/api/Backend.java
index 299fc2f..61d6425 100644
--- a/opends/src/server/org/opends/server/api/Backend.java
+++ b/opends/src/server/org/opends/server/api/Backend.java
@@ -47,7 +47,7 @@
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.BackupConfig;
 import org.opends.server.types.BackupDirectory;
-import org.opends.server.types.CancelledOperationException;
+import org.opends.server.types.CanceledOperationException;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.DN;
 import org.opends.server.types.Entry;
@@ -531,14 +531,14 @@
    * @throws  DirectoryException  If a problem occurs while trying to
    *                              add the entry.
    *
-   * @throws  CancelledOperationException  If this backend noticed and
+   * @throws CanceledOperationException  If this backend noticed and
    *                                       reacted to a request to
    *                                       cancel or abandon the add
    *                                       operation.
    */
   public abstract void addEntry(Entry entry,
                                 AddOperation addOperation)
-         throws DirectoryException, CancelledOperationException;
+         throws DirectoryException, CanceledOperationException;
 
 
 
@@ -560,14 +560,14 @@
    * @throws  DirectoryException  If a problem occurs while trying to
    *                              remove the entry.
    *
-   * @throws  CancelledOperationException  If this backend noticed and
+   * @throws CanceledOperationException  If this backend noticed and
    *                                       reacted to a request to
    *                                       cancel or abandon the
    *                                       delete operation.
    */
   public abstract void deleteEntry(DN entryDN,
                                    DeleteOperation deleteOperation)
-         throws DirectoryException, CancelledOperationException;
+         throws DirectoryException, CanceledOperationException;
 
 
 
@@ -587,14 +587,14 @@
    * @throws  DirectoryException  If a problem occurs while trying to
    *                              replace the entry.
    *
-   * @throws  CancelledOperationException  If this backend noticed and
+   * @throws CanceledOperationException  If this backend noticed and
    *                                       reacted to a request to
    *                                       cancel or abandon the
    *                                       modify operation.
    */
   public abstract void replaceEntry(Entry entry,
                                     ModifyOperation modifyOperation)
-         throws DirectoryException, CancelledOperationException;
+         throws DirectoryException, CanceledOperationException;
 
 
 
@@ -617,14 +617,14 @@
    * @throws  DirectoryException  If a problem occurs while trying to
    *                              perform the rename.
    *
-   * @throws  CancelledOperationException  If this backend noticed and
+   * @throws CanceledOperationException  If this backend noticed and
    *                                       reacted to a request to
    *                                       cancel or abandon the
    *                                       modify DN operation.
    */
   public abstract void renameEntry(DN currentDN, Entry entry,
                             ModifyDNOperation modifyDNOperation)
-         throws DirectoryException, CancelledOperationException;
+         throws DirectoryException, CanceledOperationException;
 
 
 
@@ -639,13 +639,13 @@
    * @throws  DirectoryException  If a problem occurs while processing
    *                              the search.
    *
-   * @throws  CancelledOperationException  If this backend noticed and
+   * @throws CanceledOperationException  If this backend noticed and
    *                                       reacted to a request to
    *                                       cancel or abandon the
    *                                       search operation.
    */
   public abstract void search(SearchOperation searchOperation)
-         throws DirectoryException, CancelledOperationException;
+         throws DirectoryException, CanceledOperationException;
 
 
 
diff --git a/opends/src/server/org/opends/server/api/ClientConnection.java b/opends/src/server/org/opends/server/api/ClientConnection.java
index 167de55..e35379c 100644
--- a/opends/src/server/org/opends/server/api/ClientConnection.java
+++ b/opends/src/server/org/opends/server/api/ClientConnection.java
@@ -38,7 +38,7 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.opends.messages.Message;
-import org.opends.server.api.plugin.IntermediateResponsePluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.PersistentSearch;
 import org.opends.server.core.PluginConfigManager;
@@ -537,18 +537,18 @@
     // message.
     PluginConfigManager pluginConfigManager =
          DirectoryServer.getPluginConfigManager();
-    IntermediateResponsePluginResult pluginResult =
+    PluginResult.IntermediateResponse pluginResult =
          pluginConfigManager.invokeIntermediateResponsePlugins(
                                   intermediateResponse);
 
     boolean continueProcessing = true;
-    if (pluginResult.sendIntermediateResponse())
+    if (pluginResult.sendResponse())
     {
       continueProcessing =
            sendIntermediateResponseMessage(intermediateResponse);
     }
 
-    return (continueProcessing && pluginResult.continueOperation());
+    return (continueProcessing && pluginResult.continueProcessing());
   }
 
 
diff --git a/opends/src/server/org/opends/server/api/SynchronizationProvider.java b/opends/src/server/org/opends/server/api/SynchronizationProvider.java
index abcc576..d12da31 100644
--- a/opends/src/server/org/opends/server/api/SynchronizationProvider.java
+++ b/opends/src/server/org/opends/server/api/SynchronizationProvider.java
@@ -162,7 +162,7 @@
          throws DirectoryException
   {
     // No processing is required by default.
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
 
@@ -232,7 +232,7 @@
          throws DirectoryException
   {
     // No processing is required by default.
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
 
@@ -302,7 +302,7 @@
          throws DirectoryException
   {
     // No processing is required by default.
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
 
@@ -372,7 +372,7 @@
          throws DirectoryException
   {
     // No processing is required by default.
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
 
diff --git a/opends/src/server/org/opends/server/api/plugin/DirectoryServerPlugin.java b/opends/src/server/org/opends/server/api/plugin/DirectoryServerPlugin.java
index 3f61546..4ce5818 100644
--- a/opends/src/server/org/opends/server/api/plugin/DirectoryServerPlugin.java
+++ b/opends/src/server/org/opends/server/api/plugin/DirectoryServerPlugin.java
@@ -35,16 +35,7 @@
 import org.opends.server.admin.std.server.PluginCfg;
 import org.opends.server.api.ClientConnection;
 import org.opends.server.config.ConfigException;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.IntermediateResponse;
-import org.opends.server.types.LDIFImportConfig;
-import org.opends.server.types.LDIFExportConfig;
-import org.opends.server.types.Modification;
-import org.opends.server.types.SearchResultEntry;
-import org.opends.server.types.SearchResultReference;
+import org.opends.server.types.*;
 import org.opends.server.types.operation.*;
 
 import static org.opends.messages.PluginMessages.*;
@@ -247,7 +238,7 @@
    *
    * @return  The result of the startup plugin processing.
    */
-  public StartupPluginResult doStartup()
+  public PluginResult.Startup doStartup()
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.get(
         String.valueOf(pluginDN), PluginType.STARTUP.getName());
@@ -285,7 +276,7 @@
    *
    * @return  The result of the plugin processing.
    */
-  public PostConnectPluginResult doPostConnect(ClientConnection
+  public PluginResult.PostConnect doPostConnect(ClientConnection
                                                     clientConnection)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.get(
@@ -309,7 +300,7 @@
    *
    * @return  The result of the plugin processing.
    */
-  public PostDisconnectPluginResult
+  public PluginResult.PostDisconnect
               doPostDisconnect(ClientConnection clientConnection,
                                DisconnectReason disconnectReason,
                                Message message)
@@ -334,8 +325,8 @@
    *
    * @return  The result of the plugin processing.
    */
-  public LDIFPluginResult doLDIFImport(LDIFImportConfig importConfig,
-                                       Entry entry)
+  public PluginResult.ImportLDIF
+    doLDIFImport(LDIFImportConfig importConfig, Entry entry)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.get(
         String.valueOf(pluginDN), PluginType.LDIF_IMPORT.getName());
@@ -354,8 +345,8 @@
    *
    * @return  The result of the plugin processing.
    */
-  public LDIFPluginResult doLDIFExport(LDIFExportConfig exportConfig,
-                                       Entry entry)
+  public PluginResult.ImportLDIF
+    doLDIFExport(LDIFExportConfig exportConfig, Entry entry)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.get(
         String.valueOf(pluginDN), PluginType.LDIF_EXPORT.getName());
@@ -373,7 +364,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseAbandonOperation abandonOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -394,7 +385,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationAbandonOperation abandonOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -412,10 +403,13 @@
    * @param  addOperation  The add operation that has been requested.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseAddOperation addOperation)
-  {
+       throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.get(
         String.valueOf(pluginDN), PluginType.PRE_PARSE_ADD.getName());
     throw new UnsupportedOperationException(message.toString());
@@ -433,10 +427,13 @@
    * @param  addOperation  The add operation to be processed.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationAddOperation addOperation)
-  {
+      throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_OPERATION_ADD.getName());
@@ -456,7 +453,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationAddOperation addOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -478,7 +475,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseAddOperation addOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -517,7 +514,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseBindOperation bindOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -537,7 +534,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationBindOperation bindOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -559,7 +556,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationBindOperation bindOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -581,7 +578,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseBindOperation bindOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -600,10 +597,13 @@
    *                           requested.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseCompareOperation compareOperation)
-  {
+       throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_PARSE_COMPARE.getName());
@@ -620,10 +620,13 @@
    * @param  compareOperation  The compare operation to be processed.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationCompareOperation compareOperation)
-  {
+      throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_OPERATION_COMPARE.getName());
@@ -643,7 +646,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationCompareOperation compareOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -665,7 +668,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseCompareOperation compareOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -684,10 +687,13 @@
    *                          requested.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseDeleteOperation deleteOperation)
-  {
+       throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_PARSE_DELETE.getName());
@@ -706,10 +712,13 @@
    * @param  deleteOperation  The delete operation to be processed.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationDeleteOperation deleteOperation)
-  {
+      throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_OPERATION_DELETE.getName());
@@ -729,7 +738,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationDeleteOperation deleteOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -751,7 +760,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseDeleteOperation deleteOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -789,10 +798,13 @@
    *                            requested.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseExtendedOperation extendedOperation)
-  {
+       throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_PARSE_EXTENDED.getName());
@@ -810,10 +822,13 @@
    *                            processed.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationExtendedOperation extendedOperation)
-  {
+      throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_OPERATION_EXTENDED.getName());
@@ -834,7 +849,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationExtendedOperation
                             extendedOperation)
   {
@@ -857,7 +872,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseExtendedOperation extendedOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -876,10 +891,13 @@
    *                          requested.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseModifyOperation modifyOperation)
-  {
+       throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_PARSE_MODIFY.getName());
@@ -898,10 +916,13 @@
    * @param  modifyOperation  The modify operation to be processed.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationModifyOperation modifyOperation)
-  {
+      throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_OPERATION_MODIFY.getName());
@@ -921,7 +942,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationModifyOperation modifyOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -943,7 +964,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseModifyOperation modifyOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -981,10 +1002,13 @@
    *                            requested.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseModifyDNOperation modifyDNOperation)
-  {
+       throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_PARSE_MODIFY_DN.getName());
@@ -1004,10 +1028,13 @@
    *                            processed.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationModifyDNOperation modifyDNOperation)
-  {
+      throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_OPERATION_MODIFY_DN.getName());
@@ -1042,7 +1069,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public SubordinateModifyDNPluginResult
+  public PluginResult.SubordinateModifyDN
        processSubordinateModifyDN(SubordinateModifyDNOperation
                                        modifyDNOperation,
                                   Entry oldEntry, Entry newEntry,
@@ -1067,7 +1094,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationModifyDNOperation
                             modifyDNOperation)
   {
@@ -1090,7 +1117,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseModifyDNOperation modifyDNOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -1129,10 +1156,13 @@
    *                          requested.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseSearchOperation searchOperation)
-  {
+       throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_PARSE_SEARCH.getName());
@@ -1149,10 +1179,13 @@
    * @param  searchOperation  The search operation to be processed.
    *
    * @return  Information about the result of the plugin processing.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationSearchOperation searchOperation)
-  {
+      throws CanceledOperationException {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
         get(String.valueOf(pluginDN),
             PluginType.PRE_OPERATION_SEARCH.getName());
@@ -1177,7 +1210,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public SearchEntryPluginResult
+  public PluginResult.IntermediateResponse
        processSearchEntry(SearchEntrySearchOperation searchOperation,
                           SearchResultEntry searchEntry)
   {
@@ -1201,7 +1234,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public SearchReferencePluginResult
+  public PluginResult.IntermediateResponse
        processSearchReference(SearchReferenceSearchOperation
                                    searchOperation,
                               SearchResultReference searchReference)
@@ -1225,7 +1258,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationSearchOperation searchOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -1247,7 +1280,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseSearchOperation searchOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -1267,7 +1300,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseUnbindOperation unbindOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -1288,7 +1321,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationUnbindOperation unbindOperation)
   {
     Message message = ERR_PLUGIN_TYPE_NOT_SUPPORTED.
@@ -1308,7 +1341,7 @@
    *
    * @return  Information about the result of the plugin processing.
    */
-  public IntermediateResponsePluginResult
+  public PluginResult.IntermediateResponse
               processIntermediateResponse(
                    IntermediateResponse intermediateResponse)
   {
diff --git a/opends/src/server/org/opends/server/api/plugin/IntermediateResponsePluginResult.java b/opends/src/server/org/opends/server/api/plugin/IntermediateResponsePluginResult.java
deleted file mode 100644
index 5c436c5..0000000
--- a/opends/src/server/org/opends/server/api/plugin/IntermediateResponsePluginResult.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing by an intermediate response plugin.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class IntermediateResponsePluginResult
-{
-  /**
-   * An intermediate response plugin result instance that indicates
-   * all processing was successful.
-   */
-  public static final IntermediateResponsePluginResult SUCCESS =
-       new IntermediateResponsePluginResult();
-
-
-
-  // Indicates whether any further intermediate response plugins
-  // should be invoked for this operation.
-  private final boolean continuePluginProcessing;
-
-  // Indicates whether processing should continue for the associated
-  // operation.
-  private final boolean continueOperation;
-
-  // Indicates whether the intermediate response plugin terminated the
-  // client connection.
-  private final boolean connectionTerminated;
-
-  // Indicates whether the associated intermediate response message
-  // should be sent to the client.
-  private final boolean sendIntermediateResponse;
-
-
-
-  /**
-   * Creates a new intermediate response plugin result with the
-   * default settings.  In this case, it will indicate that the
-   * connection has not been terminated, that further plugin
-   * processing should continue, that the intermediate response should
-   * be returned to the client, and that processing on the associated
-   * operation should continue.
-   */
-  private IntermediateResponsePluginResult()
-  {
-    this(false, true, true, true);
-  }
-
-
-
-  /**
-   * Creates a new intermediate response plugin result with the
-   * provided information.
-   *
-   * @param  connectionTerminated      Indicates whether the
-   *                                   intermediate response plugin
-   *                                   terminated the client
-   *                                   connection.
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   intermediate response plugins
-   *                                   should be invoked for this
-   *                                   operation.
-   * @param  sendIntermediateResponse  Indicates whether the
-   *                                   intermediate response message
-   *                                   should be sent to the client.
-   * @param  continueOperation         Indicates whether the server
-   *                                   should continue processing on
-   *                                   the associated operation.
-   */
-  public IntermediateResponsePluginResult(
-              boolean connectionTerminated,
-              boolean continuePluginProcessing,
-              boolean sendIntermediateResponse,
-              boolean continueOperation)
-  {
-    this.connectionTerminated     = connectionTerminated;
-    this.continuePluginProcessing = continuePluginProcessing;
-    this.sendIntermediateResponse = sendIntermediateResponse;
-    this.continueOperation        = continueOperation;
-  }
-
-
-
-  /**
-   * Indicates whether the intermediate response plugin terminated the
-   * client connection.
-   *
-   * @return  {@code true} if the intermediate response plugin
-   *          terminated the client connection, or {@code false} if
-   *          not.
-   */
-  public boolean connectionTerminated()
-  {
-    return connectionTerminated;
-  }
-
-
-
-  /**
-   * Indicates whether any further intermediate response plugins
-   * should be invoked for this operation.
-   *
-   * @return  {@code true} if any further intermediate response
-   *          plugins should be invoked for this operation, or
-   *          {@code false} if not.
-   */
-  public boolean continuePluginProcessing()
-  {
-    return continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the associated intermediate response message
-   * should be sent to the client.
-   *
-   * @return  {@code true} if the associated intermediate response
-   *          message should be sent to the client, or {@code false}
-   *          if not.
-   */
-  public boolean sendIntermediateResponse()
-  {
-    return sendIntermediateResponse;
-  }
-
-
-
-  /**
-   * Indicates whether processing should continue for the associated
-   * operation.
-   *
-   * @return  {@code true} if processing on the operation should
-   *          continue, or {@code false} if not.
-   */
-  public boolean continueOperation()
-  {
-    return continueOperation;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this intermediate response
-   * plugin result.
-   *
-   * @return  A string representation of this intermediate response
-   *          plugin result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this intermediate response
-   * plugin result to the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("IntermediateResponsePluginResult(" +
-                  "connectionTerminated=");
-    buffer.append(connectionTerminated);
-    buffer.append(", continuePluginProcessing=");
-    buffer.append(continuePluginProcessing);
-    buffer.append(", sendIntermediateResponse=");
-    buffer.append(sendIntermediateResponse);
-    buffer.append(", continueOperation=");
-    buffer.append(continueOperation);
-    buffer.append(")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/api/plugin/LDIFPluginResult.java b/opends/src/server/org/opends/server/api/plugin/LDIFPluginResult.java
deleted file mode 100644
index 4882396..0000000
--- a/opends/src/server/org/opends/server/api/plugin/LDIFPluginResult.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import org.opends.messages.Message;
-
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing an LDIF import or export plugin.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class LDIFPluginResult
-{
-  /**
-   * An LDIF plugin result instance that indicates all processing was
-   * successful.
-   */
-  public static final LDIFPluginResult SUCCESS =
-       new LDIFPluginResult();
-
-
-
-  // Indicates whether any further LDIF import/export plugins should
-  // be invoked for the associated entry.
-  private final boolean continuePluginProcessing;
-
-  // Indicates whether the associated entry should still be
-  // imported/exported.
-  private final boolean continueEntryProcessing;
-
-  // A message explaining why the entry was rejected.
-  private final Message rejectMessage;
-
-
-
-  /**
-   * Creates a new LDIF plugin result with the default settings.  In
-   * this case, it will indicate that all processing should continue
-   * as normal.
-   */
-  private LDIFPluginResult()
-  {
-    this(true, true, null);
-  }
-
-
-
-  /**
-   * Creates a new pre-operation plugin result with the provided
-   * information.
-   *
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   LDIF import/export plugins
-   *                                   should be invoked for the
-   *                                   associated entry.
-   * @param  continueEntryProcessing   Indicates whether the
-   *                                   associated entry should still
-   *                                   be imported/exported.
-   */
-  public LDIFPluginResult(boolean continuePluginProcessing,
-                          boolean continueEntryProcessing)
-  {
-    this(continuePluginProcessing, continueEntryProcessing, null);
-  }
-
-
-
-  /**
-   * Creates a new pre-operation plugin result with the provided
-   * information.
-   *
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   LDIF import/export plugins
-   *                                   should be invoked for the
-   *                                   associated entry.
-   * @param  continueEntryProcessing   Indicates whether the
-   *                                   associated entry should still
-   *                                   be imported/exported.
-   * @param  rejectMessage             A message explaining why the
-   *                                   entry should not be
-   *                                   imported/exported.
-   */
-  public LDIFPluginResult(boolean continuePluginProcessing,
-                          boolean continueEntryProcessing,
-                          Message rejectMessage)
-  {
-    this.continuePluginProcessing = continuePluginProcessing;
-    this.continueEntryProcessing  = continueEntryProcessing;
-    this.rejectMessage            = rejectMessage;
-  }
-
-
-
-  /**
-   * Indicates whether any further LDIF import/export plugins should
-   * be invoked for the associated entry.
-   *
-   * @return  {@code true} if any further LDIF import/export plugins
-   *          should be invoked for the associated entry, or
-   *          {@code false} if not.
-   */
-  public boolean continuePluginProcessing()
-  {
-    return continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the associated entry should still be
-   * imported/exported.
-   *
-   * @return  {@code true} if the associated entry should still be
-   *          imported/exported, or {@code false} if not.
-   */
-  public boolean continueEntryProcessing()
-  {
-    return continueEntryProcessing;
-  }
-
-
-
-  /**
-   * Retrieves a message explaining why the entry should not be
-   * imported/exported, if one was provided.
-   *
-   * @return  A message explaining why the entry should not be
-   *          imported/exported, or {@code null} if none was provided.
-   */
-  public Message getRejectMessage()
-  {
-    return rejectMessage;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this post-response plugin
-   * result.
-   *
-   * @return  A string representation of this post-response plugin
-   *          result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this post-response plugin
-   * result to the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("LDIFPluginResult(continuePluginProcessing=");
-    buffer.append(continuePluginProcessing);
-    buffer.append(", continueEntryProcessing=");
-    buffer.append(continueEntryProcessing);
-
-    if (rejectMessage != null)
-    {
-      buffer.append(", rejectMessage=\"");
-      buffer.append(rejectMessage);
-      buffer.append("\"");
-    }
-
-    buffer.append(")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/api/plugin/PluginResult.java b/opends/src/server/org/opends/server/api/plugin/PluginResult.java
new file mode 100644
index 0000000..8f16525
--- /dev/null
+++ b/opends/src/server/org/opends/server/api/plugin/PluginResult.java
@@ -0,0 +1,1477 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2006-2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.api.plugin;
+
+import org.opends.messages.Message;
+import org.opends.server.types.ResultCode;
+import org.opends.server.types.DN;
+import org.opends.server.types.DisconnectReason;
+
+import java.util.List;
+
+/**
+ * This class defines a data structure that holds information about
+ * the result of processing by a plugin.
+ */
+@org.opends.server.types.PublicAPI(
+    stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
+    mayInstantiate=true,
+    mayExtend=false,
+    mayInvoke=true)
+public final class PluginResult
+{
+  /**
+   * Defines a startup plugin result consisting of either continue
+   * skip further plugins, or stop startup with an error message.
+   */
+  public static final class Startup
+  {
+    // Whether to continue startup.
+    private final boolean continueProcessing;
+
+    // Whether to invoke the rest of the plugins.
+    private final boolean continuePluginProcessing;
+
+    // An message explaining why startup should stop.
+    private final Message errorMessage;
+
+    private static Startup DEFAULT_RESULT =
+        new Startup(true, true, null);
+
+    /**
+     * Construct a new startup plugin result.
+     *
+     * @param continueProcessing Whether to continue startup.
+     * @param continuePluginProcessing Whether to invoke the rest
+     * of the plugins.
+     * @param errorMessage An message explaining why startup should
+     * stop.
+     */
+    private Startup(boolean continueProcessing,
+                    boolean continuePluginProcessing,
+                    Message errorMessage)
+    {
+      this.continueProcessing = continueProcessing;
+      this.errorMessage = errorMessage;
+      this.continuePluginProcessing = continuePluginProcessing;
+    }
+
+    /**
+     * Defines a continue processing startup plugin result.
+     *
+     * @return a continue processing startup plugin result.
+     */
+    public static Startup continueStartup()
+    {
+      return DEFAULT_RESULT;
+    }
+
+    /**
+     * Defines a skip further plugin processing startup plugin result.
+     *
+     * @return  a skip further plugin processing startup plugin
+     * result.
+     */
+    public static Startup skipFurtherPluginProcesssing()
+    {
+      return new Startup(true, false, null);
+    }
+
+    /**
+     * Defines a new stop processing startup plugin result.
+     *
+     * @param errorMessage An message explaining why processing
+     * should stop for the given entry.
+     *
+     * @return a new stop processing startup plugin result.
+     */
+    public static Startup stopStartup(Message errorMessage)
+    {
+      return new Startup(false, false, errorMessage);
+    }
+
+    /**
+     * Whether to continue startup.
+     *
+     * @return <code>true</code> if processing should continue
+     * or <code>false</code> otherwise.
+     */
+    public boolean continueProcessing()
+    {
+      return continueProcessing;
+    }
+
+    /**
+     * Whether to invoke the rest of the plugins.
+     *
+     * @return <code>true</code> if the rest of the plugins should
+     * be invoked for <code>false</code> to skip the rest of the
+     * plugins.
+     */
+    public boolean continuePluginProcessing()
+    {
+      return continuePluginProcessing;
+    }
+
+    /**
+     * Retrieves the error message if <code>continueProcessing</code>
+     * returned <code>false</code>.
+     *
+     * @return An error message explaining why processing should
+     * stop or <code>null</code> if none is provided.
+     */
+    public Message getErrorMessage()
+    {
+      return errorMessage;
+    }
+  }
+
+  /**
+   * Defines a pre parse plugin result for core server operation
+   * processing consisting of either continue, skip further
+   * plugins, or stop operation processing with a result code,
+   * matched DN, referral URLs, and error message.
+   */
+  public static final class PreParse
+  {
+    // Whether to continue operation processing.
+    private final boolean continueProcessing;
+
+    // Whether to invoke the rest of the plugins.
+    private final boolean continuePluginProcessing;
+
+    // An message explaining why processing should stop.
+    private final Message errorMessage;
+
+    // The matched DN for this result.
+    private final DN matchedDN;
+
+    // The set of referral URLs for this result.
+    private final List<String> referralURLs;
+
+    // The result code for this result.
+    private final ResultCode resultCode;
+
+    private static PreParse DEFAULT_RESULT =
+        new PreParse(true, true, null, null, null, null);
+
+    /**
+     * Construct a new pre parse plugin result.
+     *
+     * @param continueProcessing Whether to continue startup.
+     * @param continuePluginProcessing Whether to invoke the rest
+     * of the plugins.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param resultCode The result code for this result.
+     * @param matchedDN The matched DN for this result.
+     * @param referralURLs The set of referral URLs for this result.
+     * stop.
+     */
+    private PreParse (boolean continueProcessing,
+                      boolean continuePluginProcessing,
+                      Message errorMessage,
+                      ResultCode resultCode, DN matchedDN,
+                      List<String> referralURLs)
+    {
+      this.continueProcessing = continueProcessing;
+      this.errorMessage = errorMessage;
+      this.continuePluginProcessing = continuePluginProcessing;
+      this.resultCode = resultCode;
+      this.matchedDN = matchedDN;
+      this.referralURLs = referralURLs;
+    }
+
+    /**
+     * Defines a continue processing pre parse plugin result.
+     *
+     * @return a continue processing pre parse plugin result.
+     */
+    public static PreParse continueOperationProcessing()
+    {
+      return DEFAULT_RESULT;
+    }
+
+    /**
+     * Defines a skip further plugin processing pre parse plugin
+     * result.
+     *
+     * @return  a skip further plugin processing pre parse plugin
+     * result.
+     */
+    public static PreParse skipFurtherPluginProcesssing()
+    {
+      return new PreParse(true, false, null, null, null, null);
+    }
+
+    /**
+     * Defines a new stop processing pre parse plugin result.
+     *
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param matchedDN The matched DN for this result.
+     * @param referralURLs The set of referral URLs for this result.
+     *
+     * @return a new stop processing pre parse plugin result.
+     */
+    public static PreParse stopProcessing(ResultCode resultCode,
+                                          Message errorMessage,
+                                          DN matchedDN,
+                                          List<String> referralURLs)
+    {
+      return new PreParse(false, false, errorMessage, resultCode,
+          matchedDN, referralURLs);
+    }
+
+    /**
+     * Contrust a new stop processing pre parse plugin result.
+     *
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     *
+     * @return a new stop processing pre parse plugin result.
+     */
+    public static PreParse stopProcessing(ResultCode resultCode,
+                                          Message errorMessage)
+    {
+      return new PreParse(false, false, errorMessage, resultCode,
+          null, null);
+    }
+
+    /**
+     * Whether to continue operation processing.
+     *
+     * @return <code>true</code> if processing should continue
+     * or <code>false</code> otherwise.
+     */
+    public boolean continueProcessing()
+    {
+      return continueProcessing;
+    }
+
+    /**
+     * Whether to invoke the rest of the plugins.
+     *
+     * @return <code>true</code> if the rest of the plugins should
+     * be invoked for <code>false</code> to skip the rest of the
+     * plugins.
+     */
+    public boolean continuePluginProcessing()
+    {
+      return continuePluginProcessing;
+    }
+
+    /**
+     * Retrieves the error message if <code>continueProcessing</code>
+     * returned <code>false</code>.
+     *
+     * @return An error message explaining why processing should
+     * stop or <code>null</code> if none is provided.
+     */
+    public Message getErrorMessage()
+    {
+      return errorMessage;
+    }
+
+    /**
+     * Retrieves the result code for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the result code for the operation or <code>null</code>
+     * if none is provided.
+     */
+    public ResultCode getResultCode()
+    {
+      return resultCode;
+    }
+
+    /**
+     * Retrieves the matched DN for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the matched DN for the operation or <code>null</code>
+     * if none is provided.
+     */
+    public DN getMatchedDN()
+    {
+      return matchedDN;
+    }
+
+    /**
+     * Retrieves the referral URLs for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the refferal URLs for the operation or
+     * <code>null</code> if none is provided.
+     */
+    public List<String> getReferralURLs()
+    {
+      return referralURLs;
+    }
+  }
+
+  /**
+   * Defines a pre operation plugin result for core server operation
+   * processing consisting of either continue, skip further
+   * plugins, or stop operation processing with a result code,
+   * matched DN, referral URLs, and error message.
+   */
+  public static final class PreOperation
+  {
+    // Whether to continue operation processing.
+    private final boolean continueProcessing;
+
+    // Whether to invoke the rest of the plugins.
+    private final boolean continuePluginProcessing;
+
+    // An message explaining why processing should stop.
+    private final Message errorMessage;
+
+    // The matched DN for this result.
+    private final DN matchedDN;
+
+    // The set of referral URLs for this result.
+    private final List<String> referralURLs;
+
+    // The result code for this result.
+    private final ResultCode resultCode;
+
+    private static PreOperation DEFAULT_RESULT =
+        new PreOperation(true, true, null, null, null, null);
+
+    /**
+     * Construct a new pre operation plugin result.
+     *
+     * @param continueProcessing Whether to continue startup.
+     * @param continuePluginProcessing Whether to invoke the rest
+     * of the plugins.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param resultCode The result code for this result.
+     * @param matchedDN The matched DN for this result.
+     * @param referralURLs The set of referral URLs for this result.
+     * stop.
+     */
+    private PreOperation (boolean continueProcessing,
+                          boolean continuePluginProcessing,
+                          Message errorMessage,
+                          ResultCode resultCode, DN matchedDN,
+                          List<String> referralURLs)
+    {
+      this.continueProcessing = continueProcessing;
+      this.errorMessage = errorMessage;
+      this.continuePluginProcessing = continuePluginProcessing;
+      this.resultCode = resultCode;
+      this.matchedDN = matchedDN;
+      this.referralURLs = referralURLs;
+    }
+
+    /**
+     * Defines a continue processing pre operation plugin result.
+     *
+     * @return a continue processing pre operation plugin result.
+     */
+    public static PreOperation continueOperationProcessing()
+    {
+      return DEFAULT_RESULT;
+    }
+
+    /**
+     * Defines a skip further plugin processing pre operation plugin
+     * result.
+     *
+     * @return  a skip further plugin processing pre operation plugin
+     * result.
+     */
+    public static PreOperation skipFurtherPluginProcesssing()
+    {
+      return new PreOperation(true, false, null, null, null, null);
+    }
+
+    /**
+     * Defines a new stop processing pre operation plugin result.
+     *
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param matchedDN The matched DN for this result.
+     * @param referralURLs The set of referral URLs for this result.
+     *
+     * @return a new stop processing pre operation plugin result.
+     */
+    public static PreOperation stopProcessing(
+        ResultCode resultCode, Message errorMessage, DN matchedDN,
+        List<String> referralURLs)
+    {
+      return new PreOperation(false, false, errorMessage, resultCode,
+          matchedDN, referralURLs);
+    }
+
+    /**
+     * Contrust a new stop processing pre operation plugin result.
+     *
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     *
+     * @return a new stop processing pre operation plugin result.
+     */
+    public static PreOperation stopProcessing(ResultCode resultCode,
+                                              Message errorMessage)
+    {
+      return new PreOperation(false, false, errorMessage, resultCode,
+          null, null);
+    }
+
+    /**
+     * Whether to continue operation processing.
+     *
+     * @return <code>true</code> if processing should continue
+     * or <code>false</code> otherwise.
+     */
+    public boolean continueProcessing()
+    {
+      return continueProcessing;
+    }
+
+    /**
+     * Whether to invoke the rest of the plugins.
+     *
+     * @return <code>true</code> if the rest of the plugins should
+     * be invoked for <code>false</code> to skip the rest of the
+     * plugins.
+     */
+    public boolean continuePluginProcessing()
+    {
+      return continuePluginProcessing;
+    }
+
+    /**
+     * Retrieves the error message if <code>continueProcessing</code>
+     * returned <code>false</code>.
+     *
+     * @return An error message explaining why processing should
+     * stop or <code>null</code> if none is provided.
+     */
+    public Message getErrorMessage()
+    {
+      return errorMessage;
+    }
+
+    /**
+     * Retrieves the result code for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the result code for the operation or <code>null</code>
+     * if none is provided.
+     */
+    public ResultCode getResultCode()
+    {
+      return resultCode;
+    }
+
+    /**
+     * Retrieves the matched DN for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the matched DN for the operation or <code>null</code>
+     * if none is provided.
+     */
+    public DN getMatchedDN()
+    {
+      return matchedDN;
+    }
+
+    /**
+     * Retrieves the referral URLs for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the refferal URLs for the operation or
+     * <code>null</code> if none is provided.
+     */
+    public List<String> getReferralURLs()
+    {
+      return referralURLs;
+    }
+  }
+
+  /**
+   * Defines a post operation plugin result for core server operation
+   * processing consisting of either continue, skip further
+   * plugins, or stop operation processing with a result code,
+   * matched DN, referral URLs, and error message.
+   */
+  public static final class PostOperation
+  {
+    // Whether to continue operation processing.
+    private final boolean continueProcessing;
+
+    // An message explaining why processing should stop.
+    private final Message errorMessage;
+
+    // The matched DN for this result.
+    private final DN matchedDN;
+
+    // The set of referral URLs for this result.
+    private final List<String> referralURLs;
+
+    // The result code for this result.
+    private final ResultCode resultCode;
+
+    private static PostOperation DEFAULT_RESULT =
+        new PostOperation(true, null, null, null, null);
+
+    /**
+     * Constructs a new post operation plugin result.
+     *
+     * @param continueProcessing Whether to continue startup.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param resultCode The result code for this result.
+     * @param matchedDN The matched DN for this result.
+     * @param referralURLs The set of referral URLs for this result.
+     */
+    private PostOperation(boolean continueProcessing,
+                          Message errorMessage,
+                          ResultCode resultCode, DN matchedDN,
+                          List<String> referralURLs)
+    {
+      this.continueProcessing = continueProcessing;
+      this.errorMessage = errorMessage;
+      this.resultCode = resultCode;
+      this.matchedDN = matchedDN;
+      this.referralURLs = referralURLs;
+    }
+
+    /**
+     * Defines a continue processing post operation plugin result.
+     *
+     * @return a continue processing post operation plugin result.
+     */
+    public static PostOperation continueOperationProcessing()
+    {
+      return DEFAULT_RESULT;
+    }
+
+    /**
+     * Defines a new stop processing post operation plugin result.
+     *
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param matchedDN The matched DN for this result.
+     * @param referralURLs The set of referral URLs for this result.
+     *
+     * @return a new stop processing post operation plugin result.
+     */
+    public static PostOperation stopProcessing(
+        ResultCode resultCode, Message errorMessage, DN matchedDN,
+        List<String> referralURLs)
+    {
+      return new PostOperation(false, errorMessage, resultCode,
+          matchedDN, referralURLs);
+    }
+
+    /**
+     * Contrust a new stop processing post operation plugin result.
+     *
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     *
+     * @return a new stop processing post operation plugin result.
+     */
+    public static PostOperation stopProcessing(ResultCode resultCode,
+                                               Message errorMessage)
+    {
+      return new PostOperation(false, errorMessage, resultCode, null,
+          null);
+    }
+
+    /**
+     * Whether to continue operation processing.
+     *
+     * @return <code>true</code> if processing should continue
+     * or <code>false</code> otherwise.
+     */
+    public boolean continueProcessing()
+    {
+      return continueProcessing;
+    }
+
+    /**
+     * Retrieves the error message if <code>continueProcessing</code>
+     * returned <code>false</code>.
+     *
+     * @return An error message explaining why processing should
+     * stop or <code>null</code> if none is provided.
+     */
+    public Message getErrorMessage()
+    {
+      return errorMessage;
+    }
+
+    /**
+     * Retrieves the result code for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the result code for the operation or <code>null</code>
+     * if none is provided.
+     */
+    public ResultCode getResultCode()
+    {
+      return resultCode;
+    }
+
+    /**
+     * Retrieves the matched DN for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the matched DN for the operation or <code>null</code>
+     * if none is provided.
+     */
+    public DN getMatchedDN()
+    {
+      return matchedDN;
+    }
+
+    /**
+     * Retrieves the referral URLs for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the refferal URLs for the operation or
+     * <code>null</code> if none is provided.
+     */
+    public List<String> getReferralURLs()
+    {
+      return referralURLs;
+    }
+  }
+
+
+  /**
+   * Defines a post response plugin result for core server operation
+   * processing consisting of either continue or skip further
+   * plugins.
+   */
+  public static final class PostResponse
+  {
+    // Whether to invoke the rest of the plugins.
+    private final boolean continuePluginProcessing;
+
+    private static PostResponse DEFAULT_RESULT =
+        new PostResponse(true);
+
+    /**
+     * Constructs a new post response plugin result.
+     *
+     * @param continuePluginProcessing Whether to invoke the rest
+     * of the plugins.
+     */
+    private PostResponse (boolean continuePluginProcessing)
+    {
+      this.continuePluginProcessing = continuePluginProcessing;
+    }
+
+    /**
+     * Defines a continue processing post response plugin result.
+     *
+     * @return a continue processing post response plugin result.
+     */
+    public static PostResponse continueOperationProcessing()
+    {
+      return DEFAULT_RESULT;
+    }
+
+    /**
+     * Defines a skip further plugin processing post response plugin
+     *  result.
+     *
+     * @return  a skip further plugin processing post response plugin
+     *  result.
+     */
+    public static PostResponse skipFurtherPluginProcesssing()
+    {
+      return new PostResponse(false);
+    }
+
+    /**
+     * Whether to invoke the rest of the plugins.
+     *
+     * @return <code>true</code> if the rest of the plugins should
+     * be invoked for <code>false</code> to skip the rest of the
+     * plugins.
+     */
+    public boolean continuePluginProcessing()
+    {
+      return continuePluginProcessing;
+    }
+  }
+
+  /**
+   * Defines a LDIF plugin result for import from LDIF
+   * processing consisting of either continue, skip further
+   * plugins, or stop processing with an error message.
+   */
+  public static final class ImportLDIF
+  {
+    // Whether to continue operation processing.
+    private final boolean continueProcessing;
+
+    // Whether to invoke the rest of the plugins.
+    private final boolean continuePluginProcessing;
+
+    // An message explaining why processing should stop.
+    private final Message errorMessage;
+
+    private static ImportLDIF DEFAULT_RESULT =
+        new ImportLDIF(true, true, null);
+
+    /**
+     * Construct a new import LDIF plugin result.
+     *
+     * @param continueProcessing Whether to continue startup.
+     * @param continuePluginProcessing Whether to invoke the rest
+     * of the plugins.
+     * @param errorMessage An message explaining why startup should
+     * stop.
+     */
+    private ImportLDIF(boolean continueProcessing,
+                       boolean continuePluginProcessing,
+                       Message errorMessage)
+    {
+      this.continueProcessing = continueProcessing;
+      this.errorMessage = errorMessage;
+      this.continuePluginProcessing = continuePluginProcessing;
+    }
+
+    /**
+     * Defines a continue processing LDIF import plugin result.
+     *
+     * @return a continue processing LDIF import plugin result.
+     */
+    public static ImportLDIF continueEntryProcessing()
+    {
+      return DEFAULT_RESULT;
+    }
+
+    /**
+     * Defines a skip further plugin processing LDIF import plugin
+     *  result.
+     *
+     * @return  a skip further plugin processing LDIF import plugin
+     *  result.
+     */
+    public static ImportLDIF skipFurtherPluginProcesssing()
+    {
+      return new ImportLDIF(true, false, null);
+    }
+
+    /**
+     * Defines a new stop processing LDIF import plugin result.
+     *
+     * @param errorMessage An message explaining why processing
+     * should stop for the given entry.
+     *
+     * @return a new stop processing LDIF import plugin result.
+     */
+    public static ImportLDIF stopEntryProcessing(Message errorMessage)
+    {
+      return new ImportLDIF(false, false, errorMessage);
+    }
+
+    /**
+     * Whether to continue operation processing.
+     *
+     * @return <code>true</code> if processing should continue
+     * or <code>false</code> otherwise.
+     */
+    public boolean continueProcessing()
+    {
+      return continueProcessing;
+    }
+
+    /**
+     * Whether to invoke the rest of the plugins.
+     *
+     * @return <code>true</code> if the rest of the plugins should
+     * be invoked for <code>false</code> to skip the rest of the
+     * plugins.
+     */
+    public boolean continuePluginProcessing()
+    {
+      return continuePluginProcessing;
+    }
+
+    /**
+     * Retrieves the error message if <code>continueProcessing</code>
+     * returned <code>false</code>.
+     *
+     * @return An error message explaining why processing should
+     * stop or <code>null</code> if none is provided.
+     */
+    public Message getErrorMessage()
+    {
+      return errorMessage;
+    }
+  }
+
+  /**
+   * Defines a subordinate modify DN plugin result for core server
+   * operation processing consisting of either continue, skip further
+   * plugins, or stop operation processing with a result code,
+   * matched DN, referral URLs, and error message.
+   */
+  public static final class SubordinateModifyDN
+  {
+    // Whether to continue operation processing.
+    private final boolean continueProcessing;
+
+    // Whether to invoke the rest of the plugins.
+    private final boolean continuePluginProcessing;
+
+    // An message explaining why processing should stop.
+    private final Message errorMessage;
+
+    // The matched DN for this result.
+    private final DN matchedDN;
+
+    // The set of referral URLs for this result.
+    private final List<String> referralURLs;
+
+    // The result code for this result.
+    private final ResultCode resultCode;
+
+    private static SubordinateModifyDN DEFAULT_RESULT =
+        new SubordinateModifyDN(true, true, null, null, null, null);
+
+    /**
+     * Construct a new subordinate modify DN plugin result.
+     *
+     * @param continueProcessing Whether to continue startup.
+     * @param continuePluginProcessing Whether to invoke the rest
+     * of the plugins.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param resultCode The result code for this result.
+     * @param matchedDN The matched DN for this result.
+     * @param referralURLs The set of referral URLs for this result.
+     * stop.
+     */
+    private SubordinateModifyDN(boolean continueProcessing,
+                                boolean continuePluginProcessing,
+                                Message errorMessage,
+                                ResultCode resultCode, DN matchedDN,
+                                List<String> referralURLs)
+    {
+      this.continueProcessing = continueProcessing;
+      this.errorMessage = errorMessage;
+      this.continuePluginProcessing = continuePluginProcessing;
+      this.resultCode = resultCode;
+      this.matchedDN = matchedDN;
+      this.referralURLs = referralURLs;
+    }
+
+    /**
+     * Defines a continue processing subordinate modify DN plugin
+     *  result.
+     *
+     * @return a continue processing subordinate modify DN plugin
+     *  result.
+     */
+    public static SubordinateModifyDN continueOperationProcessing()
+    {
+      return DEFAULT_RESULT;
+    }
+
+    /**
+     * Defines a skip further plugin processing subordinate modify DN
+     * plugin result.
+     *
+     * @return  a skip further plugin processing subordinate modify DN
+     * plugin result.
+     */
+    public static SubordinateModifyDN skipFurtherPluginProcesssing()
+    {
+      return new SubordinateModifyDN(true, false, null, null, null,
+          null);
+    }
+
+    /**
+     * Defines a new stop processing subordinate modify DN plugin
+     * result.
+     *
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param matchedDN The matched DN for this result.
+     * @param referralURLs The set of referral URLs for this result.
+     *
+     * @return a new stop processing subordinate modify DN plugin
+     * result.
+     */
+    public static SubordinateModifyDN stopProcessing(
+        ResultCode resultCode, Message errorMessage, DN matchedDN,
+        List<String> referralURLs)
+    {
+      return new SubordinateModifyDN(false, false, errorMessage,
+          resultCode, matchedDN, referralURLs);
+    }
+
+    /**
+     * Contrust a new stop processing subordinate modify DN plugin
+     * result.
+     *
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     *
+     * @return a new stop processing subordinate modify DN plugin
+     * result.
+     */
+    public static SubordinateModifyDN stopProcessing(
+        ResultCode resultCode, Message errorMessage)
+    {
+      return new SubordinateModifyDN(false, false, errorMessage,
+          resultCode, null, null);
+    }
+
+    /**
+     * Whether to continue operation processing.
+     *
+     * @return <code>true</code> if processing should continue
+     * or <code>false</code> otherwise.
+     */
+    public boolean continueProcessing()
+    {
+      return continueProcessing;
+    }
+
+    /**
+     * Whether to invoke the rest of the plugins.
+     *
+     * @return <code>true</code> if the rest of the plugins should
+     * be invoked for <code>false</code> to skip the rest of the
+     * plugins.
+     */
+    public boolean continuePluginProcessing()
+    {
+      return continuePluginProcessing;
+    }
+
+    /**
+     * Retrieves the error message if <code>continueProcessing</code>
+     * returned <code>false</code>.
+     *
+     * @return An error message explaining why processing should
+     * stop or <code>null</code> if none is provided.
+     */
+    public Message getErrorMessage()
+    {
+      return errorMessage;
+    }
+
+    /**
+     * Retrieves the result code for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the result code for the operation or <code>null</code>
+     * if none is provided.
+     */
+    public ResultCode getResultCode()
+    {
+      return resultCode;
+    }
+
+    /**
+     * Retrieves the matched DN for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the matched DN for the operation or <code>null</code>
+     * if none is provided.
+     */
+    public DN getMatchedDN()
+    {
+      return matchedDN;
+    }
+
+    /**
+     * Retrieves the referral URLs for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the refferal URLs for the operation or
+     * <code>null</code> if none is provided.
+     */
+    public List<String> getReferralURLs()
+    {
+      return referralURLs;
+    }
+  }
+
+  /**
+   * Defines an intermediate response plugin result for core server
+   *  operation processing consisting of either continue, skip further
+   * plugins, or stop operation processing with a result code,
+   * matched DN, referral URLs, and error message.
+   */
+  public static final class IntermediateResponse
+  {
+    // Whether to continue operation processing.
+    private final boolean continueProcessing;
+
+    // Whether to invoke the rest of the plugins.
+    private final boolean continuePluginProcessing;
+
+    // Whether to send the intermediate response to the client.
+    private final boolean sendResponse;
+
+    // An message explaining why processing should stop.
+    private final Message errorMessage;
+
+    // The matched DN for this result.
+    private final DN matchedDN;
+
+    // The set of referral URLs for this result.
+    private final List<String> referralURLs;
+
+    // The result code for this result.
+    private final ResultCode resultCode;
+
+    private static IntermediateResponse DEFAULT_RESULT =
+        new IntermediateResponse(true, true, true, null, null, null,
+            null);
+
+    /**
+     * Construct a new intermediate response plugin result.
+     *
+     * @param continueProcessing Whether to continue startup.
+     * @param continuePluginProcessing Whether to invoke the rest
+     * of the plugins.
+     * @param sendResponse Whether to send the intermediate response
+     * to the client.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param resultCode The result code for this result.
+     * @param matchedDN The matched DN for this result.
+     * @param referralURLs The set of referral URLs for this result.
+     * stop.
+     */
+    private IntermediateResponse(boolean continueProcessing,
+                                 boolean continuePluginProcessing,
+                                 boolean sendResponse,
+                                 Message errorMessage,
+                                 ResultCode resultCode, DN matchedDN,
+                                 List<String> referralURLs)
+    {
+      this.continueProcessing = continueProcessing;
+      this.errorMessage = errorMessage;
+      this.continuePluginProcessing = continuePluginProcessing;
+      this.resultCode = resultCode;
+      this.matchedDN = matchedDN;
+      this.referralURLs = referralURLs;
+      this.sendResponse = sendResponse;
+    }
+
+    /**
+     * Defines a continue processing intermediate response plugin
+     * result.
+     *
+     * @param sendResponse Whether to send the intermediate response
+     * to the client.
+     * @return a continue processing intermediate response plugin
+     * result.
+     */
+    public static IntermediateResponse
+    continueOperationProcessing(boolean sendResponse)
+    {
+      if(sendResponse)
+      {
+        return DEFAULT_RESULT;
+      }
+      else
+      {
+        return new IntermediateResponse(true, true, sendResponse,
+            null, null, null, null);
+      }
+    }
+
+    /**
+     * Defines a skip further plugin processing intermediate response
+     * plugin result.
+     *
+     * @param sendResponse Whether to send the intermediate response
+     * to the client.
+     *
+     * @return  a skip further plugin processing intermediate response
+     * plugin result.
+     */
+    public static IntermediateResponse
+    skipFurtherPluginProcesssing(boolean sendResponse)
+    {
+      return new IntermediateResponse(true, false, sendResponse,
+          null, null, null, null);
+    }
+
+    /**
+     * Defines a new stop processing intermediate response plugin
+     * result.
+     *
+     * @param sendResponse Whether to send the intermediate response
+     * to the client.
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param matchedDN The matched DN for this result.
+     * @param referralURLs The set of referral URLs for this result.
+     *
+     * @return a new stop processing intermediate response plugin
+     * result.
+     */
+    public static IntermediateResponse stopProcessing(
+        boolean sendResponse, ResultCode resultCode,
+        Message errorMessage, DN matchedDN, List<String> referralURLs)
+    {
+      return new IntermediateResponse(false, false, sendResponse,
+          errorMessage, resultCode, matchedDN, referralURLs);
+    }
+
+    /**
+     * Contrust a new stop processing intermediate response plugin
+     * result.
+     *
+     * @param sendResponse Whether to send the intermediate response
+     * to the client.
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     *
+     * @return a new stop processing intermediate response plugin
+     * result.
+     */
+    public static IntermediateResponse stopProcessing(
+        boolean sendResponse, ResultCode resultCode,
+        Message errorMessage)
+    {
+      return new IntermediateResponse(false, false, sendResponse,
+          errorMessage, resultCode, null, null);
+    }
+
+    /**
+     * Whether to continue operation processing.
+     *
+     * @return <code>true</code> if processing should continue
+     * or <code>false</code> otherwise.
+     */
+    public boolean continueProcessing()
+    {
+      return continueProcessing;
+    }
+
+    /**
+     * Whether to invoke the rest of the plugins.
+     *
+     * @return <code>true</code> if the rest of the plugins should
+     * be invoked for <code>false</code> to skip the rest of the
+     * plugins.
+     */
+    public boolean continuePluginProcessing()
+    {
+      return continuePluginProcessing;
+    }
+
+    /**
+     * Whether to send the intermediate response to the client.
+     *
+     * @return <code>true</code> if the intermediate response should
+     * be sent to the client or <code>false</code> otherwise.
+     */
+    public boolean sendResponse()
+    {
+      return sendResponse;
+    }
+
+    /**
+     * Retrieves the error message if <code>continueProcessing</code>
+     * returned <code>false</code>.
+     *
+     * @return An error message explaining why processing should
+     * stop or <code>null</code> if none is provided.
+     */
+    public Message getErrorMessage()
+    {
+      return errorMessage;
+    }
+
+    /**
+     * Retrieves the result code for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the result code for the operation or <code>null</code>
+     * if none is provided.
+     */
+    public ResultCode getResultCode()
+    {
+      return resultCode;
+    }
+
+    /**
+     * Retrieves the matched DN for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the matched DN for the operation or <code>null</code>
+     * if none is provided.
+     */
+    public DN getMatchedDN()
+    {
+      return matchedDN;
+    }
+
+    /**
+     * Retrieves the referral URLs for the operation
+     * if <code>continueProcessing</code> returned <code>false</code>.
+     *
+     * @return the refferal URLs for the operation or
+     * <code>null</code> if none is provided.
+     */
+    public List<String> getReferralURLs()
+    {
+      return referralURLs;
+    }
+  }
+
+  /**
+   * Defines a post connect plugin result for client connection
+   * processing consisting of either continue, skip further
+   * plugins, or stop.
+   */
+  public static final class PostConnect
+  {
+    // Whether to continue connection processing.
+    private final boolean continueProcessing;
+
+    // Whether to invoke the rest of the plugins.
+    private final boolean continuePluginProcessing;
+
+    // An message explaining why processing should stop.
+    private final Message errorMessage;
+
+    // The disconnect reason that provides the generic cause for the
+    // disconnect.
+    private final DisconnectReason disconnectReason;
+
+    // Whether to send a disconnect notification to the client.
+    private final boolean sendDisconnectNotification;
+
+    private static PostConnect DEFAULT_RESULT =
+        new PostConnect(true, true, null, null, false);
+
+    /**
+     * Construct a new post connect plugin result.
+     *
+     * @param continueProcessing Whether to continue startup.
+     * @param continuePluginProcessing Whether to invoke the rest
+     * of the plugins.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param disconnectReason The generic cause for the disconnect.
+     * @param sendDisconnectNotification Whether to send a disconnect
+     * notification to the client.
+     */
+    private PostConnect(boolean continueProcessing,
+                        boolean continuePluginProcessing,
+                        Message errorMessage,
+                        DisconnectReason disconnectReason,
+                        boolean sendDisconnectNotification)
+    {
+      this.continueProcessing = continueProcessing;
+      this.errorMessage = errorMessage;
+      this.continuePluginProcessing = continuePluginProcessing;
+      this.disconnectReason = disconnectReason;
+      this.sendDisconnectNotification = sendDisconnectNotification;
+    }
+
+    /**
+     * Defines a continue processing post connect plugin result.
+     *
+     * @return a continue processing post connect plugin result.
+     */
+    public static PostConnect continueConnectProcessing()
+    {
+      return DEFAULT_RESULT;
+    }
+
+    /**
+     * Defines a skip further plugin processing post connect plugin
+     * result.
+     *
+     * @return  a skip further plugin processing post connect plugin
+     * result.
+     */
+    public static PostConnect skipFurtherPluginProcesssing()
+    {
+      return new PostConnect(true, false, null, null, false);
+    }
+
+    /**
+     * Defines a new stop processing post connect plugin result.
+     *
+     * @param disconnectReason The generic cause for the disconnect.
+     * @param sendDisconnectNotification Whether to send a disconnect
+     * notification to the client.
+     * @param errorMessage An message explaining why processing
+     * should stop for the given entry.
+     *
+     * @return a new stop processing post connect plugin result.
+     */
+    public static PostConnect disconnectClient(
+        DisconnectReason disconnectReason,
+        boolean sendDisconnectNotification, Message errorMessage)
+    {
+      return new PostConnect(false, false, errorMessage,
+          disconnectReason, sendDisconnectNotification);
+    }
+
+    /**
+     * Whether to continue operation processing.
+     *
+     * @return <code>true</code> if processing should continue
+     * or <code>false</code> otherwise.
+     */
+    public boolean continueProcessing()
+    {
+      return continueProcessing;
+    }
+
+    /**
+     * Whether to invoke the rest of the plugins.
+     *
+     * @return <code>true</code> if the rest of the plugins should
+     * be invoked for <code>false</code> to skip the rest of the
+     * plugins.
+     */
+    public boolean continuePluginProcessing()
+    {
+      return continuePluginProcessing;
+    }
+
+    /**
+     * Retrieves the error message if <code>continueProcessing</code>
+     * returned <code>false</code>.
+     *
+     * @return An error message explaining why processing should
+     * stop or <code>null</code> if none is provided.
+     */
+    public Message getErrorMessage()
+    {
+      return errorMessage;
+    }
+
+    /**
+     * The disconnect reason that provides the generic cause for the
+     * disconnect.
+     *
+     * @return the generic cause for the disconnect.
+     */
+    public DisconnectReason getDisconnectReason()
+    {
+      return disconnectReason;
+    }
+
+    /**
+     * Indicates whether to try to provide notification to the client
+     * that the connection will be closed.
+     *
+     * @return <code>true</code> if notification should be provided or
+     * <code>false</code> otherwise.
+     */
+    public boolean sendDisconnectNotification()
+    {
+      return sendDisconnectNotification;
+    }
+  }
+
+  /**
+   * Defines a post disconnect plugin result for client connection
+   * processing consisting of either continue or skip further
+   * plugins.
+   */
+  public static final class PostDisconnect
+  {
+    // Whether to invoke the rest of the plugins.
+    private final boolean continuePluginProcessing;
+
+    private static PostDisconnect DEFAULT_RESULT =
+        new PostDisconnect(true);
+
+    /**
+     * Construct a new post disconnect plugin result.
+     *
+     * @param continuePluginProcessing Whether to invoke the rest
+     * of the plugins.
+     */
+    private PostDisconnect(boolean continuePluginProcessing)
+    {
+      this.continuePluginProcessing = continuePluginProcessing;
+    }
+
+    /**
+     * Defines a continue processing post disconnect plugin result.
+     *
+     * @return a continue processing post disconnect plugin result.
+     */
+    public static PostDisconnect continueDisconnectProcessing()
+    {
+      return DEFAULT_RESULT;
+    }
+
+    /**
+     * Defines a skip further plugin processing post disconnect
+     * plugin result.
+     *
+     * @return  a skip further plugin processing post disconnect
+     * plugin result.
+     */
+    public static PostDisconnect skipFurtherPluginProcesssing()
+    {
+      return new PostDisconnect(false);
+    }
+
+    /**
+     * Whether to invoke the rest of the plugins.
+     *
+     * @return <code>true</code> if the rest of the plugins should
+     * be invoked for <code>false</code> to skip the rest of the
+     * plugins.
+     */
+    public boolean continuePluginProcessing()
+    {
+      return continuePluginProcessing;
+    }
+  }
+}
diff --git a/opends/src/server/org/opends/server/api/plugin/PostConnectPluginResult.java b/opends/src/server/org/opends/server/api/plugin/PostConnectPluginResult.java
deleted file mode 100644
index 6b884a1..0000000
--- a/opends/src/server/org/opends/server/api/plugin/PostConnectPluginResult.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing by a post-connect plugin.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class PostConnectPluginResult
-{
-  /**
-   * A post-connect plugin result instance that indicates all
-   * processing was  successful.
-   */
-  public static final PostConnectPluginResult SUCCESS =
-       new PostConnectPluginResult();
-
-
-
-  // Indicates whether any further post-connect plugins should be
-  // invoked for this connection.
-  private final boolean continuePluginProcessing;
-
-  // Indicates whether the post-connect plugin terminated the client
-  // connection.
-  private final boolean connectionTerminated;
-
-
-
-  /**
-   * Creates a new post-connect plugin result with the default
-   * settings.  In this case, it will indicate that the connection has
-   * not been terminated and that further post-connect plugin
-   * processing should be allowed.
-   */
-  private PostConnectPluginResult()
-  {
-    this(false, true);
-  }
-
-
-
-  /**
-   * Creates a new post-connect plugin result with the provided
-   * information.
-   *
-   * @param  connectionTerminated      Indicates whether the
-   *                                   post-connect plugin terminated
-   *                                   the client connection.
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   post-connect plugins should be
-   *                                   invoked for this connection.
-   */
-  public PostConnectPluginResult(boolean connectionTerminated,
-                                 boolean continuePluginProcessing)
-  {
-    this.connectionTerminated     = connectionTerminated;
-    this.continuePluginProcessing = continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the post-connect plugin terminated the client
-   * connection.
-   *
-   * @return  {@code true} if the post-connect plugin terminated the
-   *          client connection, or {@code false} if not.
-   */
-  public boolean connectionTerminated()
-  {
-    return connectionTerminated;
-  }
-
-
-
-  /**
-   * Indicates whether any further post-connect plugins should be
-   * invoked for this connection.
-   *
-   * @return  {@code true} if any further post-connect plugins should
-   *          be invoked for this connection, or {@code false} if not.
-   */
-  public boolean continuePluginProcessing()
-  {
-    return continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this post-connect plugin
-   * result.
-   *
-   * @return  A string representation of this post-connect plugin
-   *          result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this post-connect plugin
-   * result to the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("PostConnectPluginResult(connectionTerminated=");
-    buffer.append(connectionTerminated);
-    buffer.append(", continuePluginProcessing=");
-    buffer.append(continuePluginProcessing);
-    buffer.append(")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/api/plugin/PostDisconnectPluginResult.java b/opends/src/server/org/opends/server/api/plugin/PostDisconnectPluginResult.java
deleted file mode 100644
index 76cc1b7..0000000
--- a/opends/src/server/org/opends/server/api/plugin/PostDisconnectPluginResult.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing by a post-disconnect plugin.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class PostDisconnectPluginResult
-{
-  /**
-   * A post-disconnect plugin result instance that indicates all
-   * processing was successful.
-   */
-  public static final PostDisconnectPluginResult SUCCESS =
-       new PostDisconnectPluginResult();
-
-
-
-  // Indicates whether any further post-disconnect plugins should be
-  // invoked for this connection.
-  private final boolean continuePluginProcessing;
-
-
-
-  /**
-   * Creates a new post-connect plugin result with the default
-   * settings.  In this case, it will indicate that the further
-   * post-disconnect plugin processing should be allowed.
-   */
-  private PostDisconnectPluginResult()
-  {
-    this(true);
-  }
-
-
-
-  /**
-   * Creates a new post-disconnect plugin result with the provided
-   * information.
-   *
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   post-disconnect plugins should
-   *                                   be invoked for this connection.
-   */
-  public PostDisconnectPluginResult(boolean continuePluginProcessing)
-  {
-    this.continuePluginProcessing = continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether any further post-disconnect plugins should be
-   * invoked for this connection.
-   *
-   * @return  {@code true} if any further post-disconnect plugins
-   *          should be invoked for this connection, or {@code false}
-   *          if not.
-   */
-  public boolean continuePluginProcessing()
-  {
-    return continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this post-connect plugin
-   * result.
-   *
-   * @return  A string representation of this post-connect plugin
-   *          result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this post-connect plugin
-   * result to the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("PostDisconnectPluginResult(" +
-                  "continuePluginProcessing=");
-    buffer.append(continuePluginProcessing);
-    buffer.append(")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/api/plugin/PostOperationPluginResult.java b/opends/src/server/org/opends/server/api/plugin/PostOperationPluginResult.java
deleted file mode 100644
index 59a5690..0000000
--- a/opends/src/server/org/opends/server/api/plugin/PostOperationPluginResult.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing by a post-operation plugin.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class PostOperationPluginResult
-{
-  /**
-   * A post-operation plugin result instance that indicates all
-   * processing was  successful.
-   */
-  public static final PostOperationPluginResult SUCCESS =
-       new PostOperationPluginResult();
-
-
-
-  // Indicates whether any further post-operation plugins should be
-  // invoked for this operation.
-  private final boolean continuePluginProcessing;
-
-  // Indicates whether the post-operation plugin terminated the client
-  // connection.
-  private final boolean connectionTerminated;
-
-
-
-  /**
-   * Creates a new post-operation plugin result with the default
-   * settings.  In this case, it will indicate that the connection has
-   * not been terminated and that further post-operation plugin
-   * processing should be allowed.
-   */
-  private PostOperationPluginResult()
-  {
-    this(false, true);
-  }
-
-
-
-  /**
-   * Creates a new post-operation plugin result with the provided
-   * information.
-   *
-   * @param  connectionTerminated      Indicates whether the
-   *                                   post-operation plugin
-   *                                   terminated the client
-   *                                   connection.
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   post-operation plugins should
-   *                                   be invoked for this operation.
-   */
-  public PostOperationPluginResult(boolean connectionTerminated,
-                                   boolean continuePluginProcessing)
-  {
-    this.connectionTerminated     = connectionTerminated;
-    this.continuePluginProcessing = continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the post-operation plugin terminated the client
-   * connection.
-   *
-   * @return  {@code true} if the post-operation plugin terminated the
-   *          client connection, or {@code false} if not.
-   */
-  public boolean connectionTerminated()
-  {
-    return connectionTerminated;
-  }
-
-
-
-  /**
-   * Indicates whether any further post-operation plugins should be
-   * invoked for this operation.
-   *
-   * @return  {@code true} if any further post-operation plugins
-   *          should be invoked for this operation, or {@code false}
-   *          if not.
-   */
-  public boolean continuePluginProcessing()
-  {
-    return continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this post-connect plugin
-   * result.
-   *
-   * @return  A string representation of this post-connect plugin
-   *          result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this post-connect plugin
-   * result to the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("PostOperationPluginResult(connectionTerminated=");
-    buffer.append(connectionTerminated);
-    buffer.append(", continuePluginProcessing=");
-    buffer.append(continuePluginProcessing);
-    buffer.append(")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/api/plugin/PostResponsePluginResult.java b/opends/src/server/org/opends/server/api/plugin/PostResponsePluginResult.java
deleted file mode 100644
index 59ad1c1..0000000
--- a/opends/src/server/org/opends/server/api/plugin/PostResponsePluginResult.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing by a post-response plugin.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class PostResponsePluginResult
-{
-  /**
-   * A post-response plugin result instance that indicates all
-   * processing was successful.
-   */
-  public static final PostResponsePluginResult SUCCESS =
-       new PostResponsePluginResult();
-
-
-
-  // Indicates whether any further post-response plugins should be
-  // invoked for this operation.
-  private final boolean continuePluginProcessing;
-
-  // Indicates whether the post-response plugin terminated the client
-  // connection.
-  private final boolean connectionTerminated;
-
-
-
-  /**
-   * Creates a new post-response plugin result with the default
-   * settings.  In this case, it will indicate that the connection has
-   * not been terminated and that further post-response plugin
-   * processing should be allowed.
-   */
-  private PostResponsePluginResult()
-  {
-    this(false, true);
-  }
-
-
-
-  /**
-   * Creates a new post-response plugin result with the provided
-   * information.
-   *
-   * @param  connectionTerminated      Indicates whether the
-   *                                   post-response plugin terminated
-   *                                   the client connection.
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   post-response plugins should be
-   *                                   invoked for this operation.
-   */
-  public PostResponsePluginResult(boolean connectionTerminated,
-                                  boolean continuePluginProcessing)
-  {
-    this.connectionTerminated     = connectionTerminated;
-    this.continuePluginProcessing = continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether any further post-response plugins should be
-   * invoked for this operation.
-   *
-   * @return  {@code true} if any further post-response plugins should
-   *          be invoked for this operation, or {@code false} if not.
-   */
-  public boolean continuePluginProcessing()
-  {
-    return continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the post-response plugin terminated the client
-   * connection.
-   *
-   * @return  {@code true} if the post-response plugin terminated the
-   *          client connection, or {@code false} if not.
-   */
-  public boolean connectionTerminated()
-  {
-    return connectionTerminated;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this post-response plugin
-   * result.
-   *
-   * @return  A string representation of this post-response plugin
-   *          result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this post-response plugin
-   * result to the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("PostResponsePluginResult(connectionTerminated=");
-    buffer.append(connectionTerminated);
-    buffer.append(", continuePluginProcessing=");
-    buffer.append(continuePluginProcessing);
-    buffer.append(")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/api/plugin/PreOperationPluginResult.java b/opends/src/server/org/opends/server/api/plugin/PreOperationPluginResult.java
deleted file mode 100644
index d890765..0000000
--- a/opends/src/server/org/opends/server/api/plugin/PreOperationPluginResult.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing by a pre-operation plugin.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class PreOperationPluginResult
-{
-  /**
-   * A pre-operation plugin result instance that indicates all
-   * processing was successful.
-   */
-  public static final PreOperationPluginResult SUCCESS =
-       new PreOperationPluginResult();
-
-
-
-  // Indicates whether any further pre-operation plugins should be
-  // invoked for this operation.
-  private final boolean continuePluginProcessing;
-
-  // Indicates whether the pre-operation plugin terminated the client
-  // connection.
-  private final boolean connectionTerminated;
-
-  // Indicates whether the server should immediately send the response
-  // from this plugin to the client with no further processing.
-  private final boolean sendResponseImmediately;
-
-  // Indicates whether the server should skip the core processing for
-  // the associated operation.
-  private final boolean skipCoreProcessing;
-
-
-
-  /**
-   * Creates a new pre-operation plugin result with the default
-   * settings.  In this case, it will indicate that the connection has
-   * not been terminated, that further pre-operation plugin processing
-   * should continue, that the core processing should not be skipped,
-   * and that the post-operation plugin processing should not be
-   * skipped.
-   */
-  private PreOperationPluginResult()
-  {
-    this(false, true, false, false);
-  }
-
-
-
-  /**
-   * Creates a new pre-operation plugin result with the provided
-   * information.
-   *
-   * @param  connectionTerminated      Indicates whether the
-   *                                   pre-operation plugin terminated
-   *                                   the client connection.
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   pre-operation plugins should be
-   *                                   invoked for this operation.
-   * @param  sendResponseImmediately   Indicates whether the server
-   *                                   should send the response set by
-   *                                   this plugin to the client
-   *                                   immediately with no further
-   *                                   processing on the operation.
-   */
-  public PreOperationPluginResult(boolean connectionTerminated,
-                                  boolean continuePluginProcessing,
-                                  boolean sendResponseImmediately)
-  {
-    this(connectionTerminated, continuePluginProcessing,
-         sendResponseImmediately, false);
-  }
-
-
-
-  /**
-   * Creates a new pre-operation plugin result with the provided
-   * information.
-   *
-   * @param  connectionTerminated      Indicates whether the
-   *                                   pre-operation plugin terminated
-   *                                   the client connection.
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   pre-operation plugins should be
-   *                                   invoked for this operation.
-   * @param  sendResponseImmediately   Indicates whether the server
-   *                                   should send the response set by
-   *                                   this plugin to the client
-   *                                   immediately with no further
-   *                                   processing on the operation.
-   * @param  skipCoreProcessing        Indicates whether the server
-   *                                   should skip the core processing
-   *                                   for the operation.  If
-   *                                   {@code sendResponseImmediately}
-   *                                   is {@code false}, then any
-   *                                   post-operation plugins will
-   *                                   still be invoked.
-   */
-  public PreOperationPluginResult(boolean connectionTerminated,
-                                  boolean continuePluginProcessing,
-                                  boolean sendResponseImmediately,
-                                  boolean skipCoreProcessing)
-  {
-    this.connectionTerminated     = connectionTerminated;
-    this.continuePluginProcessing = continuePluginProcessing;
-    this.sendResponseImmediately  = sendResponseImmediately;
-    this.skipCoreProcessing       = skipCoreProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the pre-operation plugin terminated the client
-   * connection.
-   *
-   * @return  {@code true} if the pre-operation plugin terminated the
-   *          client connection, or {@code false} if not.
-   */
-  public boolean connectionTerminated()
-  {
-    return connectionTerminated;
-  }
-
-
-
-  /**
-   * Indicates whether any further pre-operation plugins should be
-   * invoked for this operation.
-   *
-   * @return  {@code true} if any further pre-operation plugins should
-   *          be invoked for this operation, or {@code false} if not.
-   */
-  public boolean continuePluginProcessing()
-  {
-    return continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the server should send the response set by this
-   * plugin to the client immediately with no further processing on
-   * the operation.
-   *
-   * @return  {@code true} if the server should send the response set
-   *          by this plugin to the client immediately, or
-   *          {@code false} if further processing should be performed
-   *          on the operation.
-   */
-  public boolean sendResponseImmediately()
-  {
-    return sendResponseImmediately;
-  }
-
-
-
-  /**
-   * Indicates whether the server should skip core processing for the
-   * operation.  If {@code sendResponseImmediately} is {@code false},
-   * then the server will still process any post-operation plugins
-   * that may be registered with the server.
-   *
-   * @return  {@code true} if the server should skip core processing
-   *          for the operation, or {@code false} if not.
-   */
-  public boolean skipCoreProcessing()
-  {
-    return skipCoreProcessing;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this pre-operation plugin
-   * result.
-   *
-   * @return  A string representation of this pre-operation plugin
-   *          result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this pre-operation plugin
-   * result to the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("PreOperationPluginResult(connectionTerminated=");
-    buffer.append(connectionTerminated);
-    buffer.append(", continuePluginProcessing=");
-    buffer.append(continuePluginProcessing);
-    buffer.append(", sendResponseImmediately=");
-    buffer.append(sendResponseImmediately);
-    buffer.append(", skipCoreProcessing=");
-    buffer.append(skipCoreProcessing);
-    buffer.append(")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/api/plugin/PreParsePluginResult.java b/opends/src/server/org/opends/server/api/plugin/PreParsePluginResult.java
deleted file mode 100644
index 7077e38..0000000
--- a/opends/src/server/org/opends/server/api/plugin/PreParsePluginResult.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing by a pre-parse plugin.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class PreParsePluginResult
-{
-  /**
-   * A pre-parse plugin result instance that indicates all processing
-   * was successful.
-   */
-  public static final PreParsePluginResult SUCCESS =
-       new PreParsePluginResult();
-
-
-
-  // Indicates whether any further pre-operation plugins should be
-  // invoked for this operation.
-  private final boolean continuePluginProcessing;
-
-  // Indicates whether the pre-parse plugin terminated the client
-  // connection.
-  private final boolean connectionTerminated;
-
-  // Indicates whether the server should immediately send the response
-  // from this plugin to the client with no further processing.
-  private final boolean sendResponseImmediately;
-
-  // Indicates whether the server should skip the core processing for
-  // the associated operation.
-  private final boolean skipCoreProcessing;
-
-
-
-  /**
-   * Creates a new pre-parse plugin result with the default settings.
-   * In this case, it will indicate that the connection has not been
-   * terminated, that further pre-parse plugin processing should
-   * continue, that the core processing should not be skipped, and
-   * that the pre-operation and post-operation plugin processing
-   * should not be skipped.
-   */
-  private PreParsePluginResult()
-  {
-    this(false, true, false, false);
-  }
-
-
-
-  /**
-   * Creates a new pre-parse plugin result with the provided
-   * information.
-   *
-   * @param  connectionTerminated      Indicates whether the
-   *                                   pre-parse plugin terminated
-   *                                   the client connection.
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   pre-parse plugins should be
-   *                                   invoked for this operation.
-   * @param  sendResponseImmediately   Indicates whether the server
-   *                                   should send the response set by
-   *                                   this plugin to the client
-   *                                   immediately with no further
-   *                                   processing on the operation.
-   */
-  public PreParsePluginResult(boolean connectionTerminated,
-                              boolean continuePluginProcessing,
-                              boolean sendResponseImmediately)
-  {
-    this(connectionTerminated, continuePluginProcessing,
-         sendResponseImmediately, false);
-  }
-
-
-
-  /**
-   * Creates a new pre-parse plugin result with the provided
-   * information.
-   *
-   * @param  connectionTerminated      Indicates whether the
-   *                                   pre-parse plugin terminated
-   *                                   the client connection.
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   pre-parse plugins should be
-   *                                   invoked for this operation.
-   * @param  sendResponseImmediately   Indicates whether the server
-   *                                   should send the response set by
-   *                                   this plugin to the client
-   *                                   immediately with no further
-   *                                   processing on the operation.
-   * @param  skipCoreProcessing        Indicates whether the server
-   *                                   should skip the core processing
-   *                                   for the operation.  If
-   *                                   {@code sendResponseImmediately}
-   *                                   is {@code false}, then any
-   *                                   post-operation plugins will
-   *                                   still be invoked.
-   */
-  public PreParsePluginResult(boolean connectionTerminated,
-                              boolean continuePluginProcessing,
-                              boolean sendResponseImmediately,
-                              boolean skipCoreProcessing)
-  {
-    this.connectionTerminated     = connectionTerminated;
-    this.continuePluginProcessing = continuePluginProcessing;
-    this.sendResponseImmediately  = sendResponseImmediately;
-    this.skipCoreProcessing       = skipCoreProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the pre-parse plugin terminated the client
-   * connection.
-   *
-   * @return  {@code true} if the pre-parse plugin terminated the
-   *          client connection, or {@code false} if not.
-   */
-  public boolean connectionTerminated()
-  {
-    return connectionTerminated;
-  }
-
-
-
-  /**
-   * Indicates whether any further pre-parse plugins should be invoked
-   * for this operation.
-   *
-   * @return  {@code true} if any further pre-parse plugins should be
-   *          invoked for this operation, or {@code false} if not.
-   */
-  public boolean continuePluginProcessing()
-  {
-    return continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the server should send the response set by this
-   * plugin to the client immediately with no further processing on
-   * the operation.
-   *
-   * @return  {@code true} if the server should send the response set
-   *          by this plugin to the client immediately, or
-   *          {@code false} if further processing should be performed
-   *          on the operation.
-   */
-  public boolean sendResponseImmediately()
-  {
-    return sendResponseImmediately;
-  }
-
-
-
-  /**
-   * Indicates whether the server should skip core processing for the
-   * operation.  If {@code sendResponseImmediately} is {@code false},
-   * then the server will still process any post-operation plugins
-   * that may be registered with the server.
-   *
-   * @return  {@code true} if the server should skip core processing
-   *          for the operation, or {@code false} if not.
-   */
-  public boolean skipCoreProcessing()
-  {
-    return skipCoreProcessing;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this pre-parse plugin
-   * result.
-   *
-   * @return  A string representation of this pre-parse plugin result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this pre-parse plugin result
-   * to the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("PreParsePluginResult(connectionTerminated=");
-    buffer.append(connectionTerminated);
-    buffer.append(", continuePluginProcessing=");
-    buffer.append(continuePluginProcessing);
-    buffer.append(", sendResponseImmediately=");
-    buffer.append(sendResponseImmediately);
-    buffer.append(", skipCoreProcessing=");
-    buffer.append(skipCoreProcessing);
-    buffer.append(")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/api/plugin/SearchEntryPluginResult.java b/opends/src/server/org/opends/server/api/plugin/SearchEntryPluginResult.java
deleted file mode 100644
index 6554b45..0000000
--- a/opends/src/server/org/opends/server/api/plugin/SearchEntryPluginResult.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing by a search result entry plugin.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class SearchEntryPluginResult
-{
-  /**
-   * A search entry plugin result instance that indicates all
-   * processing was successful.
-   */
-  public static final SearchEntryPluginResult SUCCESS =
-       new SearchEntryPluginResult();
-
-
-
-  // Indicates whether any further search result entry plugins should
-  // be invoked for this operation.
-  private final boolean continuePluginProcessing;
-
-  // Indicates whether processing should continue for the associated
-  // search operation.
-  private final boolean continueSearch;
-
-  // Indicates whether the search result entry plugin terminated the
-  // client connection.
-  private final boolean connectionTerminated;
-
-  // Indicates whether the associated entry should be sent to the
-  // client.
-  private final boolean sendEntry;
-
-
-
-  /**
-   * Creates a new search entry plugin result with the default
-   * settings.  In this case, it will indicate that the connection has
-   * not been terminated, that further search entry plugin processing
-   * should continue, that the entry should be returned to the client,
-   * and that processing on the search operation should continue.
-   */
-  private SearchEntryPluginResult()
-  {
-    this(false, true, true, true);
-  }
-
-
-
-  /**
-   * Creates a new search entry plugin result with the provided
-   * information.
-   *
-   * @param  connectionTerminated      Indicates whether the search
-   *                                   entry plugin terminated the
-   *                                   client connection.
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   search entry plugins should be
-   *                                   invoked for this operation.
-   * @param  sendEntry                 Indicates whether the entry
-   *                                   should be sent to the client.
-   * @param  continueSearch            Indicates whether the server
-   *                                   should continue processing the
-   *                                   search operation.
-   */
-  public SearchEntryPluginResult(boolean connectionTerminated,
-                                 boolean continuePluginProcessing,
-                                 boolean sendEntry,
-                                 boolean continueSearch)
-  {
-    this.connectionTerminated     = connectionTerminated;
-    this.continuePluginProcessing = continuePluginProcessing;
-    this.sendEntry                = sendEntry;
-    this.continueSearch           = continueSearch;
-  }
-
-
-
-  /**
-   * Indicates whether the search result entry plugin terminated the
-   * client connection.
-   *
-   * @return  {@code true} if the search result entry plugin
-   *          terminated the client connection, or {@code false} if
-   *          not.
-   */
-  public boolean connectionTerminated()
-  {
-    return connectionTerminated;
-  }
-
-
-
-  /**
-   * Indicates whether any further search result entry plugins should
-   * be invoked for this operation.
-   *
-   * @return  {@code true} if any further search result entry plugins
-   *          should be invoked for this operation, or {@code false}
-   *          if not.
-   */
-  public boolean continuePluginProcessing()
-  {
-    return continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the associated search result entry should be
-   * sent to the client.
-   *
-   * @return  {@code true} if the associated search result entry
-   *          should be sent to the client, or {@code false} if not.
-   */
-  public boolean sendEntry()
-  {
-    return sendEntry;
-  }
-
-
-
-  /**
-   * Indicates whether processing should continue for the associated
-   * search operation (i.e., if it should continue looking for more
-   * matching entries).
-   *
-   * @return  {@code true} if processing on the search operation
-   *          should continue, or {@code false} if not.
-   */
-  public boolean continueSearch()
-  {
-    return continueSearch;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this search result entry
-   * plugin result.
-   *
-   * @return  A string representation of this search result entry
-   *          plugin result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this search result entry
-   * plugin result to the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("SearchEntryPluginResult(connectionTerminated=");
-    buffer.append(connectionTerminated);
-    buffer.append(", continuePluginProcessing=");
-    buffer.append(continuePluginProcessing);
-    buffer.append(", sendEntry=");
-    buffer.append(sendEntry);
-    buffer.append(", continueSearch=");
-    buffer.append(continueSearch);
-    buffer.append(")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/api/plugin/SearchReferencePluginResult.java b/opends/src/server/org/opends/server/api/plugin/SearchReferencePluginResult.java
deleted file mode 100644
index 18ecd83..0000000
--- a/opends/src/server/org/opends/server/api/plugin/SearchReferencePluginResult.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing by a search result reference plugin.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class SearchReferencePluginResult
-{
-  /**
-   * A search reference plugin result instance that indicates all
-   * processing was successful.
-   */
-  public static final SearchReferencePluginResult SUCCESS =
-       new SearchReferencePluginResult();
-
-
-
-  // Indicates whether any further search result reference plugins
-  // should be invoked for this operation.
-  private final boolean continuePluginProcessing;
-
-  // Indicates whether processing should continue for the associated
-  // search operation.
-  private final boolean continueSearch;
-
-  // Indicates whether the search result reference plugin terminated
-  // the client connection.
-  private final boolean connectionTerminated;
-
-  // Indicates whether the associated reference should be sent to the
-  // client.
-  private final boolean sendReference;
-
-
-
-  /**
-   * Creates a new search reference plugin result with the default
-   * settings.  In this case, it will indicate that the connection has
-   * not been terminated, that further search reference plugin
-   * processing should continue, that the reference should be returned
-   * to the client, and that processing on the search operation should
-   * continue.
-   */
-  private SearchReferencePluginResult()
-  {
-    this(false, true, true, true);
-  }
-
-
-
-  /**
-   * Creates a new search reference plugin result with the provided
-   * information.
-   *
-   * @param  connectionTerminated      Indicates whether the search
-   *                                   reference plugin terminated the
-   *                                   client connection.
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   search reference plugins should
-   *                                   be invoked for this operation.
-   * @param  sendReference             Indicates whether the reference
-   *                                   should be sent to the client.
-   * @param  continueSearch            Indicates whether the server
-   *                                   should continue processing the
-   *                                   search operation.
-   */
-  public SearchReferencePluginResult(boolean connectionTerminated,
-                                     boolean continuePluginProcessing,
-                                     boolean sendReference,
-                                     boolean continueSearch)
-  {
-    this.connectionTerminated     = connectionTerminated;
-    this.continuePluginProcessing = continuePluginProcessing;
-    this.sendReference            = sendReference;
-    this.continueSearch           = continueSearch;
-  }
-
-
-
-  /**
-   * Indicates whether the search result reference plugin terminated
-   * the client connection.
-   *
-   * @return  {@code true} if the search result reference plugin
-   *          terminated the client connection, or {@code false} if
-   *          not.
-   */
-  public boolean connectionTerminated()
-  {
-    return connectionTerminated;
-  }
-
-
-
-  /**
-   * Indicates whether any further search result reference plugins
-   * should be invoked for this operation.
-   *
-   * @return  {@code true} if any further search result reference
-   *          plugins should be invoked for this operation, or
-   *          {@code false} if not.
-   */
-  public boolean continuePluginProcessing()
-  {
-    return continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the associated search result reference should
-   * be sent to the client.
-   *
-   * @return  {@code true} if the associated search result reference
-   *          should be sent to the client, or {@code false} if not.
-   */
-  public boolean sendReference()
-  {
-    return sendReference;
-  }
-
-
-
-  /**
-   * Indicates whether processing should continue for the associated
-   * search operation (i.e., if it should continue looking for more
-   * matching entries).
-   *
-   * @return  {@code true} if processing on the search operation
-   *          continue, or {@code false} if not.
-   */
-  public boolean continueSearch()
-  {
-    return continueSearch;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this search result reference
-   * plugin result.
-   *
-   * @return  A string representation of this search result reference
-   *          plugin result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this search result reference
-   * plugin result to the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("SearchReferencePluginResult(" +
-                  "connectionTerminated=");
-    buffer.append(connectionTerminated);
-    buffer.append(", continuePluginProcessing=");
-    buffer.append(continuePluginProcessing);
-    buffer.append(", sendReference=");
-    buffer.append(sendReference);
-    buffer.append(", continueSearch=");
-    buffer.append(continueSearch);
-    buffer.append(")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/api/plugin/StartupPluginResult.java b/opends/src/server/org/opends/server/api/plugin/StartupPluginResult.java
deleted file mode 100644
index 64b21a9..0000000
--- a/opends/src/server/org/opends/server/api/plugin/StartupPluginResult.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-import org.opends.messages.Message;
-import org.opends.messages.MessageDescriptor;
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing by a plugin invoked during the Directory
- * Server startup process.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class StartupPluginResult
-{
-  /**
-   * A startup plugin result instance that indicates all processing
-   * was successful.
-   */
-  public static final StartupPluginResult SUCCESS =
-       new StartupPluginResult();
-
-
-
-  // Indicates whether the startup plugin completed successfully.
-  private final boolean completedSuccessfully;
-
-  // Indicates whether the server should continue with the startup
-  // process.
-  private final boolean continueStartup;
-
-  // A message that explains any error that might have
-  // occurred.
-  private final Message errorMessage;
-
-
-
-  /**
-   * Creates a new startup plugin result with the default settings.
-   * In this case, it will indicate that the plugin completed
-   * successfully, that the startup process should continue, and that
-   * there is no error message.
-   */
-  private StartupPluginResult()
-  {
-    this(true, true, null);
-  }
-
-
-
-  /**
-   * Creates a new startup plugin result with the provided
-   * information.
-   *
-   * @param  completedSuccessfully  Indicates whether the startup
-   *                                plugin completed its processing
-   *                                successfully.
-   * @param  continueStartup        Indicates whether the Directory
-   *                                Server should continue with its
-   *                                startup process.
-   * @param  errorMessage           An error message that explains any
-   *                                error that might have occurred.
-   */
-  public StartupPluginResult(boolean completedSuccessfully,
-                             boolean continueStartup,
-                             Message errorMessage)
-  {
-    this.completedSuccessfully = completedSuccessfully;
-    this.continueStartup       = continueStartup;
-    this.errorMessage          = errorMessage;
-  }
-
-
-
-  /**
-   * Indicates whether the startup plugin completed its processing
-   * successfully.
-   *
-   * @return  {@code true} if the startup plugin completed its
-   *          processing successfully, or {@code false} if not.
-   */
-  public boolean completedSuccessfully()
-  {
-    return completedSuccessfully;
-  }
-
-
-
-  /**
-   * Indicates whether the Directory Server should continue with its
-   * startup process.
-   *
-   * @return  {@code true} if the Directory Server should continue
-   *          with its startup process, or {@code false} if not.
-   */
-  public boolean continueStartup()
-  {
-    return continueStartup;
-  }
-
-
-
-  /**
-   * Retrieves the human-readable error message generated by the
-   * startup plugin.
-   *
-   * @return  The human-readable error message generated by the
-   *          startup plugin, or {@code null} if there is no error
-   *          message.
-   */
-  public Message getErrorMessage()
-  {
-    return errorMessage;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this startup plugin result.
-   *
-   * @return  A string representation of this startup plugin result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this startup plugin result to
-   * the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("StartupPluginResult(completedSuccessfully=");
-    buffer.append(completedSuccessfully);
-    buffer.append(", continueStartup=");
-    buffer.append(continueStartup);
-    buffer.append(", errorID=");
-    if (errorMessage != null) {
-      buffer.append(errorMessage.getDescriptor().getId());
-    } else {
-      buffer.append(MessageDescriptor.NULL_ID);
-    }
-    buffer.append(", errorMessage=\"");
-    buffer.append(errorMessage);
-    buffer.append("\")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/api/plugin/SubordinateModifyDNPluginResult.java b/opends/src/server/org/opends/server/api/plugin/SubordinateModifyDNPluginResult.java
deleted file mode 100644
index cccb762..0000000
--- a/opends/src/server/org/opends/server/api/plugin/SubordinateModifyDNPluginResult.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-/**
- * This class defines a data structure that holds information about
- * the result of processing by a subordinate modify DN plugin.
- */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
-     mayInstantiate=true,
-     mayExtend=false,
-     mayInvoke=true)
-public class SubordinateModifyDNPluginResult
-{
-  /**
-   * A pre-operation plugin result instance that indicates all
-   * processing was successful.
-   */
-  public static final SubordinateModifyDNPluginResult SUCCESS =
-       new SubordinateModifyDNPluginResult();
-
-
-
-  // Indicates whether to abort the modify DN operation without making
-  // any changes.
-  private final boolean abortModifyDNOperation;
-
-  // Indicates whether any further subordinate modify DN plugins
-  // should be invoked for this operation.
-  private final boolean continuePluginProcessing;
-
-  // Indicates whether the subordinate modify DN plugin terminated the
-  // client connection.
-  private final boolean connectionTerminated;
-
-
-
-  /**
-   * Creates a new subordinate modify DN plugin result with the
-   * default settings.  In this case, it will indicate that the
-   * connection has not been terminated, that further subordinate
-   * modify DN processing should continue, and that the modify DN
-   * operation should not be aborted.
-   */
-  private SubordinateModifyDNPluginResult()
-  {
-    this(false, true, false);
-  }
-
-
-
-  /**
-   * Creates a new subordinate modify DN plugin result with the
-   * provided information.
-   *
-   * @param  connectionTerminated      Indicates whether the
-   *                                   subordinate modify DN plugin
-   *                                   terminated the client
-   *                                   connection.
-   * @param  continuePluginProcessing  Indicates whether any further
-   *                                   subordinate modify DN plugins
-   *                                   should be invoked for this
-   *                                   operation.
-   * @param  abortModifyDNOperation    Indicates whether the modify DN
-   *                                   operation should be aborted and
-   *                                   all associated changes
-   *                                   discarded.
-   */
-  public SubordinateModifyDNPluginResult(boolean connectionTerminated,
-              boolean continuePluginProcessing,
-              boolean abortModifyDNOperation)
-  {
-    this.connectionTerminated     = connectionTerminated;
-    this.continuePluginProcessing = continuePluginProcessing;
-    this.abortModifyDNOperation   = abortModifyDNOperation;
-  }
-
-
-
-  /**
-   * Indicates whether the subordinate modify DN plugin terminated the
-   * client connection.
-   *
-   * @return  {@code true} if the subordinate modify DN plugin
-   *          terminated the client connection, or {@code false} if
-   *          not.
-   */
-  public boolean connectionTerminated()
-  {
-    return connectionTerminated;
-  }
-
-
-
-  /**
-   * Indicates whether any further subordinate modify DN plugins
-   * should be invoked for this operation.
-   *
-   * @return  {@code true} if any further subordinate modify DN
-   *          plugins should be invoked for this operation, or
-   *          {@code false} if not.
-   */
-  public boolean continuePluginProcessing()
-  {
-    return continuePluginProcessing;
-  }
-
-
-
-  /**
-   * Indicates whether the modify DN operation should be aborted and
-   * all associated changes discarded.
-   *
-   * @return  {@code true} if the modify DN operation should be
-   *          aborted, or {@code false} if not.
-   */
-  public boolean abortModifyDNOperation()
-  {
-    return abortModifyDNOperation;
-  }
-
-
-
-  /**
-   * Retrieves a string representation of this post-response plugin
-   * result.
-   *
-   * @return  A string representation of this post-response plugin
-   *          result.
-   */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this subordinate modify DN
-   * plugin result to the provided buffer.
-   *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
-   */
-  public void toString(StringBuilder buffer)
-  {
-    buffer.append("SubordinateModifyDNPluginResult(");
-    buffer.append("connectionTerminated=");
-    buffer.append(connectionTerminated);
-    buffer.append(", continuePluginProcessing=");
-    buffer.append(continuePluginProcessing);
-    buffer.append(", abortModifyDNOperation=");
-    buffer.append(abortModifyDNOperation);
-    buffer.append(")");
-  }
-}
-
diff --git a/opends/src/server/org/opends/server/backends/RootDSEBackend.java b/opends/src/server/org/opends/server/backends/RootDSEBackend.java
index fb1f312..13c37f1 100644
--- a/opends/src/server/org/opends/server/backends/RootDSEBackend.java
+++ b/opends/src/server/org/opends/server/backends/RootDSEBackend.java
@@ -965,8 +965,7 @@
    */
   @Override()
   public void search(SearchOperation searchOperation)
-         throws DirectoryException, CancelledOperationException
-  {
+         throws DirectoryException, CanceledOperationException {
     DN baseDN = searchOperation.getBaseDN();
     if (! baseDN.isNullDN())
     {
@@ -1002,11 +1001,7 @@
 
         for (DN subBase : baseMap.keySet())
         {
-          CancelRequest cancelRequest = searchOperation.getCancelRequest();
-          if (cancelRequest != null)
-          {
-            throw new CancelledOperationException(CancelResult.CANCELED);
-          }
+          searchOperation.checkIfCanceled(false);
 
           Backend b = baseMap.get(subBase);
           Entry subBaseEntry = b.getEntry(subBase);
@@ -1033,11 +1028,7 @@
         {
           for (DN subBase : baseMap.keySet())
           {
-            CancelRequest cancelRequest = searchOperation.getCancelRequest();
-            if (cancelRequest != null)
-            {
-              throw new CancelledOperationException(CancelResult.CANCELED);
-            }
+            searchOperation.checkIfCanceled(false);
 
             Backend b = baseMap.get(subBase);
             searchOperation.setBaseDN(subBase);
diff --git a/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java b/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
index 86c94fb..b3604a5 100644
--- a/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
+++ b/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
@@ -916,8 +916,7 @@
   @Override()
   public void renameEntry(DN currentDN, Entry entry,
                           ModifyDNOperation modifyDNOperation)
-      throws DirectoryException, CancelledOperationException
-  {
+      throws DirectoryException, CanceledOperationException {
     writerBegin();
 
     EntryContainer currentContainer;
diff --git a/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java b/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
index d04b05e..52204f6 100644
--- a/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -33,7 +33,7 @@
 import org.opends.server.api.Backend;
 import org.opends.server.api.EntryCache;
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.SubordinateModifyDNPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.core.AddOperation;
 import org.opends.server.core.DeleteOperation;
 import org.opends.server.core.DirectoryServer;
@@ -2994,7 +2994,7 @@
    * @throws org.opends.server.types.DirectoryException
    *          If a problem occurs while trying to perform
    *          the rename.
-   * @throws org.opends.server.types.CancelledOperationException
+   * @throws org.opends.server.types.CanceledOperationException
    *          If this backend noticed and reacted
    *          to a request to cancel or abandon the
    *          modify DN operation.
@@ -3004,8 +3004,7 @@
   public void renameEntry(DN currentDN, Entry entry,
                           ModifyDNOperation modifyDNOperation)
       throws DatabaseException, JebException, DirectoryException,
-      CancelledOperationException
-  {
+      CanceledOperationException {
     TransactedOperation operation =
         new RenameEntryTransaction(currentDN, entry, modifyDNOperation);
 
@@ -3503,12 +3502,11 @@
              DirectoryServer.getPluginConfigManager();
         List<Modification> modifications =
              Collections.unmodifiableList(new ArrayList<Modification>(0));
-        SubordinateModifyDNPluginResult pluginResult =
+        PluginResult.SubordinateModifyDN pluginResult =
              pluginManager.invokeSubordinateModifyDNPlugins(
                   modifyDNOperation, oldEntry, newEntry, modifications);
 
-        if (pluginResult.connectionTerminated() ||
-            pluginResult.abortModifyDNOperation())
+        if (!pluginResult.continueProcessing())
         {
           Message message = ERR_JEB_MODIFYDN_ABORTED_BY_SUBORDINATE_PLUGIN.get(
                   oldDN.toString(), newDN.toString());
@@ -3634,12 +3632,11 @@
              DirectoryServer.getPluginConfigManager();
         List<Modification> modifications =
              Collections.unmodifiableList(new ArrayList<Modification>(0));
-        SubordinateModifyDNPluginResult pluginResult =
+        PluginResult.SubordinateModifyDN pluginResult =
              pluginManager.invokeSubordinateModifyDNPlugins(
                   modifyDNOperation, oldEntry, newEntry, modifications);
 
-        if (pluginResult.connectionTerminated() ||
-            pluginResult.abortModifyDNOperation())
+        if (!pluginResult.continueProcessing())
         {
           Message message = ERR_JEB_MODIFYDN_ABORTED_BY_SUBORDINATE_PLUGIN.get(
                   oldDN.toString(), newDN.toString());
diff --git a/opends/src/server/org/opends/server/backends/task/TaskBackend.java b/opends/src/server/org/opends/server/backends/task/TaskBackend.java
index a40e6bf..eafd70a 100644
--- a/opends/src/server/org/opends/server/backends/task/TaskBackend.java
+++ b/opends/src/server/org/opends/server/backends/task/TaskBackend.java
@@ -55,7 +55,7 @@
 import org.opends.server.types.AttributeValue;
 import org.opends.server.types.BackupConfig;
 import org.opends.server.types.BackupDirectory;
-import org.opends.server.types.CancelledOperationException;
+import org.opends.server.types.CanceledOperationException;
 import org.opends.server.types.ConditionResult;
 import org.opends.server.types.ConfigChangeResult;
 import org.opends.server.types.DebugLogLevel;
@@ -838,8 +838,7 @@
    */
   @Override()
   public void search(SearchOperation searchOperation)
-         throws DirectoryException, CancelledOperationException
-  {
+         throws DirectoryException, CanceledOperationException {
     // Look at the base DN and scope for the search operation to decide which
     // entries we need to look at.
     boolean searchRoot            = false;
diff --git a/opends/src/server/org/opends/server/controls/ProxiedAuthV1Control.java b/opends/src/server/org/opends/server/controls/ProxiedAuthV1Control.java
index 5f0ebc7..5122226 100644
--- a/opends/src/server/org/opends/server/controls/ProxiedAuthV1Control.java
+++ b/opends/src/server/org/opends/server/controls/ProxiedAuthV1Control.java
@@ -371,8 +371,7 @@
 
       // FIXME -- We should provide some mechanism for enabling debug
       // processing.
-      PasswordPolicyState pwpState = new PasswordPolicyState(userEntry, false,
-                                                             false);
+      PasswordPolicyState pwpState = new PasswordPolicyState(userEntry, false);
       if (pwpState.isDisabled() || pwpState.isAccountExpired() ||
           pwpState.lockedDueToFailures() ||
           pwpState.lockedDueToIdleInterval() ||
diff --git a/opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java b/opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java
index bcde899..197f6bf 100644
--- a/opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java
+++ b/opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java
@@ -305,7 +305,7 @@
           // FIXME -- We should provide some mechanism for enabling debug
           // processing.
           PasswordPolicyState pwpState =
-               new PasswordPolicyState(userEntry, false, false);
+               new PasswordPolicyState(userEntry, false);
           if (pwpState.isDisabled() || pwpState.isAccountExpired() ||
               pwpState.lockedDueToFailures() ||
               pwpState.lockedDueToIdleInterval() ||
@@ -358,7 +358,7 @@
         // FIXME -- We should provide some mechanism for enabling debug
         // processing.
         PasswordPolicyState pwpState =
-             new PasswordPolicyState(userEntry, false, false);
+             new PasswordPolicyState(userEntry, false);
         if (pwpState.isDisabled() || pwpState.isAccountExpired() ||
             pwpState.lockedDueToFailures() ||
             pwpState.lockedDueToIdleInterval() ||
diff --git a/opends/src/server/org/opends/server/core/AbandonOperationBasis.java b/opends/src/server/org/opends/server/core/AbandonOperationBasis.java
index 483a940..649f815 100644
--- a/opends/src/server/org/opends/server/core/AbandonOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/AbandonOperationBasis.java
@@ -38,16 +38,10 @@
 import java.util.List;
 
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.PreParsePluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.loggers.debug.DebugLogger;
 import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 import org.opends.server.types.operation.PostOperationAbandonOperation;
 import org.opends.server.types.operation.PreParseAbandonOperation;
 
@@ -95,6 +89,8 @@
 
 
     this.idToAbandon = idToAbandon;
+    this.cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL,
+        ERR_CANNOT_CANCEL_ABANDON.get());
   }
 
 
@@ -129,20 +125,6 @@
    * {@inheritDoc}
    */
   @Override()
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, Message message
-  )
-  {
-    clientConnection.disconnect(disconnectReason, sendNotification,
-            message);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
   public final String[][] getRequestLogElements()
   {
     // Note that no debugging will be done in this method because it is a likely
@@ -239,53 +221,31 @@
   {
     setResultCode(ResultCode.UNDEFINED);
 
+    // Start the processing timer.
+    setProcessingStartTime();
+
+    // Log the abandon request message.
+    logAbandonRequest(this);
 
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
          DirectoryServer.getPluginConfigManager();
-    boolean skipPostOperation = false;
-
-
-    // Start the processing timer.
-    setProcessingStartTime();
-
 
     // Create a labeled block of code that we can break out of if a problem is
     // detected.
 abandonProcessing:
     {
       // Invoke the pre-parse abandon plugins.
-      PreParsePluginResult preParseResult =
+      PluginResult.PreParse preParseResult =
            pluginConfigManager.invokePreParseAbandonPlugins(this);
-      if (preParseResult.connectionTerminated())
+      if (!preParseResult.continueProcessing())
       {
-        // There's no point in continuing.  Log the request and result and
-        // return.
-        setResultCode(ResultCode.CANCELED);
-
-        appendErrorMessage(ERR_CANCELED_BY_PREPARSE_DISCONNECT.get());
-
-        setProcessingStopTime();
-
-        logAbandonRequest(this);
-        logAbandonResult(this);
-        return;
-      }
-      else if (preParseResult.sendResponseImmediately())
-      {
-        skipPostOperation = true;
+        setResultCode(preParseResult.getResultCode());
+        appendErrorMessage(preParseResult.getErrorMessage());
+        setMatchedDN(preParseResult.getMatchedDN());
+        setReferralURLs(preParseResult.getReferralURLs());
         break abandonProcessing;
       }
-      else if (preParseResult.skipCoreProcessing())
-      {
-        skipPostOperation = false;
-        break abandonProcessing;
-      }
-
-
-      // Log the abandon request message.
-      logAbandonRequest(this);
-
 
       // Actually perform the abandon operation.  Make sure to set the result
       // code to reflect whether the abandon was successful and an error message
@@ -306,20 +266,22 @@
         // configurable option in the server.
         boolean notifyRequestor = DirectoryServer.notifyAbandonedOperations();
         Message cancelReason = INFO_CANCELED_BY_ABANDON_REQUEST.get(messageID);
-        MessageBuilder cancelResponse = new MessageBuilder();
         CancelResult result =
-             operation.cancel(new CancelRequest(notifyRequestor, cancelReason,
-                                                cancelResponse));
+             operation.cancel(new CancelRequest(notifyRequestor, cancelReason));
         setResultCode(result.getResultCode());
-        setErrorMessage(cancelResponse);
+        appendErrorMessage(result.getResponseMessage());
       }
-    }
 
-
-    // Invoke the post-operation abandon plugins.
-    if (! skipPostOperation)
-    {
-      pluginConfigManager.invokePostOperationAbandonPlugins(this);
+      PluginResult.PostOperation postOpResult =
+          pluginConfigManager.invokePostOperationAbandonPlugins(this);
+      if (!postOpResult.continueProcessing())
+      {
+        setResultCode(preParseResult.getResultCode());
+        appendErrorMessage(preParseResult.getErrorMessage());
+        setMatchedDN(preParseResult.getMatchedDN());
+        setReferralURLs(preParseResult.getReferralURLs());
+        break abandonProcessing;
+      }
     }
 
 
@@ -337,41 +299,6 @@
    * {@inheritDoc}
    */
   @Override()
-  public final CancelResult cancel(CancelRequest cancelRequest)
-  {
-    cancelRequest.addResponseMessage(ERR_CANNOT_CANCEL_ABANDON.get());
-    return CancelResult.CANNOT_CANCEL;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelRequest getCancelRequest()
-  {
-    return null;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    // Abandon operations cannot be canceled.
-    return false;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
   public final void toString(StringBuilder buffer)
   {
     buffer.append("AbandonOperation(connID=");
diff --git a/opends/src/server/org/opends/server/core/AddOperationBasis.java b/opends/src/server/org/opends/server/core/AddOperationBasis.java
index 2536585..aca00cb 100644
--- a/opends/src/server/org/opends/server/core/AddOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/AddOperationBasis.java
@@ -52,30 +52,12 @@
 import java.util.Map;
 
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.PreParsePluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.loggers.debug.DebugLogger;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.protocols.ldap.LDAPAttribute;
-import org.opends.server.types.Entry;
-import org.opends.server.types.LDAPException;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.AttributeValue;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.ObjectClass;
-import org.opends.server.types.Operation;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.RawAttribute;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 import org.opends.server.types.operation.PostResponseAddOperation;
 import org.opends.server.types.operation.PreParseAddOperation;
 import org.opends.server.workflowelement.localbackend.LocalBackendAddOperation;
@@ -105,9 +87,6 @@
   // not be a valid DN.
   private ByteString rawEntryDN;
 
-  // The cancel request that has been issued for this add operation.
-  private CancelRequest cancelRequest;
-
   // The processed DN of the entry to add.
   private DN entryDN;
 
@@ -562,19 +541,6 @@
   }
 
 
-
-  /**
-   * {@inheritDoc}
-   */
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, Message message
-  )
-  {
-    clientConnection.disconnect(disconnectReason, sendNotification,
-            message);
-  }
-
-
   /**
    * {@inheritDoc}
    */
@@ -694,67 +660,6 @@
   }
 
 
-  /**
-   * {@inheritDoc}
-   */
-  public final CancelResult cancel(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-
-    CancelResult cancelResult = getCancelResult();
-    long stopWaitingTime = System.currentTimeMillis() + 5000;
-    while ((cancelResult == null) &&
-           (System.currentTimeMillis() < stopWaitingTime))
-    {
-      try
-      {
-        Thread.sleep(50);
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-      }
-
-      cancelResult = getCancelResult();
-    }
-
-    if (cancelResult == null)
-    {
-      // This can happen in some rare cases (e.g., if a client disconnects and
-      // there is still a lot of data to send to that client), and in this case
-      // we'll prevent the cancel thread from blocking for a long period of
-      // time.
-      cancelResult = CancelResult.CANNOT_CANCEL;
-    }
-
-    return cancelResult;
-  }
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public final CancelRequest getCancelRequest()
-  {
-    return cancelRequest;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public
-  boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-    return true;
-  }
-
-
 
   /**
    * {@inheritDoc}
@@ -783,81 +688,50 @@
    */
   public final void run()
   {
-    // Start the processing timer.
-    setProcessingStartTime();
     setResultCode(ResultCode.UNDEFINED);
 
+    // Start the processing timer.
+    setProcessingStartTime();
 
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
-    {
-      indicateCancelled(cancelRequest);
-      setProcessingStopTime();
-      return;
-    }
-
+    // Log the add request message.
+    logAddRequest(this);
 
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
       DirectoryServer.getPluginConfigManager();
 
-
     // This flag is set to true as soon as a workflow has been executed.
     boolean workflowExecuted = false;
 
-
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-addProcessing:
+    try
     {
+      // Check for and handle a request to cancel this operation.
+      checkIfCanceled(false);
+
       // Invoke the pre-parse add plugins.
-      PreParsePluginResult preParseResult =
+      PluginResult.PreParse preParseResult =
         pluginConfigManager.invokePreParseAddPlugins(this);
-      if (preParseResult.connectionTerminated())
+
+      if(!preParseResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the request and
-        // result and return.
-        setResultCode(ResultCode.CANCELED);
-
-        appendErrorMessage(ERR_CANCELED_BY_PREPARSE_DISCONNECT.get());
-
-        setProcessingStopTime();
-
-        logAddRequest(this);
-        logAddResponse(this);
-        pluginConfigManager.invokePostResponseAddPlugins(this);
+        setResultCode(preParseResult.getResultCode());
+        appendErrorMessage(preParseResult.getErrorMessage());
+        setMatchedDN(preParseResult.getMatchedDN());
+        setReferralURLs(preParseResult.getReferralURLs());
         return;
       }
-      else if (preParseResult.sendResponseImmediately())
-      {
-        logAddRequest(this);
-        break addProcessing;
-      }
-      else if (preParseResult.skipCoreProcessing())
-      {
-        break addProcessing;
-      }
 
-      // Log the add request message.
-      logAddRequest(this);
-
-
-      // Check for a request to cancel this operation.
-      if (cancelRequest != null)
-      {
-        break addProcessing;
-      }
-
+      // Check for and handle a request to cancel this operation.
+      checkIfCanceled(false);
 
       // Process the entry DN and set of attributes to convert them from their
       // raw forms as provided by the client to the forms required for the rest
       // of the add processing.
       DN entryDN = getEntryDN();
       if (entryDN == null){
-        break addProcessing;
+        return;
       }
 
-
       // Retrieve the network group attached to the client connection
       // and get a workflow to process the operation.
       NetworkGroup ng = getClientConnection().getNetworkGroup();
@@ -867,61 +741,54 @@
         // We have found no workflow for the requested base DN, just return
         // a no such entry result code and stop the processing.
         updateOperationErrMsgAndResCode();
-        break addProcessing;
+        return;
       }
       workflow.execute(this);
       workflowExecuted = true;
 
-    } // end of processing block
-
-
-    // Check for a terminated connection.
-    if (getCancelResult() == CancelResult.CANCELED)
-    {
-      // Stop the processing timer.
-      setProcessingStopTime();
-
-      // Log the add response message.
-      logAddResponse(this);
-
-      return;
     }
-
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
+    catch(CanceledOperationException coe)
     {
-      indicateCancelled(cancelRequest);
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, coe);
+      }
 
+      setResultCode(ResultCode.CANCELED);
+      cancelResult = new CancelResult(ResultCode.CANCELED, null);
+
+      appendErrorMessage(coe.getCancelRequest().getCancelReason());
+    }
+    finally
+    {
       // Stop the processing timer.
       setProcessingStopTime();
 
+      if(cancelRequest == null || cancelResult == null ||
+          cancelResult.getResultCode() != ResultCode.CANCELED ||
+          cancelRequest.notifyOriginalRequestor() ||
+          DirectoryServer.notifyAbandonedOperations())
+      {
+        clientConnection.sendResponse(this);
+      }
+
+
       // Log the add response message.
       logAddResponse(this);
 
+      // Notifies any persistent searches that might be registered with the
+      // server.
+      notifyPersistentSearches(workflowExecuted);
+
       // Invoke the post-response add plugins.
       invokePostResponsePlugins(workflowExecuted);
 
-      return;
+      // If no cancel result, set it
+      if(cancelResult == null)
+      {
+        cancelResult = new CancelResult(ResultCode.TOO_LATE, null);
+      }
     }
-
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
-
-    // Stop the processing timer.
-    setProcessingStopTime();
-
-    // Send the add response to the client.
-    clientConnection.sendResponse(this);
-
-    // Log the add response message.
-    logAddResponse(this);
-
-    // Notifies any persistent searches that might be registered with the
-    // server.
-    notifyPersistentSearches(workflowExecuted);
-
-    // Invoke the post-response add plugins.
-    invokePostResponsePlugins(workflowExecuted);
   }
 
 
diff --git a/opends/src/server/org/opends/server/core/BindOperationBasis.java b/opends/src/server/org/opends/server/core/BindOperationBasis.java
index fe44ac6..89dc056 100644
--- a/opends/src/server/org/opends/server/core/BindOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/BindOperationBasis.java
@@ -47,25 +47,11 @@
 import java.util.List;
 
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.PreParsePluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.loggers.debug.DebugLogger;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.AuthenticationInfo;
-import org.opends.server.types.AuthenticationType;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.Entry;
-import org.opends.server.types.Operation;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.DisconnectReason;
+import org.opends.server.types.*;
 import org.opends.server.types.operation.PreParseBindOperation;
 import org.opends.server.workflowelement.localbackend.*;
 
@@ -184,6 +170,9 @@
     responseControls         = new ArrayList<Control>(0);
     authFailureReason        = null;
     saslAuthUserEntry        = null;
+
+    cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL,
+        ERR_CANNOT_CANCEL_BIND.get());
   }
 
 
@@ -233,6 +222,9 @@
     responseControls       = new ArrayList<Control>(0);
     authFailureReason      = null;
     saslAuthUserEntry      = null;
+
+    cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL,
+        ERR_CANNOT_CANCEL_BIND.get());
   }
 
 
@@ -288,6 +280,9 @@
     authFailureReason        = null;
     saslAuthUserEntry        = null;
     userEntryDN              = null;
+
+    cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL,
+        ERR_CANNOT_CANCEL_BIND.get());
   }
 
 
@@ -336,6 +331,9 @@
     authFailureReason      = null;
     saslAuthUserEntry      = null;
     userEntryDN            = null;
+
+    cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL,
+        ERR_CANNOT_CANCEL_BIND.get());
   }
 
 
@@ -551,18 +549,6 @@
    * {@inheritDoc}
    */
   @Override()
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, Message message
-  )
-  {
-    clientConnection.disconnect(disconnectReason, sendNotification,
-            message);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
   public final String[][] getRequestLogElements()
   {
     // Note that no debugging will be done in this method because it is a likely
@@ -681,35 +667,6 @@
     responseControls.remove(control);
   }
 
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelResult cancel(CancelRequest cancelRequest)
-  {
-    cancelRequest.addResponseMessage(ERR_CANNOT_CANCEL_BIND.get());
-    return CancelResult.CANNOT_CANCEL;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelRequest getCancelRequest()
-  {
-    return null;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public
-  boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    // Bind operations cannot be canceled.
-    return false;
-  }
 
   /**
    * {@inheritDoc}
@@ -761,12 +718,16 @@
    */
   public final void run()
   {
+    setResultCode(ResultCode.UNDEFINED);
+
     // Start the processing timer and initially set the result to indicate that
     // the result is unknown.
     setProcessingStartTime();
-    ClientConnection clientConnection = getClientConnection();
 
-    setResultCode(ResultCode.UNDEFINED);
+    // Log the bind request message.
+    logBindRequest(this);
+
+    ClientConnection clientConnection = getClientConnection();
 
     // Set a flag to indicate that a bind operation is in progress.  This should
     // ensure that no new operations will be accepted for this client until the
@@ -785,53 +746,33 @@
 
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
-      DirectoryServer.getPluginConfigManager();
+        DirectoryServer.getPluginConfigManager();
 
 
     // This flag is set to true as soon as a workflow has been executed.
     boolean workflowExecuted = false;
 
 
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-bindProcessing:
+    try
     {
       // Invoke the pre-parse bind plugins.
-      PreParsePluginResult preParseResult =
-        pluginConfigManager.invokePreParseBindPlugins(this);
-      if (preParseResult.connectionTerminated())
+      PluginResult.PreParse preParseResult =
+          pluginConfigManager.invokePreParseBindPlugins(this);
+      if (!preParseResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the request and
-        // result and return.
-        setResultCode(ResultCode.CANCELED);
-
-        appendErrorMessage(ERR_CANCELED_BY_PREPARSE_DISCONNECT.get());
-
-        setProcessingStopTime();
-
-        logBindRequest(this);
-        logBindResponse(this);
-        clientConnection.setBindInProgress(false);
+        setResultCode(preParseResult.getResultCode());
+        appendErrorMessage(preParseResult.getErrorMessage());
+        setMatchedDN(preParseResult.getMatchedDN());
+        setReferralURLs(preParseResult.getReferralURLs());
         return;
       }
-      else if (preParseResult.sendResponseImmediately())
-      {
-        logBindRequest(this);
-        break bindProcessing;
-      }
-      else if (preParseResult.skipCoreProcessing())
-      {
-        break bindProcessing;
-      }
 
-      // Log the bind request message.
-      logBindRequest(this);
 
       // Process the bind DN to convert it from the raw form as provided by the
       // client into the form required for the rest of the bind processing.
       DN bindDN = getBindDN();
       if (bindDN == null){
-        break bindProcessing;
+        return;
       }
 
       // If this is a simple bind
@@ -840,12 +781,12 @@
       // for that user.
       switch (getAuthenticationType())
       {
-      case SIMPLE:
-        DN actualRootDN = DirectoryServer.getActualRootBindDN(bindDN);
-        if (actualRootDN != null)
-        {
-          bindDN = actualRootDN;
-        }
+        case SIMPLE:
+          DN actualRootDN = DirectoryServer.getActualRootBindDN(bindDN);
+          if (actualRootDN != null)
+          {
+            bindDN = actualRootDN;
+          }
       }
 
 
@@ -858,43 +799,45 @@
         // We have found no workflow for the requested base DN, just return
         // a no such entry result code and stop the processing.
         updateOperationErrMsgAndResCode();
-        break bindProcessing;
+        return;
       }
       workflow.execute(this);
       workflowExecuted = true;
 
-    } // end of processing block
-
-    // Check for a terminated connection.
-    if (getCancelResult() == CancelResult.CANCELED)
+    }
+    catch(CanceledOperationException coe)
     {
+      // This shouldn't happen for bind operations. Just cancel anyways
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, coe);
+      }
+
+      setResultCode(ResultCode.CANCELED);
+
+      appendErrorMessage(cancelRequest.getCancelReason());
+    }
+    finally
+    {
+      // If the bind processing is finished, then unset the "bind in progress"
+      // flag to allow other operations to be processed on the connection.
+      if (getResultCode() != ResultCode.SASL_BIND_IN_PROGRESS)
+      {
+        clientConnection.setBindInProgress(false);
+      }
+
       // Stop the processing timer.
       setProcessingStopTime();
 
-      // Log the bind response message.
+      // Send the bind response to the client.
+      clientConnection.sendResponse(this);
+
+      // Log the bind response.
       logBindResponse(this);
 
-      return;
+      // Invoke the post-response bind plugins.
+      invokePostResponsePlugins(workflowExecuted);
     }
-
-    // If the bind processing is finished, then unset the "bind in progress"
-    // flag to allow other operations to be processed on the connection.
-    if (getResultCode() != ResultCode.SASL_BIND_IN_PROGRESS)
-    {
-      clientConnection.setBindInProgress(false);
-    }
-
-    // Stop the processing timer.
-    setProcessingStopTime();
-
-    // Send the bind response to the client.
-    clientConnection.sendResponse(this);
-
-    // Log the bind response.
-    logBindResponse(this);
-
-    // Invoke the post-response bind plugins.
-    invokePostResponsePlugins(workflowExecuted);
   }
 
 
diff --git a/opends/src/server/org/opends/server/core/CompareOperationBasis.java b/opends/src/server/org/opends/server/core/CompareOperationBasis.java
index 14b0b78..794dbea 100644
--- a/opends/src/server/org/opends/server/core/CompareOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/CompareOperationBasis.java
@@ -25,7 +25,6 @@
  *      Copyright 2007-2008 Sun Microsystems, Inc.
  */
 package org.opends.server.core;
-import org.opends.messages.Message;
 import org.opends.messages.MessageBuilder;
 
 import static org.opends.server.core.CoreConstants.*;
@@ -38,24 +37,11 @@
 import java.util.List;
 
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.PreParsePluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.loggers.debug.DebugLogger;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.Entry;
-import org.opends.server.types.Operation;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 import org.opends.server.types.operation.PostResponseCompareOperation;
 import org.opends.server.types.operation.PreParseCompareOperation;
 import org.opends.server.workflowelement.localbackend.
@@ -86,9 +72,6 @@
   // The raw, unprocessed entry DN as included in the client request.
   private ByteString rawEntryDN;
 
-  // The cancel request that has been issued for this compare operation.
-  private CancelRequest cancelRequest;
-
   // The DN of the entry for the compare operation.
   private DN entryDN;
 
@@ -287,20 +270,6 @@
    * {@inheritDoc}
    */
   @Override()
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, Message message
-  )
-  {
-    clientConnection.disconnect(disconnectReason, sendNotification,
-            message);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
   public final String[][] getRequestLogElements()
   {
     // Note that no debugging will be done in this method because it is a likely
@@ -456,63 +425,36 @@
     // Start the processing timer.
     setProcessingStartTime();
 
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
-    {
-      indicateCancelled(cancelRequest);
-      setProcessingStopTime();
-      return;
-    }
+    // Log the compare request message.
+    logCompareRequest(this);
 
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
-         DirectoryServer.getPluginConfigManager();
+        DirectoryServer.getPluginConfigManager();
 
     // This flag is set to true as soon as a workflow has been executed.
     boolean workflowExecuted = false;
 
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-compareProcessing:
+    try
     {
+      // Check for and handle a request to cancel this operation.
+      checkIfCanceled(false);
+
       // Invoke the pre-parse compare plugins.
-      PreParsePluginResult preParseResult =
-           pluginConfigManager.invokePreParseComparePlugins(this);
-      if (preParseResult.connectionTerminated())
+      PluginResult.PreParse preParseResult =
+          pluginConfigManager.invokePreParseComparePlugins(this);
+      if(!preParseResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the request and
-        // result and return.
-        setResultCode(ResultCode.CANCELED);
-
-        appendErrorMessage(ERR_CANCELED_BY_PREPARSE_DISCONNECT.get());
-
-        setProcessingStopTime();
-
-        logCompareRequest(this);
-        logCompareResponse(this);
-        pluginConfigManager.invokePostResponseComparePlugins(this);
+        setResultCode(preParseResult.getResultCode());
+        appendErrorMessage(preParseResult.getErrorMessage());
+        setMatchedDN(preParseResult.getMatchedDN());
+        setReferralURLs(preParseResult.getReferralURLs());
         return;
       }
-      else if (preParseResult.sendResponseImmediately())
-      {
-        logCompareRequest(this);
-        break compareProcessing;
-      }
-      else if (preParseResult.skipCoreProcessing())
-      {
-        break compareProcessing;
-      }
-
-
-      // Log the compare request message.
-      logCompareRequest(this);
 
 
       // Check for a request to cancel this operation.
-      if (cancelRequest != null)
-      {
-        break compareProcessing;
-      }
+      checkIfCanceled(false);
 
 
       // Process the entry DN to convert it from the raw form to the form
@@ -534,7 +476,7 @@
         setResultCode(de.getResultCode());
         appendErrorMessage(de.getMessageObject());
 
-        break compareProcessing;
+        return;
       }
 
 
@@ -547,58 +489,50 @@
         // We have found no workflow for the requested base DN, just return
         // a no such entry result code and stop the processing.
         updateOperationErrMsgAndResCode();
-        break compareProcessing;
+        return;
       }
       workflow.execute(this);
       workflowExecuted = true;
 
-    } // end of processing block
-
-
-    // Check for a terminated connection.
-    if (getCancelResult() == CancelResult.CANCELED)
-    {
-      // Stop the processing timer.
-      setProcessingStopTime();
-
-      // Log the add response message.
-      logCompareResponse(this);
-
-      return;
     }
-
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
+    catch(CanceledOperationException coe)
     {
-      indicateCancelled(cancelRequest);
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, coe);
+      }
 
+      setResultCode(ResultCode.CANCELED);
+      cancelResult = new CancelResult(ResultCode.CANCELED, null);
+
+      appendErrorMessage(coe.getCancelRequest().getCancelReason());
+    }
+    finally
+    {
       // Stop the processing timer.
       setProcessingStopTime();
 
+      if(cancelRequest == null || cancelResult == null ||
+          cancelResult.getResultCode() != ResultCode.CANCELED ||
+          cancelRequest.notifyOriginalRequestor() ||
+          DirectoryServer.notifyAbandonedOperations())
+      {
+        clientConnection.sendResponse(this);
+      }
+
+
       // Log the compare response message.
       logCompareResponse(this);
 
       // Invoke the post-response compare plugins.
       invokePostResponsePlugins(workflowExecuted);
 
-      return;
+      // If no cancel result, set it
+      if(cancelResult == null)
+      {
+        cancelResult = new CancelResult(ResultCode.TOO_LATE, null);
+      }
     }
-
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
-
-    // Stop the processing timer.
-    setProcessingStopTime();
-
-    // Send the compare response to the client.
-    clientConnection.sendResponse(this);
-
-    // Log the compare response message.
-    logCompareResponse(this);
-
-    // Invoke the post-response compare plugins.
-    invokePostResponsePlugins(workflowExecuted);
-
   }
 
 
@@ -658,70 +592,6 @@
   }
 
 
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelResult cancel(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-
-    CancelResult cancelResult = getCancelResult();
-    long stopWaitingTime = System.currentTimeMillis() + 5000;
-    while ((cancelResult == null) &&
-           (System.currentTimeMillis() < stopWaitingTime))
-    {
-      try
-      {
-        Thread.sleep(50);
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-      }
-
-      cancelResult = getCancelResult();
-    }
-
-    if (cancelResult == null)
-    {
-      // This can happen in some rare cases (e.g., if a client disconnects and
-      // there is still a lot of data to send to that client), and in this case
-      // we'll prevent the cancel thread from blocking for a long period of
-      // time.
-      cancelResult = CancelResult.CANNOT_CANCEL;
-    }
-
-    return cancelResult;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelRequest getCancelRequest()
-  {
-    return cancelRequest;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-    return true;
-  }
-
-
 
   /**
    * {@inheritDoc}
diff --git a/opends/src/server/org/opends/server/core/DeleteOperationBasis.java b/opends/src/server/org/opends/server/core/DeleteOperationBasis.java
index 60ddb22..07e2761 100644
--- a/opends/src/server/org/opends/server/core/DeleteOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/DeleteOperationBasis.java
@@ -47,23 +47,11 @@
 import java.util.List;
 
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.PreParsePluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.loggers.debug.DebugLogger;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.Entry;
-import org.opends.server.types.Operation;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 import org.opends.server.types.operation.PostResponseDeleteOperation;
 import org.opends.server.types.operation.PreParseDeleteOperation;
 import org.opends.server.workflowelement.localbackend.*;
@@ -88,9 +76,6 @@
   // The raw, unprocessed entry DN as included in the client request.
   private ByteString rawEntryDN;
 
-  // The cancel request that has been issued for this delete operation.
-  private CancelRequest cancelRequest;
-
   // The DN of the entry for the delete operation.
   private DN entryDN;
 
@@ -235,18 +220,6 @@
     return OperationType.DELETE;
   }
 
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, Message message
-  )
-  {
-    clientConnection.disconnect(disconnectReason, sendNotification,
-            message);
-  }
-
 
   /**
    * {@inheritDoc}
@@ -369,66 +342,6 @@
    * {@inheritDoc}
    */
   @Override()
-  public final CancelResult cancel(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-
-    CancelResult cancelResult = getCancelResult();
-    long stopWaitingTime = System.currentTimeMillis() + 5000;
-    while ((cancelResult == null) &&
-           (System.currentTimeMillis() < stopWaitingTime))
-    {
-      try
-      {
-        Thread.sleep(50);
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-      }
-
-      cancelResult = getCancelResult();
-    }
-
-    if (cancelResult == null)
-    {
-      // This can happen in some rare cases (e.g., if a client disconnects and
-      // there is still a lot of data to send to that client), and in this case
-      // we'll prevent the cancel thread from blocking for a long period of
-      // time.
-      cancelResult = CancelResult.CANNOT_CANCEL;
-    }
-
-    return cancelResult;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelRequest getCancelRequest()
-  {
-    return cancelRequest;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public
-  boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-    return true;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
   public final void toString(StringBuilder buffer)
   {
     buffer.append("DeleteOperation(connID=");
@@ -454,74 +367,43 @@
   {
     setResultCode(ResultCode.UNDEFINED);
 
-    // Get the plugin config manager that will be used for invoking plugins.
-    PluginConfigManager pluginConfigManager =
-         DirectoryServer.getPluginConfigManager();
-
     // Start the processing timer.
     setProcessingStartTime();
 
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
-    {
-      indicateCancelled(cancelRequest);
-      setProcessingStopTime();
-      return;
-    }
+    // Log the delete request message.
+    logDeleteRequest(this);
 
+    // Get the plugin config manager that will be used for invoking plugins.
+    PluginConfigManager pluginConfigManager =
+        DirectoryServer.getPluginConfigManager();
 
     // This flag is set to true as soon as a workflow has been executed.
     boolean workflowExecuted = false;
 
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-deleteProcessing:
+    try
     {
       // Invoke the pre-parse delete plugins.
-      PreParsePluginResult preParseResult =
-           pluginConfigManager.invokePreParseDeletePlugins(this);
-      if (preParseResult.connectionTerminated())
+      PluginResult.PreParse preParseResult =
+          pluginConfigManager.invokePreParseDeletePlugins(this);
+      if(!preParseResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the request and
-        // result and return.
-        setResultCode(ResultCode.CANCELED);
-
-        appendErrorMessage(ERR_CANCELED_BY_PREPARSE_DISCONNECT.get());
-
-        setProcessingStopTime();
-
-        logDeleteRequest(this);
-        logDeleteResponse(this);
-        pluginConfigManager.invokePostResponseDeletePlugins(this);
+        setResultCode(preParseResult.getResultCode());
+        appendErrorMessage(preParseResult.getErrorMessage());
+        setMatchedDN(preParseResult.getMatchedDN());
+        setReferralURLs(preParseResult.getReferralURLs());
         return;
       }
-      else if (preParseResult.sendResponseImmediately())
-      {
-        logDeleteRequest(this);
-        break deleteProcessing;
-      }
-      else if (preParseResult.skipCoreProcessing())
-      {
-        break deleteProcessing;
-      }
-
-
-      // Log the delete request message.
-      logDeleteRequest(this);
 
 
       // Check for a request to cancel this operation.
-      if (cancelRequest != null)
-      {
-        break deleteProcessing;
-      }
+      checkIfCanceled(false);
 
 
       // Process the entry DN to convert it from its raw form as provided by the
       // client to the form required for the rest of the delete processing.
       DN entryDN = getEntryDN();
       if (entryDN == null){
-        break deleteProcessing;
+        return;
       }
 
 
@@ -534,61 +416,54 @@
         // We have found no workflow for the requested base DN, just return
         // a no such entry result code and stop the processing.
         updateOperationErrMsgAndResCode();
-        break deleteProcessing;
+        return;
       }
       workflow.execute(this);
       workflowExecuted = true;
 
-    } // end of processing block
-
-
-    // Check for a terminated connection.
-    if (getCancelResult() == CancelResult.CANCELED)
-    {
-      // Stop the processing timer.
-      setProcessingStopTime();
-
-      // Log the add response message.
-      logDeleteResponse(this);
-
-      return;
     }
-
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
+    catch(CanceledOperationException coe)
     {
-      indicateCancelled(cancelRequest);
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, coe);
+      }
 
+      setResultCode(ResultCode.CANCELED);
+      cancelResult = new CancelResult(ResultCode.CANCELED, null);
+
+      appendErrorMessage(coe.getCancelRequest().getCancelReason());
+    }
+    finally
+    {
       // Stop the processing timer.
       setProcessingStopTime();
 
-      // Log the delete response message.
+      if(cancelRequest == null || cancelResult == null ||
+          cancelResult.getResultCode() != ResultCode.CANCELED ||
+          cancelRequest.notifyOriginalRequestor() ||
+          DirectoryServer.notifyAbandonedOperations())
+      {
+        clientConnection.sendResponse(this);
+      }
+
+
+      // Log the delete response.
       logDeleteResponse(this);
 
+      // Notifies any persistent searches that might be registered with the
+      // server.
+      notifyPersistentSearches(workflowExecuted);
+
       // Invoke the post-response delete plugins.
       invokePostResponsePlugins(workflowExecuted);
 
-      return;
+      // If no cancel result, set it
+      if(cancelResult == null)
+      {
+        cancelResult = new CancelResult(ResultCode.TOO_LATE, null);
+      }
     }
-
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
-
-    // Stop the processing timer.
-    setProcessingStopTime();
-
-    // Send the delete response to the client.
-    getClientConnection().sendResponse(this);
-
-    // Log the delete response.
-    logDeleteResponse(this);
-
-    // Notifies any persistent searches that might be registered with the
-    // server.
-    notifyPersistentSearches(workflowExecuted);
-
-    // Invoke the post-response delete plugins.
-    invokePostResponsePlugins(workflowExecuted);
   }
 
 
diff --git a/opends/src/server/org/opends/server/core/DirectoryServer.java b/opends/src/server/org/opends/server/core/DirectoryServer.java
index ad15df0..cea6268 100644
--- a/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -71,7 +71,7 @@
 import org.opends.server.api.WorkQueue;
 import org.opends.server.api.AccessControlHandler;
 import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.StartupPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.backends.RootDSEBackend;
 import static org.opends.server.config.ConfigConstants.DN_MONITOR_ROOT;
 import static org.opends.server.config.ConfigConstants.ENV_VAR_INSTANCE_ROOT;
@@ -1414,9 +1414,9 @@
       workQueue = new WorkQueueConfigManager().initializeWorkQueue();
 
 
-      StartupPluginResult startupPluginResult =
+      PluginResult.Startup startupPluginResult =
            pluginConfigManager.invokeStartupPlugins();
-      if (! startupPluginResult.continueStartup())
+      if (! startupPluginResult.continueProcessing())
       {
         Message message = ERR_STARTUP_PLUGIN_ERROR.
             get(startupPluginResult.getErrorMessage(),
diff --git a/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java b/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
index d321428..195ee47 100644
--- a/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
@@ -25,7 +25,6 @@
  *      Copyright 2006-2008 Sun Microsystems, Inc.
  */
 package org.opends.server.core;
-import org.opends.messages.Message;
 import org.opends.messages.MessageBuilder;
 
 
@@ -35,18 +34,8 @@
 
 import org.opends.server.api.ClientConnection;
 import org.opends.server.api.ExtendedOperationHandler;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
-import org.opends.server.api.plugin.PreParsePluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.DN;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
 import org.opends.server.types.operation.PostOperationExtendedOperation;
 import org.opends.server.types.operation.PostResponseExtendedOperation;
 import org.opends.server.types.operation.PreOperationExtendedOperation;
@@ -58,7 +47,7 @@
 
 import org.opends.server.loggers.debug.DebugLogger;
 import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.DebugLogLevel;
+import org.opends.server.types.*;
 import static org.opends.messages.CoreMessages.*;
 import static org.opends.server.util.ServerConstants.*;
 
@@ -90,9 +79,6 @@
   // Indicates whether a response has yet been sent for this operation.
   private boolean responseSent;
 
-  // The cancel request that has been issued for this extended operation.
-  private CancelRequest cancelRequest;
-
   // The set of response controls for this extended operation.
   private List<Control> responseControls;
 
@@ -134,6 +120,17 @@
     responseControls = new ArrayList<Control>();
     cancelRequest    = null;
     responseSent     = false;
+
+    if (requestOID.equals(OID_CANCEL_REQUEST))
+    {
+      cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL,
+          ERR_CANNOT_CANCEL_CANCEL.get());
+    }
+    if(requestOID.equals(OID_START_TLS_REQUEST))
+    {
+      cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL,
+          ERR_CANNOT_CANCEL_START_TLS.get());
+    }
   }
 
 
@@ -243,20 +240,6 @@
    * {@inheritDoc}
    */
   @Override()
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, Message message
-  )
-  {
-    clientConnection.disconnect(disconnectReason, sendNotification,
-            message);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
   public final String[][] getRequestLogElements()
   {
     // Note that no debugging will be done in this method because it is a likely
@@ -384,82 +367,36 @@
   {
     setResultCode(ResultCode.UNDEFINED);
 
+    // Start the processing timer.
+    setProcessingStartTime();
+
+    // Log the extended request message.
+    logExtendedRequest(this);
 
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
          DirectoryServer.getPluginConfigManager();
-    boolean skipPostOperation = false;
 
-
-    // Start the processing timer.
-    setProcessingStartTime();
-
-
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
+    try
     {
-      if (! (requestOID.equals(OID_CANCEL_REQUEST) ||
-             requestOID.equals(OID_START_TLS_REQUEST)))
-      {
-        indicateCancelled(cancelRequest);
-        setProcessingStopTime();
-        return;
-      }
-    }
-
-
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-extendedProcessing:
-    {
-      // Invoke the pre-parse extended plugins.
-      PreParsePluginResult preParseResult =
-           pluginConfigManager.invokePreParseExtendedPlugins(this);
-      if (preParseResult.connectionTerminated())
-      {
-        // There's no point in continuing with anything.  Log the request and
-        // result and return.
-        setResultCode(ResultCode.CANCELED);
-
-        appendErrorMessage(ERR_CANCELED_BY_PREPARSE_DISCONNECT.get());
-
-        setProcessingStopTime();
-
-        logExtendedRequest(this);
-        logExtendedResponse(this);
-        pluginConfigManager.invokePostResponseExtendedPlugins(this);
-        return;
-      }
-      else if (preParseResult.sendResponseImmediately())
-      {
-        skipPostOperation = true;
-        logExtendedRequest(this);
-        break extendedProcessing;
-      }
-      else if (preParseResult.skipCoreProcessing())
-      {
-        skipPostOperation = false;
-        break extendedProcessing;
-      }
-
-
-      // Log the extended request message.
-      logExtendedRequest(this);
-
-
       // Check for and handle a request to cancel this operation.
-      if (cancelRequest != null)
+      checkIfCanceled(false);
+
+      // Invoke the pre-parse extended plugins.
+      PluginResult.PreParse preParseResult =
+           pluginConfigManager.invokePreParseExtendedPlugins(this);
+
+      if(!preParseResult.continueProcessing())
       {
-        if (! (requestOID.equals(OID_CANCEL_REQUEST) ||
-               requestOID.equals(OID_START_TLS_REQUEST)))
-        {
-          indicateCancelled(cancelRequest);
-          setProcessingStopTime();
-          pluginConfigManager.invokePostResponseExtendedPlugins(this);
-          return;
-        }
+        setResultCode(preParseResult.getResultCode());
+        appendErrorMessage(preParseResult.getErrorMessage());
+        setMatchedDN(preParseResult.getMatchedDN());
+        setReferralURLs(preParseResult.getReferralURLs());
+        return;
       }
 
+      checkIfCanceled(false);
+
 
       // Get the extended operation handler for the request OID.  If there is
       // none, then fail.
@@ -470,7 +407,7 @@
         setResultCode(ResultCode.UNWILLING_TO_PERFORM);
         appendErrorMessage(ERR_EXTENDED_NO_HANDLER.get(
                 String.valueOf(requestOID)));
-        break extendedProcessing;
+        return;
       }
 
 
@@ -488,8 +425,7 @@
 
             appendErrorMessage(ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(
                     c.getOID()));
-            skipPostOperation=true;
-            break extendedProcessing;
+            return;
           }
           if (! c.isCritical())
           {
@@ -504,7 +440,7 @@
                     String.valueOf(requestOID),
                     c.getOID()));
 
-            break extendedProcessing;
+            return;
           }
         }
       }
@@ -523,102 +459,77 @@
         appendErrorMessage(ERR_EXTENDED_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS.get(
                 String.valueOf(requestOID)));
 
-        skipPostOperation = true;
-        break extendedProcessing;
-      }
-
-      // Invoke the pre-operation extended plugins.
-      PreOperationPluginResult preOpResult =
-           pluginConfigManager.invokePreOperationExtendedPlugins(this);
-      if (preOpResult.connectionTerminated())
-      {
-        // There's no point in continuing with anything.  Log the result
-        // and return.
-        setResultCode(ResultCode.CANCELED);
-
-        appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-        setProcessingStopTime();
-
-        logExtendedResponse(this);
-        pluginConfigManager.invokePostResponseExtendedPlugins(this);
         return;
       }
-      else if (preOpResult.sendResponseImmediately())
-      {
-        skipPostOperation = true;
-        break extendedProcessing;
-      }
-      else if (preOpResult.skipCoreProcessing())
-      {
-        skipPostOperation = false;
-        break extendedProcessing;
-      }
 
-
-      // Check for and handle a request to cancel this operation.
-      if (cancelRequest != null)
+      try
       {
-        if (! (requestOID.equals(OID_CANCEL_REQUEST) ||
-               requestOID.equals(OID_START_TLS_REQUEST)))
+        // Invoke the pre-operation extended plugins.
+        PluginResult.PreOperation preOpResult =
+            pluginConfigManager.invokePreOperationExtendedPlugins(this);
+        if(!preOpResult.continueProcessing())
         {
-          indicateCancelled(cancelRequest);
-          setProcessingStopTime();
-          pluginConfigManager.invokePostResponseExtendedPlugins(this);
+          setResultCode(preParseResult.getResultCode());
+          appendErrorMessage(preParseResult.getErrorMessage());
+          setMatchedDN(preParseResult.getMatchedDN());
+          setReferralURLs(preParseResult.getReferralURLs());
           return;
         }
+
+        checkIfCanceled(false);
+
+        // Actually perform the processing for this operation.
+        handler.processExtendedOperation(this);
+
+      }
+      finally
+      {
+        pluginConfigManager.invokePostOperationExtendedPlugins(this);
+      }
+
+    }
+    catch(CanceledOperationException coe)
+    {
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, coe);
+      }
+
+      setResultCode(ResultCode.CANCELED);
+      cancelResult = new CancelResult(ResultCode.CANCELED, null);
+
+      appendErrorMessage(coe.getCancelRequest().getCancelReason());
+    }
+    finally
+    {
+      // Stop the processing timer.
+      setProcessingStopTime();
+
+      // Send the response to the client, if it has not already been sent.
+      if (! responseSent)
+      {
+        responseSent = true;
+        if(cancelRequest == null || cancelResult == null ||
+            cancelResult.getResultCode() != ResultCode.CANCELED ||
+            cancelRequest.notifyOriginalRequestor() ||
+            DirectoryServer.notifyAbandonedOperations())
+        {
+          clientConnection.sendResponse(this);
+        }
       }
 
+      // Log the extended response.
+      logExtendedResponse(this);
 
-      // Actually perform the processing for this operation.
-      handler.processExtendedOperation(this);
-    }
+      // Invoke the post-response extended plugins.
+      pluginConfigManager.invokePostResponseExtendedPlugins(this);
 
-
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
-
-
-    // Invoke the post-operation extended plugins.
-    if (! skipPostOperation)
-    {
-      PostOperationPluginResult postOpResult =
-           pluginConfigManager.invokePostOperationExtendedPlugins(this);
-      if (postOpResult.connectionTerminated())
+      // If no cancel result, set it
+      if(cancelResult == null)
       {
-        // There's no point in continuing with anything.  Log the result and
-        // return.
-        setResultCode(ResultCode.CANCELED);
-
-        appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-
-        setProcessingStopTime();
-
-        logExtendedResponse(this);
-        pluginConfigManager.invokePostResponseExtendedPlugins(this);
-        return;
+        cancelResult = new CancelResult(ResultCode.TOO_LATE, null);
       }
     }
-
-
-    // Stop the processing timer.
-    setProcessingStopTime();
-
-
-    // Send the response to the client, if it has not already been sent.
-    if (! responseSent)
-    {
-      responseSent = true;
-      clientConnection.sendResponse(this);
-    }
-
-
-    // Log the extended response.
-    logExtendedResponse(this);
-
-
-
-    // Invoke the post-response extended plugins.
-    pluginConfigManager.invokePostResponseExtendedPlugins(this);
   }
 
 
@@ -652,73 +563,6 @@
     this.responseSent = true;
   }
 
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelResult cancel(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-
-    CancelResult cancelResult = getCancelResult();
-    long stopWaitingTime = System.currentTimeMillis() + 5000;
-    while ((cancelResult == null) &&
-           (System.currentTimeMillis() < stopWaitingTime))
-    {
-      try
-      {
-        Thread.sleep(50);
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-      }
-
-      cancelResult = getCancelResult();
-    }
-
-    if (cancelResult == null)
-    {
-      // This can happen in some rare cases (e.g., if a client disconnects and
-      // there is still a lot of data to send to that client), and in this case
-      // we'll prevent the cancel thread from blocking for a long period of
-      // time.
-      cancelResult = CancelResult.CANNOT_CANCEL;
-    }
-
-    return cancelResult;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelRequest getCancelRequest()
-  {
-    return cancelRequest;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-    return true;
-  }
-
-
-
   /**
    * {@inheritDoc}
    */
diff --git a/opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java b/opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java
index 392d1c2..306e8f6 100644
--- a/opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java
@@ -32,28 +32,14 @@
 import java.util.Iterator;
 import java.util.List;
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.PreParsePluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.Modification;
-import org.opends.server.types.Operation;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.RDN;
-import org.opends.server.types.ResultCode;
 import org.opends.server.types.operation.PostResponseModifyDNOperation;
 import org.opends.server.types.operation.PreParseModifyDNOperation;
 import static org.opends.server.core.CoreConstants.*;
 import static org.opends.server.loggers.AccessLogger.*;
 
-import org.opends.server.types.DebugLogLevel;
+import org.opends.server.types.*;
 import org.opends.server.workflowelement.localbackend.*;
 
 import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -94,9 +80,6 @@
   // client.
   private ByteString rawNewSuperior;
 
-  // The cancel request issued for this modify DN operation.
-  private CancelRequest cancelRequest;
-
   // The current DN of the entry.
   private DN entryDN;
 
@@ -451,19 +434,6 @@
    * {@inheritDoc}
    */
   @Override()
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, Message message
-  )
-  {
-    clientConnection.disconnect(disconnectReason, sendNotification,
-            message);
-  }
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
   public final String[][] getRequestLogElements()
   {
     // Note that no debugging will be done in this method because it is a likely
@@ -608,68 +578,40 @@
   {
     setResultCode(ResultCode.UNDEFINED);
 
-    // Get the plugin config manager that will be used for invoking plugins.
-    PluginConfigManager pluginConfigManager =
-      DirectoryServer.getPluginConfigManager();
-
     // Start the processing timer.
     setProcessingStartTime();
 
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
-    {
-      indicateCancelled(cancelRequest);
-      setProcessingStopTime();
-      return;
-    }
+    // Log the modify DN request message.
+    logModifyDNRequest(this);
 
+    // Get the plugin config manager that will be used for invoking plugins.
+    PluginConfigManager pluginConfigManager =
+        DirectoryServer.getPluginConfigManager();
 
     // This flag is set to true as soon as a workflow has been executed.
     boolean workflowExecuted = false;
 
 
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-modifyDNProcessing:
+    try
     {
+      // Check for and handle a request to cancel this operation.
+      checkIfCanceled(false);
+
       // Invoke the pre-parse modify DN plugins.
-      PreParsePluginResult preParseResult =
-        pluginConfigManager.invokePreParseModifyDNPlugins(this);
-      if (preParseResult.connectionTerminated())
+      PluginResult.PreParse preParseResult =
+          pluginConfigManager.invokePreParseModifyDNPlugins(this);
+
+      if(!preParseResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the request and
-        // result and return.
-        setResultCode(ResultCode.CANCELED);
-
-        appendErrorMessage(ERR_CANCELED_BY_PREPARSE_DISCONNECT.get());
-
-        setProcessingStopTime();
-
-        logModifyDNRequest(this);
-        logModifyDNResponse(this);
-        pluginConfigManager.invokePostResponseModifyDNPlugins(this);
+        setResultCode(preParseResult.getResultCode());
+        appendErrorMessage(preParseResult.getErrorMessage());
+        setMatchedDN(preParseResult.getMatchedDN());
+        setReferralURLs(preParseResult.getReferralURLs());
         return;
       }
-      else if (preParseResult.sendResponseImmediately())
-      {
-        logModifyDNRequest(this);
-        break modifyDNProcessing;
-      }
-      else if (preParseResult.skipCoreProcessing())
-      {
-        break modifyDNProcessing;
-      }
 
-
-      // Log the modify DN request message.
-      logModifyDNRequest(this);
-
-
-      // Check for a request to cancel this operation.
-      if (cancelRequest != null)
-      {
-        break modifyDNProcessing;
-      }
+      // Check for and handle a request to cancel this operation.
+      checkIfCanceled(false);
 
       // 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
@@ -677,7 +619,7 @@
       DN entryDN = getEntryDN();
       if (entryDN == null)
       {
-        break modifyDNProcessing;
+        return;
       }
 
       // Retrieve the network group attached to the client connection
@@ -689,59 +631,52 @@
         // We have found no workflow for the requested base DN, just return
         // a no such entry result code and stop the processing.
         updateOperationErrMsgAndResCode();
-        break modifyDNProcessing;
+        return;
       }
       workflow.execute(this);
       workflowExecuted = true;
     }
-
-    // Check for a terminated connection.
-    if (getCancelResult() == CancelResult.CANCELED)
+    catch(CanceledOperationException coe)
     {
-      // Stop the processing timer.
-      setProcessingStopTime();
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, coe);
+      }
 
-      // Log the add response message.
-      logModifyDNResponse(this);
+      setResultCode(ResultCode.CANCELED);
+      cancelResult = new CancelResult(ResultCode.CANCELED, null);
 
-      return;
+      appendErrorMessage(coe.getCancelRequest().getCancelReason());
     }
-
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
+    finally
     {
-      indicateCancelled(cancelRequest);
-
       // Stop the processing timer.
       setProcessingStopTime();
 
-      // Log the modify DN response message.
+      if(cancelRequest == null || cancelResult == null ||
+          cancelResult.getResultCode() != ResultCode.CANCELED ||
+          cancelRequest.notifyOriginalRequestor() ||
+          DirectoryServer.notifyAbandonedOperations())
+      {
+        clientConnection.sendResponse(this);
+      }
+
+      // Log the modify DN response.
       logModifyDNResponse(this);
 
+      // Notifies any persistent searches that might be registered with the
+      // server.
+      notifyPersistentSearches(workflowExecuted);
+
       // Invoke the post-response modify DN plugins.
       invokePostResponsePlugins(workflowExecuted);
 
-      return;
+      // If no cancel result, set it
+      if(cancelResult == null)
+      {
+        cancelResult = new CancelResult(ResultCode.TOO_LATE, null);
+      }
     }
-
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
-
-    // Stop the processing timer.
-    setProcessingStopTime();
-
-    // Send the modify DN response to the client.
-    clientConnection.sendResponse(this);
-
-    // Log the modify DN response.
-    logModifyDNResponse(this);
-
-    // Notifies any persistent searches that might be registered with the
-    // server.
-    notifyPersistentSearches(workflowExecuted);
-
-    // Invoke the post-response modify DN plugins.
-    invokePostResponsePlugins(workflowExecuted);
   }
 
 
@@ -862,68 +797,6 @@
    * {@inheritDoc}
    */
   @Override()
-  public final CancelResult cancel(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-
-    CancelResult cancelResult = getCancelResult();
-    long stopWaitingTime = System.currentTimeMillis() + 5000;
-    while ((cancelResult == null) &&
-        (System.currentTimeMillis() < stopWaitingTime))
-    {
-      try
-      {
-        Thread.sleep(50);
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-      }
-
-      cancelResult = getCancelResult();
-    }
-
-    if (cancelResult == null)
-    {
-      // This can happen in some rare cases (e.g., if a client disconnects and
-      // there is still a lot of data to send to that client), and in this case
-      // we'll prevent the cancel thread from blocking for a long period of
-      // time.
-      cancelResult = CancelResult.CANNOT_CANCEL;
-    }
-
-    return cancelResult;
-  }
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelRequest getCancelRequest()
-  {
-    return cancelRequest;
-  }
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-    return true;
-  }
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
   public final void toString(StringBuilder buffer)
   {
     buffer.append("ModifyDNOperation(connID=");
diff --git a/opends/src/server/org/opends/server/core/ModifyOperationBasis.java b/opends/src/server/org/opends/server/core/ModifyOperationBasis.java
index 8024586..752a3b5 100644
--- a/opends/src/server/org/opends/server/core/ModifyOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/ModifyOperationBasis.java
@@ -48,29 +48,13 @@
 import java.util.List;
 
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.PreParsePluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.loggers.debug.DebugLogger;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.protocols.ldap.LDAPAttribute;
-import org.opends.server.types.LDAPException;
 import org.opends.server.protocols.ldap.LDAPModification;
-import org.opends.server.types.AttributeValue;
-import org.opends.server.types.Entry;
-import org.opends.server.types.Operation;
-import org.opends.server.types.RawModification;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.Modification;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 import org.opends.server.types.operation.PostResponseModifyOperation;
 import org.opends.server.types.operation.PreParseModifyOperation;
 import org.opends.server.workflowelement.localbackend.*;
@@ -111,9 +95,6 @@
   // The set of modifications for this modify operation.
   private List<Modification> modifications;
 
-  // The cancel request that has been issued for this modify operation.
-  CancelRequest cancelRequest;
-
   // The change number that has been assigned to this operation.
   private long changeNumber;
 
@@ -295,17 +276,6 @@
   /**
    * {@inheritDoc}
    */
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, Message message
-  )
-  {
-    clientConnection.disconnect(disconnectReason, sendNotification,
-            message);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
   public final OperationType getOperationType()
   {
     // Note that no debugging will be done in this method because it is a likely
@@ -429,62 +399,6 @@
   /**
    * {@inheritDoc}
    */
-  public final CancelResult cancel(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-
-    CancelResult cancelResult = getCancelResult();
-    long stopWaitingTime = System.currentTimeMillis() + 5000;
-    while ((cancelResult == null) &&
-        (System.currentTimeMillis() < stopWaitingTime))
-    {
-      try
-      {
-        Thread.sleep(50);
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-      }
-
-      cancelResult = getCancelResult();
-    }
-
-    if (cancelResult == null)
-    {
-      // This can happen in some rare cases (e.g., if a client disconnects and
-      // there is still a lot of data to send to that client), and in this case
-      // we'll prevent the cancel thread from blocking for a long period of
-      // time.
-      cancelResult = CancelResult.CANNOT_CANCEL;
-    }
-
-    return cancelResult;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  public final CancelRequest getCancelRequest()
-  {
-    return cancelRequest;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  public boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-    return true;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
   public final void toString(StringBuilder buffer)
   {
     buffer.append("ModifyOperation(connID=");
@@ -526,73 +440,47 @@
   {
     setResultCode(ResultCode.UNDEFINED);
 
-    // Get the plugin config manager that will be used for invoking plugins.
-    PluginConfigManager pluginConfigManager =
-         DirectoryServer.getPluginConfigManager();
-
     // Start the processing timer.
     setProcessingStartTime();
 
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
-    {
-      indicateCancelled(cancelRequest);
-      setProcessingStopTime();
-      return;
-    }
+    // Log the modify request message.
+    logModifyRequest(this);
 
+    // Get the plugin config manager that will be used for invoking plugins.
+    PluginConfigManager pluginConfigManager =
+        DirectoryServer.getPluginConfigManager();
 
     // This flag is set to true as soon as a workflow has been executed.
     boolean workflowExecuted = false;
 
 
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-modifyProcessing:
+    try
     {
+      // Check for and handle a request to cancel this operation.
+      checkIfCanceled(false);
+
       // Invoke the pre-parse modify plugins.
-      PreParsePluginResult preParseResult =
-           pluginConfigManager.invokePreParseModifyPlugins(this);
-      if (preParseResult.connectionTerminated())
+      PluginResult.PreParse preParseResult =
+          pluginConfigManager.invokePreParseModifyPlugins(this);
+
+      if(!preParseResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the request and
-        // result and return.
-        setResultCode(ResultCode.CANCELED);
-
-        appendErrorMessage(ERR_CANCELED_BY_PREPARSE_DISCONNECT.get());
-
-        setProcessingStopTime();
-
-        logModifyRequest(this);
-        logModifyResponse(this);
-        pluginConfigManager.invokePostResponseModifyPlugins(this);
+        setResultCode(preParseResult.getResultCode());
+        appendErrorMessage(preParseResult.getErrorMessage());
+        setMatchedDN(preParseResult.getMatchedDN());
+        setReferralURLs(preParseResult.getReferralURLs());
         return;
       }
-      else if (preParseResult.sendResponseImmediately())
-      {
-        logModifyRequest(this);
-        break modifyProcessing;
-      }
-      else if (preParseResult.skipCoreProcessing())
-      {
-        break modifyProcessing;
-      }
 
-      // Log the modify request message.
-      logModifyRequest(this);
-
-      // Check for a request to cancel this operation.
-      if (getCancelRequest() != null)
-      {
-        break modifyProcessing;
-      }
+      // Check for and handle a request to cancel this operation.
+      checkIfCanceled(false);
 
 
       // Process the entry DN to convert it from the raw form to the form
       // required for the rest of the modify processing.
       DN entryDN = getEntryDN();
       if (entryDN == null){
-        break modifyProcessing;
+        return;
       }
 
 
@@ -605,61 +493,53 @@
         // We have found no workflow for the requested base DN, just return
         // a no such entry result code and stop the processing.
         updateOperationErrMsgAndResCode();
-        break modifyProcessing;
+        return;
       }
       workflow.execute(this);
       workflowExecuted = true;
 
-    } // end of processing block
-
-
-    // Check for a terminated connection.
-    if (getCancelResult() == CancelResult.CANCELED)
-    {
-      // Stop the processing timer.
-      setProcessingStopTime();
-
-      // Log the add response message.
-      logModifyResponse(this);
-
-      return;
     }
-
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
+    catch(CanceledOperationException coe)
     {
-      indicateCancelled(cancelRequest);
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, coe);
+      }
 
+      setResultCode(ResultCode.CANCELED);
+      cancelResult = new CancelResult(ResultCode.CANCELED, null);
+
+      appendErrorMessage(coe.getCancelRequest().getCancelReason());
+    }
+    finally
+    {
       // Stop the processing timer.
       setProcessingStopTime();
 
-      // Log the modify response message.
+      if(cancelRequest == null || cancelResult == null ||
+          cancelResult.getResultCode() != ResultCode.CANCELED ||
+          cancelRequest.notifyOriginalRequestor() ||
+          DirectoryServer.notifyAbandonedOperations())
+      {
+        clientConnection.sendResponse(this);
+      }
+
+      // Log the modify response.
       logModifyResponse(this);
 
-      // Invoke the post-response modify plugins.
+      // Notifies any persistent searches that might be registered with the
+      // server.
+      notifyPersistentSearches(workflowExecuted);
+
+      // Invoke the post-response add plugins.
       invokePostResponsePlugins(workflowExecuted);
 
-      return;
+      // If no cancel result, set it
+      if(cancelResult == null)
+      {
+        cancelResult = new CancelResult(ResultCode.TOO_LATE, null);
+      }
     }
-
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
-
-    // Stop the processing timer.
-    setProcessingStopTime();
-
-    // Send the modify response to the client.
-    getClientConnection().sendResponse(this);
-
-    // Log the modify response.
-    logModifyResponse(this);
-
-    // Notifies any persistent searches that might be registered with the
-    // server.
-    notifyPersistentSearches(workflowExecuted);
-
-    // Invoke the post-response modify plugins.
-    invokePostResponsePlugins(workflowExecuted);
   }
 
 
diff --git a/opends/src/server/org/opends/server/core/OperationWrapper.java b/opends/src/server/org/opends/server/core/OperationWrapper.java
index 31389bf..5027094 100644
--- a/opends/src/server/org/opends/server/core/OperationWrapper.java
+++ b/opends/src/server/org/opends/server/core/OperationWrapper.java
@@ -33,16 +33,7 @@
 import java.util.Map;
 
 import org.opends.server.api.ClientConnection;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.Entry;
-import org.opends.server.types.Operation;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 
 
 /**
@@ -108,6 +99,14 @@
   /**
    * {@inheritDoc}
    */
+  public void abort(CancelRequest cancelRequest)
+  {
+    operation.abort(cancelRequest);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
   public void disconnectClient(
           DisconnectReason disconnectReason,
           boolean sendNotification,
@@ -329,14 +328,6 @@
   /**
    * {@inheritDoc}
    */
-  public void indicateCancelled(CancelRequest cancelRequest)
-  {
-    operation.indicateCancelled(cancelRequest);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
   public boolean isInternalOperation()
   {
     return operation.isInternalOperation();
@@ -417,22 +408,6 @@
   /**
    * {@inheritDoc}
    */
-  public boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    return operation.setCancelRequest(cancelRequest);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  public void setCancelResult(CancelResult cancelResult)
-  {
-    operation.setCancelResult(cancelResult);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
   public void setDontSynchronize(boolean dontSynchronize)
   {
     operation.setDontSynchronize(dontSynchronize);
@@ -465,22 +440,6 @@
   /**
    * {@inheritDoc}
    */
-  public void setProcessingStartTime()
-  {
-    operation.setProcessingStartTime();
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  public void setProcessingStopTime()
-  {
-    operation.setProcessingStopTime();
-  }
-
-  /**
-   * {@inheritDoc}
-   */
   public void setReferralURLs(List<String> referralURLs)
   {
     operation.setReferralURLs(referralURLs);
@@ -518,5 +477,12 @@
     operation.toString(buffer);
   }
 
+  /**
+   * {@inheritDoc}
+   */
+  public synchronized final void checkIfCanceled(boolean signalTooLate)
+      throws CanceledOperationException {
+    operation.checkIfCanceled(signalTooLate);
+  }
 }
 
diff --git a/opends/src/server/org/opends/server/core/PasswordPolicyState.java b/opends/src/server/org/opends/server/core/PasswordPolicyState.java
index 6927dcc..8b6e436 100644
--- a/opends/src/server/org/opends/server/core/PasswordPolicyState.java
+++ b/opends/src/server/org/opends/server/core/PasswordPolicyState.java
@@ -104,10 +104,6 @@
   // should be stored as modifications.
   private final boolean updateEntry;
 
-  // Indicates whether to debug password policy processing performed wth this
-  // state object.
-  private final boolean debug;
-
   // The string representation of the user's DN.
   private final String userDNString;
 
@@ -187,18 +183,15 @@
    * @param  updateEntry  Indicates whether changes should update the provided
    *                      user entry directly or whether they should be
    *                      collected as a set of modifications.
-   * @param  debug        Indicates whether to enable debugging for the
-   *                      operations performed.
    *
    * @throws  DirectoryException  If a problem occurs while attempting to
    *                              determine the password policy for the user or
    *                              perform any other state initialization.
    */
-  public PasswordPolicyState(Entry userEntry, boolean updateEntry,
-                             boolean debug)
+  public PasswordPolicyState(Entry userEntry, boolean updateEntry)
        throws DirectoryException
   {
-    this(userEntry, updateEntry, TimeThread.getTime(), false, debug);
+    this(userEntry, updateEntry, TimeThread.getTime(), false);
   }
 
 
@@ -219,26 +212,22 @@
    * @param  useDefaultOnError  Indicates whether the server should fall back to
    *                            using the default password policy if there is a
    *                            problem with the configured policy for the user.
-   * @param  debug              Indicates whether to enable debugging for the
-   *                            operations performed.
    *
    * @throws  DirectoryException  If a problem occurs while attempting to
    *                              determine the password policy for the user or
    *                              perform any other state initialization.
    */
   public PasswordPolicyState(Entry userEntry, boolean updateEntry,
-                             long currentTime, boolean useDefaultOnError,
-                             boolean debug)
+                             long currentTime, boolean useDefaultOnError)
        throws DirectoryException
   {
     this.userEntry   = userEntry;
     this.updateEntry = updateEntry;
-    this.debug       = debug;
     this.currentTime = currentTime;
 
     userDNString     = userEntry.getDN().toString();
     passwordPolicy   = getPasswordPolicyInternal(this.userEntry,
-                                                 useDefaultOnError, this.debug);
+                                                 useDefaultOnError);
 
     // Get the password changed time for the user.
     AttributeType type
@@ -266,7 +255,7 @@
       {
         passwordChangedTime = 0;
 
-        if (debug)
+        if (debugEnabled())
         {
           TRACER.debugWarning("Could not determine password changed time for " +
               "user %s.", userDNString);
@@ -287,8 +276,6 @@
    * @param  useDefaultOnError  Indicates whether the server should fall back to
    *                            using the default password policy if there is a
    *                            problem with the configured policy for the user.
-   * @param  debug              Indicates whether to enable debugging for the
-   *                            operations performed.
    *
    * @return  The password policy for the user.
    *
@@ -296,7 +283,7 @@
    *                              determine the password policy for the user.
    */
   private static PasswordPolicy getPasswordPolicyInternal(Entry userEntry,
-                                     boolean useDefaultOnError, boolean debug)
+                                     boolean useDefaultOnError)
        throws DirectoryException
   {
     String userDNString = userEntry.getDN().toString();
@@ -323,7 +310,7 @@
             TRACER.debugCaught(DebugLogLevel.ERROR, e);
           }
 
-          if (debug)
+          if (debugEnabled())
           {
             TRACER.debugError("Could not parse password policy subentry " +
                 "DN %s for user %s: %s",
@@ -348,7 +335,7 @@
         PasswordPolicy policy = DirectoryServer.getPasswordPolicy(subentryDN);
         if (policy == null)
         {
-          if (debug)
+          if (debugEnabled())
           {
             TRACER.debugError("Password policy subentry %s for user %s " +
                  "is not defined in the Directory Server.",
@@ -369,27 +356,21 @@
           }
         }
 
-        if (debug)
+        if (debugEnabled())
         {
-            if (debugEnabled())
-            {
-              TRACER.debugInfo("Using password policy subentry %s for user %s.",
-                        String.valueOf(subentryDN), userDNString);
-            }
-          }
+          TRACER.debugInfo("Using password policy subentry %s for user %s.",
+              String.valueOf(subentryDN), userDNString);
+        }
 
         return policy;
       }
     }
 
     // There is no policy subentry defined: use the default.
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Using the default password policy for user %s",
-                  userDNString);
-      }
+      TRACER.debugInfo("Using the default password policy for user %s",
+          userDNString);
     }
 
     return DirectoryServer.getDefaultPasswordPolicy();
@@ -421,24 +402,21 @@
       }
     }
 
-    if (debug)
+    if (stringValue == null)
     {
-      if (stringValue == null)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning null because attribute %s does not " +
-              "exist in user entry %s",
-                    attributeType.getNameOrOID(), userDNString);
-        }
+        TRACER.debugInfo("Returning null because attribute %s does not " +
+            "exist in user entry %s",
+            attributeType.getNameOrOID(), userDNString);
       }
-      else
+    }
+    else
+    {
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning value %s for user %s",
-                    stringValue, userDNString);
-        }
+        TRACER.debugInfo("Returning value %s for user %s",
+            stringValue, userDNString);
       }
     }
 
@@ -482,14 +460,11 @@
           if (debugEnabled())
           {
             TRACER.debugCaught(DebugLogLevel.ERROR, e);
-          }
 
-          if (debug)
-          {
             TRACER.debugWarning("Unable to decode value %s for attribute %s " +
-                 "in user entry %s: %s",
-                         v.getStringValue(), attributeType.getNameOrOID(),
-                         userDNString, stackTraceToSingleLineString(e));
+                "in user entry %s: %s",
+                v.getStringValue(), attributeType.getNameOrOID(),
+                userDNString, stackTraceToSingleLineString(e));
           }
 
           Message message = ERR_PWPSTATE_CANNOT_DECODE_GENERALIZED_TIME.
@@ -502,19 +477,16 @@
       }
     }
 
-    if (debug)
+    if (timeValue == -1)
     {
-      if (timeValue == -1)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning -1 because attribute %s does not " +
-              "exist in user entry %s",
-                    attributeType.getNameOrOID(), userDNString);
-        }
+        TRACER.debugInfo("Returning -1 because attribute %s does not " +
+            "exist in user entry %s",
+            attributeType.getNameOrOID(), userDNString);
       }
-      // FIXME: else to be consistent...
     }
+    // FIXME: else to be consistent...
 
     return timeValue;
   }
@@ -556,14 +528,11 @@
             if (debugEnabled())
             {
               TRACER.debugCaught(DebugLogLevel.ERROR, e);
-            }
 
-            if (debug)
-            {
               TRACER.debugWarning("Unable to decode value %s for attribute %s" +
-                   "in user entry %s: %s",
-                           v.getStringValue(), attributeType.getNameOrOID(),
-                           userDNString, stackTraceToSingleLineString(e));
+                  "in user entry %s: %s",
+                  v.getStringValue(), attributeType.getNameOrOID(),
+                  userDNString, stackTraceToSingleLineString(e));
             }
 
             Message message = ERR_PWPSTATE_CANNOT_DECODE_GENERALIZED_TIME.
@@ -576,16 +545,13 @@
       }
     }
 
-    if (debug)
+    if (timeValues.isEmpty())
     {
-      if (timeValues.isEmpty())
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning an empty list because attribute %s " +
-              "does not exist in user entry %s",
-                    attributeType.getNameOrOID(), userDNString);
-        }
+        TRACER.debugInfo("Returning an empty list because attribute %s " +
+            "does not exist in user entry %s",
+            attributeType.getNameOrOID(), userDNString);
       }
     }
     return timeValues;
@@ -622,13 +588,10 @@
         if (valueString.equals("true") || valueString.equals("yes") ||
             valueString.equals("on") || valueString.equals("1"))
         {
-          if (debug)
+          if (debugEnabled())
           {
-            if (debugEnabled())
-            {
-              TRACER.debugInfo("Attribute %s resolves to true for user entry " +
-                  "%s", attributeType.getNameOrOID(), userDNString);
-            }
+            TRACER.debugInfo("Attribute %s resolves to true for user entry " +
+                "%s", attributeType.getNameOrOID(), userDNString);
           }
 
           return ConditionResult.TRUE;
@@ -637,42 +600,36 @@
         if (valueString.equals("false") || valueString.equals("no") ||
                  valueString.equals("off") || valueString.equals("0"))
         {
-          if (debug)
+          if (debugEnabled())
           {
-            if (debugEnabled())
-            {
-              TRACER.debugInfo("Attribute %s resolves to false for user " +
-                  "entry %s", attributeType.getNameOrOID(), userDNString);
-            }
+            TRACER.debugInfo("Attribute %s resolves to false for user " +
+                "entry %s", attributeType.getNameOrOID(), userDNString);
           }
 
           return ConditionResult.FALSE;
         }
 
-        if (debug)
+        if(debugEnabled())
         {
-            TRACER.debugError("Unable to resolve value %s for attribute %s " +
-                 "in user entry %s as a Boolean.",
-                       valueString, attributeType.getNameOrOID(),
-                       userDNString);
+          TRACER.debugError("Unable to resolve value %s for attribute %s " +
+              "in user entry %s as a Boolean.",
+              valueString, attributeType.getNameOrOID(),
+              userDNString);
         }
 
         Message message = ERR_PWPSTATE_CANNOT_DECODE_BOOLEAN.get(
             valueString, attributeType.getNameOrOID(), userDNString);
         throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
-                                     message);
+            message);
       }
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning %s because attribute %s does not exist " +
-             "in user entry %s",
-                  ConditionResult.UNDEFINED.toString(),
-                  attributeType.getNameOrOID(), userDNString);
-      }
+      TRACER.debugInfo("Returning %s because attribute %s does not exist " +
+          "in user entry %s",
+          ConditionResult.UNDEFINED.toString(),
+          attributeType.getNameOrOID(), userDNString);
     }
 
     return ConditionResult.UNDEFINED;
@@ -759,13 +716,10 @@
    */
   public void setPasswordChangedTime(long passwordChangedTime)
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Setting password changed time for user %s to " +
-            "current time of %d", userDNString, currentTime);
-      }
+      TRACER.debugInfo("Setting password changed time for user %s to " +
+          "current time of %d", userDNString, currentTime);
     }
 
     // passwordChangedTime is computed in the constructor from values in the
@@ -811,13 +765,10 @@
    */
   public void clearPasswordChangedTime()
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Clearing password changed time for user %s",
-                         userDNString);
-      }
+      TRACER.debugInfo("Clearing password changed time for user %s",
+          userDNString);
     }
 
     AttributeType type =
@@ -865,13 +816,10 @@
   {
     if (isDisabled != ConditionResult.UNDEFINED)
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning stored result of %b for user %s",
-                    (isDisabled == ConditionResult.TRUE), userDNString);
-        }
+        TRACER.debugInfo("Returning stored result of %b for user %s",
+            (isDisabled == ConditionResult.TRUE), userDNString);
       }
 
       return isDisabled == ConditionResult.TRUE;
@@ -891,7 +839,7 @@
       }
 
       isDisabled = ConditionResult.TRUE;
-      if (debug)
+      if (debugEnabled())
       {
           TRACER.debugWarning("User %s is considered administratively " +
               "disabled because an error occurred while attempting to make " +
@@ -905,26 +853,20 @@
     if (isDisabled == ConditionResult.UNDEFINED)
     {
       isDisabled = ConditionResult.FALSE;
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("User %s is not administratively disabled since " +
-              "the attribute \"%s\" is not present in the entry.",
-                     userDNString, OP_ATTR_ACCOUNT_DISABLED);
-        }
+        TRACER.debugInfo("User %s is not administratively disabled since " +
+            "the attribute \"%s\" is not present in the entry.",
+            userDNString, OP_ATTR_ACCOUNT_DISABLED);
       }
       return false;
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("User %s %s administratively disabled.",
-                  userDNString,
-                  ((isDisabled == ConditionResult.TRUE) ? " is" : " is not"));
-      }
+      TRACER.debugInfo("User %s %s administratively disabled.",
+          userDNString,
+          ((isDisabled == ConditionResult.TRUE) ? " is" : " is not"));
     }
 
     return isDisabled == ConditionResult.TRUE;
@@ -941,13 +883,10 @@
    */
   public void setDisabled(boolean isDisabled)
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Updating user %s to set the disabled flag to %b",
-                  userDNString, isDisabled);
-      }
+      TRACER.debugInfo("Updating user %s to set the disabled flag to %b",
+          userDNString, isDisabled);
     }
 
 
@@ -1006,13 +945,10 @@
   {
     if (isAccountExpired != ConditionResult.UNDEFINED)
     {
-      if(debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning stored result of %b for user %s",
-                    (isAccountExpired == ConditionResult.TRUE), userDNString);
-        }
+        TRACER.debugInfo("Returning stored result of %b for user %s",
+            (isAccountExpired == ConditionResult.TRUE), userDNString);
       }
 
       return isAccountExpired == ConditionResult.TRUE;
@@ -1034,7 +970,7 @@
       }
 
       isAccountExpired = ConditionResult.TRUE;
-      if (debug)
+      if (debugEnabled())
       {
           TRACER.debugWarning("User %s is considered to have an expired " +
                "account because an error occurred while attempting to make " +
@@ -1049,26 +985,20 @@
     {
       // The user does have an expiration time, but it hasn't arrived yet.
       isAccountExpired = ConditionResult.FALSE;
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("The account for user %s is not expired because " +
-              "the expiration time has not yet arrived.", userDNString);
-        }
+        TRACER.debugInfo("The account for user %s is not expired because " +
+            "the expiration time has not yet arrived.", userDNString);
       }
     }
     else if (accountExpirationTime >= 0)
     {
       // The user does have an expiration time, and it is in the past.
       isAccountExpired = ConditionResult.TRUE;
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("The account for user %s is expired because the " +
-              "expiration time in that account has passed.", userDNString);
-        }
+        TRACER.debugInfo("The account for user %s is expired because the " +
+            "expiration time in that account has passed.", userDNString);
       }
     }
     else
@@ -1076,14 +1006,11 @@
       // The user doesn't have an expiration time in their entry, so it
       // can't be expired.
       isAccountExpired = ConditionResult.FALSE;
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("The account for user %s is not expired because " +
-              "there is no expiration time in the user's entry.",
-          userDNString);
-        }
+        TRACER.debugInfo("The account for user %s is not expired because " +
+            "there is no expiration time in the user's entry.",
+            userDNString);
       }
     }
 
@@ -1126,13 +1053,10 @@
     {
       String timeStr = GeneralizedTimeSyntax.format(accountExpirationTime);
 
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Setting account expiration time for user %s to %s",
-                    userDNString, timeStr);
-        }
+        TRACER.debugInfo("Setting account expiration time for user %s to %s",
+            userDNString, timeStr);
       }
 
       this.accountExpirationTime = accountExpirationTime;
@@ -1167,13 +1091,10 @@
    */
   public void clearAccountExpirationTime()
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Clearing account expiration time for user %s",
-                  userDNString);
-      }
+      TRACER.debugInfo("Clearing account expiration time for user %s",
+          userDNString);
     }
 
     accountExpirationTime = -1;
@@ -1209,14 +1130,11 @@
   {
     if (authFailureTimes != null)
     {
-      if(debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning stored auth failure time list of %d " +
-              "elements for user %s" +
-              authFailureTimes.size(), userDNString);
-        }
+        TRACER.debugInfo("Returning stored auth failure time list of %d " +
+            "elements for user %s" +
+            authFailureTimes.size(), userDNString);
       }
 
       return authFailureTimes;
@@ -1241,7 +1159,7 @@
         TRACER.debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      if (debug)
+      if (debugEnabled())
       {
         TRACER.debugWarning("Error while processing auth failure times " +
              "for user %s: %s",
@@ -1265,14 +1183,11 @@
 
     if (authFailureTimes.isEmpty())
     {
-      if (debug)
+      if (debugEnabled())
       {
-       if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning an empty auth failure time list for " +
-              "user %s because the attribute is absent from the entry.",
-                    userDNString);
-        }
+        TRACER.debugInfo("Returning an empty auth failure time list for " +
+            "user %s because the attribute is absent from the entry.",
+            userDNString);
       }
 
       return authFailureTimes;
@@ -1291,13 +1206,10 @@
         long l = iterator.next();
         if (l < expirationTime)
         {
-          if (debug)
+          if (debugEnabled())
           {
-            if (debugEnabled())
-            {
-              TRACER.debugInfo("Removing expired auth failure time %d for " +
-                  "user %s", l, userDNString);
-            }
+            TRACER.debugInfo("Removing expired auth failure time %d for " +
+                "user %s", l, userDNString);
           }
 
           iterator.remove();
@@ -1345,13 +1257,10 @@
       }
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning auth failure time list of %d elements " +
-            "for user %s", authFailureTimes.size(), userDNString);
-      }
+      TRACER.debugInfo("Returning auth failure time list of %d elements " +
+          "for user %s", authFailureTimes.size(), userDNString);
     }
 
     return authFailureTimes;
@@ -1371,13 +1280,10 @@
       return;
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Updating authentication failure times for user %s",
-                  userDNString);
-      }
+      TRACER.debugInfo("Updating authentication failure times for user %s",
+          userDNString);
     }
 
 
@@ -1440,13 +1346,10 @@
     if ((lockoutCount > 0) && (lockoutCount <= authFailureTimes.size()))
     {
       setFailureLockedTime(highestFailureTime);
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Locking user account %s due to too many failures.",
-                    userDNString);
-        }
+        TRACER.debugInfo("Locking user account %s due to too many failures.",
+            userDNString);
       }
     }
   }
@@ -1507,13 +1410,10 @@
     if ((lockoutCount > 0) && (lockoutCount <= authFailureTimes.size()))
     {
       setFailureLockedTime(highestFailureTime);
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Locking user account %s due to too many failures.",
-                    userDNString);
-        }
+        TRACER.debugInfo("Locking user account %s due to too many failures.",
+            userDNString);
       }
     }
   }
@@ -1526,13 +1426,10 @@
    */
   private void clearAuthFailureTimes()
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Clearing authentication failure times for user %s",
-                  userDNString);
-      }
+      TRACER.debugInfo("Clearing authentication failure times for user %s",
+          userDNString);
     }
 
     List<Long> failureTimes = getAuthFailureTimes();
@@ -1596,7 +1493,7 @@
       }
 
       failureLockedTime = currentTime;
-      if (debug)
+      if (debugEnabled())
       {
         TRACER.debugWarning("Returning current time for user %s because an " +
             "error occurred: %s",
@@ -1659,13 +1556,10 @@
    */
   private void clearFailureLockedTime()
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Clearing failure lockout time for user %s.",
-                         userDNString);
-      }
+      TRACER.debugInfo("Clearing failure lockout time for user %s.",
+          userDNString);
     }
 
     if (-1L == getFailureLockedTime())
@@ -1719,13 +1613,10 @@
     final int maxFailures = passwordPolicy.getLockoutFailureCount();
     if (maxFailures <= 0)
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning false for user %s because lockout due " +
-              "to failures is not enabled.", userDNString);
-        }
+        TRACER.debugInfo("Returning false for user %s because lockout due " +
+            "to failures is not enabled.", userDNString);
       }
 
       return false;
@@ -1750,13 +1641,10 @@
       // failure times might have accumulated to trigger a lockout.
       if (getAuthFailureTimes().size() < maxFailures)
       {
-        if (debug)
+        if (debugEnabled())
         {
-          if (debugEnabled())
-          {
-            TRACER.debugInfo("Returning false for user %s because there is " +
-                "no locked time.", userDNString);
-          }
+          TRACER.debugInfo("Returning false for user %s because there is " +
+              "no locked time.", userDNString);
         }
 
         return false;
@@ -1765,14 +1653,11 @@
       // The account isn't locked but should be, so do so now.
       setFailureLockedTime(currentTime);// FIXME: set to max(failureTimes)?
 
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Locking user %s because there were enough " +
-              "existing failures even though there was no account locked time.",
-                    userDNString);
-        }
+        TRACER.debugInfo("Locking user %s because there were enough " +
+            "existing failures even though there was no account locked time.",
+            userDNString);
       }
       // Fall through...
     }
@@ -1786,14 +1671,11 @@
       {
         secondsUntilUnlock = (int) ((unlockTime - currentTime) / 1000);
 
-        if (debug)
+        if (debugEnabled())
         {
-          if (debugEnabled())
-          {
-            TRACER.debugInfo("Returning true for user %s because there is a " +
-                "locked time and the lockout duration has not been reached.",
-                      userDNString);
-          }
+          TRACER.debugInfo("Returning true for user %s because there is a " +
+              "locked time and the lockout duration has not been reached.",
+              userDNString);
         }
 
         return true;
@@ -1802,27 +1684,21 @@
       // The lockout in the entry has expired...
       clearFailureLockout();
 
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning false for user %s " +
-               "because the existing lockout has expired.", userDNString);
-        }
+        TRACER.debugInfo("Returning false for user %s " +
+            "because the existing lockout has expired.", userDNString);
       }
 
       assert -1L == getFailureLockedTime();
       return false;
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning true for user %s " +
-             "because there is a locked time and no lockout duration.",
-                  userDNString);
-      }
+      TRACER.debugInfo("Returning true for user %s " +
+          "because there is a locked time and no lockout duration.",
+          userDNString);
     }
 
     assert -1L <= getFailureLockedTime();
@@ -1875,13 +1751,10 @@
   {
     if (lastLoginTime != Long.MIN_VALUE)
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning stored last login time of %d for " +
-              "user %s.", lastLoginTime, userDNString);
-        }
+        TRACER.debugInfo("Returning stored last login time of %d for " +
+            "user %s.", lastLoginTime, userDNString);
       }
 
       return lastLoginTime;
@@ -1895,13 +1768,10 @@
     if ((type == null) || (format == null))
     {
       lastLoginTime = -1;
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning -1 for user %s because no last login " +
-              "time will be maintained.", userDNString);
-        }
+        TRACER.debugInfo("Returning -1 for user %s because no last login " +
+            "time will be maintained.", userDNString);
       }
 
       return lastLoginTime;
@@ -1923,14 +1793,11 @@
           SimpleDateFormat dateFormat = new SimpleDateFormat(format);
           lastLoginTime = dateFormat.parse(valueString).getTime();
 
-          if (debug)
+          if (debugEnabled())
           {
-            if (debugEnabled())
-            {
-              TRACER.debugInfo("Returning last login time of %d for user %s" +
-                   "decoded using current last login time format.",
-                        lastLoginTime, userDNString);
-              }
+            TRACER.debugInfo("Returning last login time of %d for user %s" +
+                "decoded using current last login time format.",
+                lastLoginTime, userDNString);
           }
 
           return lastLoginTime;
@@ -1951,14 +1818,11 @@
               SimpleDateFormat dateFormat = new SimpleDateFormat(f);
               lastLoginTime = dateFormat.parse(valueString).getTime();
 
-              if (debug)
+              if (debugEnabled())
               {
-                if (debugEnabled())
-                {
-                  TRACER.debugInfo("Returning last login time of %d for " +
-                      "user %s decoded using previous last login time format " +
-                      "of %s.", lastLoginTime, userDNString, f);
-                }
+                TRACER.debugInfo("Returning last login time of %d for " +
+                    "user %s decoded using previous last login time format " +
+                    "of %s.", lastLoginTime, userDNString, f);
               }
 
               return lastLoginTime;
@@ -1973,7 +1837,7 @@
           }
 
           assert lastLoginTime == -1;
-          if (debug)
+          if (debugEnabled())
           {
               TRACER.debugWarning("Returning -1 for user %s because the " +
                   "last login time value %s could not be parsed using any " +
@@ -1986,13 +1850,10 @@
     }
 
     assert lastLoginTime == -1;
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning %d for user %s because no last " +
-            "login time value exists.", lastLoginTime, userDNString);
-      }
+      TRACER.debugInfo("Returning %d for user %s because no last " +
+          "login time value exists.", lastLoginTime, userDNString);
     }
 
     return lastLoginTime;
@@ -2041,7 +1902,7 @@
         TRACER.debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      if (debug)
+      if (debugEnabled())
       {
         TRACER.debugWarning("Unable to set last login time for user %s " +
             "because an error occurred: %s",
@@ -2055,14 +1916,11 @@
     String existingTimestamp = getValue(type);
     if ((existingTimestamp != null) && timestamp.equals(existingTimestamp))
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Not updating last login time for user %s " +
-              "because the new value matches the existing value.",
-                           userDNString);
-        }
+        TRACER.debugInfo("Not updating last login time for user %s " +
+            "because the new value matches the existing value.",
+            userDNString);
       }
 
       return;
@@ -2085,13 +1943,10 @@
       modifications.add(new Modification(ModificationType.REPLACE, a, true));
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Updated the last login time for user %s to %s",
-                  userDNString, timestamp);
-      }
+      TRACER.debugInfo("Updated the last login time for user %s to %s",
+          userDNString, timestamp);
     }
   }
 
@@ -2103,12 +1958,9 @@
    */
   public void clearLastLoginTime()
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Clearing last login time for user %s", userDNString);
-      }
+      TRACER.debugInfo("Clearing last login time for user %s", userDNString);
     }
 
     lastLoginTime = -1;
@@ -2140,13 +1992,10 @@
   {
     if (isIdleLocked != ConditionResult.UNDEFINED)
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning stored result of %b for user %s",
-                    (isIdleLocked == ConditionResult.TRUE), userDNString);
-        }
+        TRACER.debugInfo("Returning stored result of %b for user %s",
+            (isIdleLocked == ConditionResult.TRUE), userDNString);
       }
 
       return isIdleLocked == ConditionResult.TRUE;
@@ -2158,15 +2007,11 @@
     {
       isIdleLocked = ConditionResult.FALSE;
 
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning false for user %s because no idle " +
-              "lockout interval is defined.", userDNString);
-        }
+        TRACER.debugInfo("Returning false for user %s because no idle " +
+            "lockout interval is defined.", userDNString);
       }
-
       return false;
     }
 
@@ -2178,44 +2023,38 @@
     if (lastLoginTime > lockTime || passwordChangedTime > lockTime)
     {
       isIdleLocked = ConditionResult.FALSE;
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
+        StringBuilder reason = new StringBuilder();
+        if(lastLoginTime > lockTime)
         {
-          StringBuilder reason = new StringBuilder();
-          if(lastLoginTime > lockTime)
-          {
-            reason.append("the last login time is in an acceptable window");
-          }
-          else
-          {
-            if(lastLoginTime < 0)
-            {
-              reason.append("there is no last login time, but ");
-            }
-            reason.append(
-                 "the password changed time is in an acceptable window");
-          }
-          TRACER.debugInfo("Returning false for user %s because %s.",
-                    userDNString, reason.toString());
+          reason.append("the last login time is in an acceptable window");
         }
+        else
+        {
+          if(lastLoginTime < 0)
+          {
+            reason.append("there is no last login time, but ");
+          }
+          reason.append(
+              "the password changed time is in an acceptable window");
+        }
+        TRACER.debugInfo("Returning false for user %s because %s.",
+            userDNString, reason.toString());
       }
     }
     else
     {
       isIdleLocked = ConditionResult.TRUE;
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          String reason = (lastLoginTime < 0)
-             ? "there is no last login time and the password " +
-                  "changed time is not in an acceptable window"
-             : "neither last login time nor password " +
-                  "changed time are in an acceptable window";
-          TRACER.debugInfo("Returning true for user %s because %s.",
-                    userDNString, reason);
-        }
+        String reason = (lastLoginTime < 0)
+            ? "there is no last login time and the password " +
+            "changed time is not in an acceptable window"
+            : "neither last login time nor password " +
+            "changed time are in an acceptable window";
+        TRACER.debugInfo("Returning true for user %s because %s.",
+            userDNString, reason);
       }
     }
 
@@ -2235,13 +2074,10 @@
   {
     if(mustChangePassword != ConditionResult.UNDEFINED)
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning stored result of %b for user %s.",
-                    (mustChangePassword == ConditionResult.TRUE), userDNString);
-        }
+        TRACER.debugInfo("Returning stored result of %b for user %s.",
+            (mustChangePassword == ConditionResult.TRUE), userDNString);
       }
 
       return mustChangePassword == ConditionResult.TRUE;
@@ -2258,16 +2094,13 @@
                || passwordPolicy.forceChangeOnReset())))
     {
       mustChangePassword = ConditionResult.FALSE;
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning false for user %s because neither " +
-               "force change on add nor force change on reset is enabled, " +
-               "or users are not allowed to self-modify passwords.",
-                    userDNString);
+        TRACER.debugInfo("Returning false for user %s because neither " +
+            "force change on add nor force change on reset is enabled, " +
+            "or users are not allowed to self-modify passwords.",
+            userDNString);
 
-        }
       }
 
       return false;
@@ -2290,41 +2123,33 @@
       if (debugEnabled())
       {
         TRACER.debugCaught(DebugLogLevel.ERROR, e);
-      }
 
-      mustChangePassword = ConditionResult.TRUE;
-      if (debug)
-      {
         TRACER.debugWarning("Returning true for user %s because an error " +
             "occurred: %s", userDNString, stackTraceToSingleLineString(e));
       }
 
+      mustChangePassword = ConditionResult.TRUE;
+
       return true;
     }
 
     if(mustChangePassword == ConditionResult.UNDEFINED)
     {
       mustChangePassword = ConditionResult.FALSE;
-      if(debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning %b for user since the attribute \"%s\"" +
-               " is not present in the entry.",
-                    false, userDNString, OP_ATTR_PWPOLICY_RESET_REQUIRED);
-        }
+        TRACER.debugInfo("Returning %b for user since the attribute \"%s\"" +
+            " is not present in the entry.",
+            false, userDNString, OP_ATTR_PWPOLICY_RESET_REQUIRED);
       }
 
       return false;
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning %b for user %s.",
-                  (mustChangePassword == ConditionResult.TRUE), userDNString);
-      }
+      TRACER.debugInfo("Returning %b for user %s.",
+          (mustChangePassword == ConditionResult.TRUE), userDNString);
     }
 
     return mustChangePassword == ConditionResult.TRUE;
@@ -2341,13 +2166,10 @@
 */
   public void setMustChangePassword(boolean mustChangePassword)
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Updating user %s to set the reset flag to %b",
-                  userDNString, mustChangePassword);
-      }
+      TRACER.debugInfo("Updating user %s to set the reset flag to %b",
+          userDNString, mustChangePassword);
     }
 
     if (mustChangePassword == mustChangePassword())
@@ -2416,13 +2238,10 @@
     // attribute.
     if (passwordPolicy.getMaximumPasswordResetAge() <= 0)
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning false for user %s because there is no " +
-              "maximum reset age.", userDNString);
-        }
+        TRACER.debugInfo("Returning false for user %s because there is no " +
+            "maximum reset age.", userDNString);
       }
 
       return false;
@@ -2430,13 +2249,10 @@
 
     if (! mustChangePassword())
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning false for user %s because the user's " +
-              "password has not been reset.", userDNString);
-        }
+        TRACER.debugInfo("Returning false for user %s because the user's " +
+            "password has not been reset.", userDNString);
       }
 
       return false;
@@ -2446,13 +2262,10 @@
         (1000L * passwordPolicy.getMaximumPasswordResetAge());
     boolean locked = (maxResetTime < currentTime);
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning %b for user %s after comparing the " +
-            "current and max reset times.", locked, userDNString);
-      }
+      TRACER.debugInfo("Returning %b for user %s after comparing the " +
+          "current and max reset times.", locked, userDNString);
     }
 
     return locked;
@@ -2642,13 +2455,10 @@
       }
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning password expiration time of %d for user " +
-            "%s.", passwordExpirationTime, userDNString);
-      }
+      TRACER.debugInfo("Returning password expiration time of %d for user " +
+          "%s.", passwordExpirationTime, userDNString);
     }
 
     return passwordExpirationTime;
@@ -2691,12 +2501,9 @@
     if (minAge <= 0)
     {
       // There is no minimum age, so the user isn't in it.
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning false because there is no minimum age.");
-        }
+        TRACER.debugInfo("Returning false because there is no minimum age.");
       }
 
       return false;
@@ -2704,13 +2511,10 @@
     else if ((passwordChangedTime + (minAge*1000L)) < currentTime)
     {
       // It's been long enough since the user changed their password.
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning false because the minimum age has " +
-              "expired.");
-        }
+        TRACER.debugInfo("Returning false because the minimum age has " +
+            "expired.");
       }
 
       return false;
@@ -2718,13 +2522,10 @@
     else if (mustChangePassword())
     {
       // The user is in a must-change mode, so the minimum age doesn't apply.
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning false because the account is in a " +
-              "must-change state.");
-        }
+        TRACER.debugInfo("Returning false because the account is in a " +
+            "must-change state.");
       }
 
       return false;
@@ -2732,12 +2533,9 @@
     else
     {
       // The user is within the minimum age.
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning true.");
-        }
+        TRACER.debugInfo("Returning true.");
       }
 
       return true;
@@ -2849,13 +2647,10 @@
   {
     if (requiredChangeTime != Long.MIN_VALUE)
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning stored required change time of %d for " +
-              "user %s", requiredChangeTime, userDNString);
-        }
+        TRACER.debugInfo("Returning stored required change time of %d for " +
+            "user %s", requiredChangeTime, userDNString);
       }
 
       return requiredChangeTime;
@@ -2876,7 +2671,7 @@
       }
 
       requiredChangeTime = -1;
-      if (debug)
+      if (debugEnabled())
       {
         TRACER.debugWarning("Returning %d for user %s because an error " +
             "occurred: %s", requiredChangeTime, userDNString,
@@ -2886,13 +2681,10 @@
       return requiredChangeTime;
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning required change time of %d for user %s",
-                  requiredChangeTime, userDNString);
-      }
+      TRACER.debugInfo("Returning required change time of %d for user %s",
+          requiredChangeTime, userDNString);
     }
 
     return requiredChangeTime;
@@ -2924,13 +2716,10 @@
    */
   public void setRequiredChangeTime(long requiredChangeTime)
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Updating required change time for user %s",
-                         userDNString);
-      }
+      TRACER.debugInfo("Updating required change time for user %s",
+          userDNString);
     }
 
     if (getRequiredChangeTime() != requiredChangeTime)
@@ -2968,13 +2757,10 @@
    */
   public void clearRequiredChangeTime()
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Clearing required change time for user %s",
-                         userDNString);
-      }
+      TRACER.debugInfo("Clearing required change time for user %s",
+          userDNString);
     }
 
     AttributeType type = DirectoryServer.getAttributeType(
@@ -3016,7 +2802,7 @@
           TRACER.debugCaught(DebugLogLevel.ERROR, e);
         }
 
-        if (debug)
+        if (debugEnabled())
         {
           TRACER.debugWarning("Unable to decode the warned time for user %s: " +
               "%s", userDNString, stackTraceToSingleLineString(e));
@@ -3027,13 +2813,10 @@
     }
 
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning a warned time of %d for user %s",
-                  warnedTime, userDNString);
-      }
+      TRACER.debugInfo("Returning a warned time of %d for user %s",
+          warnedTime, userDNString);
     }
 
     return warnedTime;
@@ -3063,14 +2846,11 @@
     long warnTime = getWarnedTime();
     if (warnTime == warnedTime)
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Not updating warned time for user %s because " +
-              "the warned time is the same as the specified time.",
-              userDNString);
-        }
+        TRACER.debugInfo("Not updating warned time for user %s because " +
+            "the warned time is the same as the specified time.",
+            userDNString);
       }
 
       return;
@@ -3096,12 +2876,9 @@
       modifications.add(new Modification(ModificationType.REPLACE, a, true));
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Updated the warned time for user %s", userDNString);
-      }
+      TRACER.debugInfo("Updated the warned time for user %s", userDNString);
     }
   }
 
@@ -3112,12 +2889,9 @@
    */
   public void clearWarnedTime()
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Clearing warned time for user %s", userDNString);
-      }
+      TRACER.debugInfo("Clearing warned time for user %s", userDNString);
     }
 
     if (getWarnedTime() < 0)
@@ -3138,12 +2912,9 @@
       modifications.add(new Modification(ModificationType.REPLACE, a, true));
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Cleared the warned time for user %s", userDNString);
-      }
+      TRACER.debugInfo("Cleared the warned time for user %s", userDNString);
     }
   }
 
@@ -3179,7 +2950,7 @@
           TRACER.debugCaught(DebugLogLevel.ERROR, e);
         }
 
-        if (debug)
+        if (debugEnabled())
         {
           TRACER.debugWarning("Error while processing grace login times " +
                "for user %s: %s",
@@ -3201,13 +2972,10 @@
     }
 
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning grace login times for user %s",
-                         userDNString);
-      }
+      TRACER.debugInfo("Returning grace login times for user %s",
+          userDNString);
     }
 
     return graceLoginTimes;
@@ -3241,16 +3009,12 @@
    */
   public void updateGraceLoginTimes()
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Updating grace login times for user %s",
-                         userDNString);
-      }
+      TRACER.debugInfo("Updating grace login times for user %s",
+          userDNString);
     }
 
-
     List<Long> graceTimes = getGraceLoginTimes();
     long highestGraceTime = -1;
     for (Long l : graceTimes)
@@ -3321,17 +3085,12 @@
       return;
     }
 
-
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Updating grace login times for user %s",
-                         userDNString);
-      }
+      TRACER.debugInfo("Updating grace login times for user %s",
+          userDNString);
     }
 
-
     AttributeType type =
          DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_GRACE_LOGIN_TIME_LC,
                                           true);
@@ -3364,13 +3123,10 @@
    */
   public void clearGraceLoginTimes()
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Clearing grace login times for user %s",
-                         userDNString);
-      }
+      TRACER.debugInfo("Clearing grace login times for user %s",
+          userDNString);
     }
 
     List<Long> graceTimes = getGraceLoginTimes();
@@ -3450,7 +3206,7 @@
                     : DirectoryServer.getPasswordStorageScheme(schemeName);
           if (scheme == null)
           {
-            if (debug)
+            if (debugEnabled())
             {
               TRACER.debugWarning("User entry %s contains a password with " +
                   "scheme %s that is not defined in the server.",
@@ -3478,7 +3234,7 @@
             TRACER.debugCaught(DebugLogLevel.ERROR, e);
           }
 
-          if (debug)
+          if (debugEnabled())
           {
             TRACER.debugWarning("Cannot get clear password value foruser %s: " +
                 "%s", userDNString, e);
@@ -3507,14 +3263,11 @@
          userEntry.getAttribute(passwordPolicy.getPasswordAttribute());
     if ((attrList == null) || attrList.isEmpty())
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning false because user %s does not have " +
-              "any values for password attribute %s", userDNString,
-                    passwordPolicy.getPasswordAttribute().getNameOrOID());
-        }
+        TRACER.debugInfo("Returning false because user %s does not have " +
+            "any values for password attribute %s", userDNString,
+            passwordPolicy.getPasswordAttribute().getNameOrOID());
       }
 
       return false;
@@ -3551,7 +3304,7 @@
                      : DirectoryServer.getPasswordStorageScheme(schemeName);
           if (scheme == null)
           {
-            if (debug)
+            if (debugEnabled())
             {
               TRACER.debugWarning("User entry %s contains a password with " +
                   "scheme %s that is not defined in the server.",
@@ -3569,14 +3322,11 @@
                                new ASN1OctetString(pwComponents[1].toString()));
           if (passwordMatches)
           {
-            if (debug)
+            if (debugEnabled())
             {
-              if (debugEnabled())
-              {
-                TRACER.debugInfo("Returning true for user %s because the " +
-                    "provided password matches a value encoded with scheme %s",
-                          userDNString, schemeName);
-              }
+              TRACER.debugInfo("Returning true for user %s because the " +
+                  "provided password matches a value encoded with scheme %s",
+                  userDNString, schemeName);
             }
 
             return true;
@@ -3589,7 +3339,7 @@
             TRACER.debugCaught(DebugLogLevel.ERROR, e);
           }
 
-          if (debug)
+          if (debugEnabled())
           {
             TRACER.debugWarning("An error occurred while attempting to " +
                 "process a password value for user %s: %s",
@@ -3600,14 +3350,11 @@
     }
 
     // If we've gotten here, then we couldn't find a match.
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning false because the provided password does " +
-            "not match any of the stored password values for user %s",
-                  userDNString);
-      }
+      TRACER.debugInfo("Returning false because the provided password does " +
+          "not match any of the stored password values for user %s",
+          userDNString);
     }
 
     return false;
@@ -3706,28 +3453,22 @@
       if (! validator.passwordIsAcceptable(newPassword, currentPasswords,
                                            operation, userEntry, invalidReason))
       {
-        if (debug)
+        if (debugEnabled())
         {
-          if (debugEnabled())
-          {
-            TRACER.debugInfo("The password provided for user %s failed " +
-                "the %s password validator.",
-                             userDNString, validatorDN.toString());
-          }
+          TRACER.debugInfo("The password provided for user %s failed " +
+              "the %s password validator.",
+              userDNString, validatorDN.toString());
         }
 
         return false;
       }
       else
       {
-        if (debug)
+        if (debugEnabled())
         {
-          if (debugEnabled())
-          {
-            TRACER.debugInfo("The password provided for user %s passed " +
-                "the %s password validator.",
-                             userDNString, validatorDN.toString());
-          }
+          TRACER.debugInfo("The password provided for user %s passed " +
+              "the %s password validator.",
+              userDNString, validatorDN.toString());
         }
       }
     }
@@ -3748,13 +3489,10 @@
   {
     if (passwordPolicy.getDefaultStorageSchemes().isEmpty())
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Doing nothing for user %s because no " +
-              "deprecated storage schemes have been defined.", userDNString);
-        }
+        TRACER.debugInfo("Doing nothing for user %s because no " +
+            "deprecated storage schemes have been defined.", userDNString);
       }
 
       return;
@@ -3765,13 +3503,10 @@
     List<Attribute> attrList = userEntry.getAttribute(type);
     if ((attrList == null) || attrList.isEmpty())
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Doing nothing for entry %s because no password " +
-              "values were found.", userDNString);
-        }
+        TRACER.debugInfo("Doing nothing for entry %s because no password " +
+            "values were found.", userDNString);
       }
 
       return;
@@ -3818,7 +3553,7 @@
                     : DirectoryServer.getPasswordStorageScheme(schemeName);
           if (scheme == null)
           {
-            if (debug)
+            if (debugEnabled())
             {
               TRACER.debugWarning("Skipping password value for user %s " +
                   "because the associated storage scheme %s is not " +
@@ -3843,13 +3578,10 @@
             }
             else if (passwordPolicy.isDeprecatedStorageScheme(schemeName))
             {
-              if (debug)
+              if (debugEnabled())
               {
-                if (debugEnabled())
-                {
-                  TRACER.debugInfo("Marking password with scheme %s for " +
-                      "removal from user entry %s.", schemeName, userDNString);
-                }
+                TRACER.debugInfo("Marking password with scheme %s for " +
+                    "removal from user entry %s.", schemeName, userDNString);
               }
 
               iterator.remove();
@@ -3866,14 +3598,11 @@
           if (debugEnabled())
           {
             TRACER.debugCaught(DebugLogLevel.ERROR, e);
-          }
 
-          if (debug)
-          {
             TRACER.debugWarning("Skipping password value for user %s because " +
                 "an error occurred while attempting to decode it based on " +
                 "the user password syntax: %s",
-                         userDNString, stackTraceToSingleLineString(e));
+                userDNString, stackTraceToSingleLineString(e));
           }
         }
       }
@@ -3881,13 +3610,10 @@
 
     if (removedValues.isEmpty())
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("User entry %s does not have any password values " +
-              "encoded using deprecated schemes.", userDNString);
-        }
+        TRACER.debugInfo("User entry %s does not have any password values " +
+            "encoded using deprecated schemes.", userDNString);
       }
 
       return;
@@ -3917,7 +3643,7 @@
             TRACER.debugCaught(DebugLogLevel.ERROR, e);
           }
 
-          if (debug)
+          if (debugEnabled())
           {
             TRACER.debugWarning("Unable to encode password for user %s using " +
                  "default scheme %s: %s",
@@ -3930,7 +3656,7 @@
 
     if (updatedValues.isEmpty())
     {
-      if (debug)
+      if (debugEnabled())
       {
         TRACER.debugWarning("Not updating user entry %s because removing " +
              "deprecated schemes would leave the user without a password.",
@@ -3958,14 +3684,11 @@
       }
     }
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Updating user entry %s to replace password values " +
-            "encoded with deprecated schemes with values encoded " +
-            "with the default schemes.", userDNString);
-      }
+      TRACER.debugInfo("Updating user entry %s to replace password values " +
+          "encoded with deprecated schemes with values encoded " +
+          "with the default schemes.", userDNString);
     }
   }
 
@@ -4000,13 +3723,10 @@
   {
     if (! maintainHistory())
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning false because password history " +
-                           "checking is disabled.");
-        }
+        TRACER.debugInfo("Returning false because password history " +
+            "checking is disabled.");
       }
 
       // Password history checking is disabled, so we don't care if it is in the
@@ -4019,13 +3739,10 @@
     // passwords.  If so, then we'll consider it to be in the history.
     if (passwordMatches(password))
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Returning true because the provided password " +
-                           "is currently in use.");
-        }
+        TRACER.debugInfo("Returning true because the provided password " +
+            "is currently in use.");
       }
 
       return true;
@@ -4073,13 +3790,10 @@
     {
       if (historyValueMatches(password, v))
       {
-        if (debug)
+        if (debugEnabled())
         {
-          if (debugEnabled())
-          {
-            TRACER.debugInfo("Returning true because the password is in " +
-                             "the history.");
-          }
+          TRACER.debugInfo("Returning true because the password is in " +
+              "the history.");
         }
 
         return true;
@@ -4088,13 +3802,10 @@
 
 
     // If we've gotten here, then the password isn't in the history.
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Returning false because the password isn't in the " +
-                         "history.");
-      }
+      TRACER.debugInfo("Returning false because the password isn't in the " +
+          "history.");
     }
 
     return false;
@@ -4128,14 +3839,11 @@
           int    hashPos = histStr.indexOf('#');
           if (hashPos <= 0)
           {
-            if (debug)
+            if (debugEnabled())
             {
-              if (debugEnabled())
-              {
-                TRACER.debugInfo("Found value " + histStr + " in the " +
-                                 "history with no timestamp.  Marking it " +
-                                 "for removal.");
-              }
+              TRACER.debugInfo("Found value " + histStr + " in the " +
+                  "history with no timestamp.  Marking it " +
+                  "for removal.");
             }
 
             LinkedHashSet<AttributeValue> values =
@@ -4162,12 +3870,9 @@
               {
                 TRACER.debugCaught(DebugLogLevel.ERROR, e);
 
-                if (debug)
-                {
-                  TRACER.debugInfo("Could not decode the timestamp in " +
-                                   "history value " + histStr + " -- " + e +
-                                   ".  Marking it for removal.");
-                }
+                TRACER.debugInfo("Could not decode the timestamp in " +
+                    "history value " + histStr + " -- " + e +
+                    ".  Marking it for removal.");
               }
 
               LinkedHashSet<AttributeValue> values =
@@ -4212,13 +3917,10 @@
       int    hashPos1 = histStr.indexOf('#');
       if (hashPos1 <= 0)
       {
-        if (debug)
+        if (debugEnabled())
         {
-          if (debugEnabled())
-          {
-            TRACER.debugInfo("Returning false because the password history " +
-                             "value didn't include any hash characters.");
-          }
+          TRACER.debugInfo("Returning false because the password history " +
+              "value didn't include any hash characters.");
         }
 
         return false;
@@ -4227,13 +3929,10 @@
       int hashPos2 = histStr.indexOf('#', hashPos1+1);
       if (hashPos2 < 0)
       {
-        if (debug)
+        if (debugEnabled())
         {
-          if (debugEnabled())
-          {
-            TRACER.debugInfo("Returning false because the password history " +
-                             "value only had one hash character.");
-          }
+          TRACER.debugInfo("Returning false because the password history " +
+              "value only had one hash character.");
         }
 
         return false;
@@ -4251,26 +3950,20 @@
         if (scheme.authPasswordMatches(password, authPWComponents[1].toString(),
                                        authPWComponents[2].toString()))
         {
-          if (debug)
+          if (debugEnabled())
           {
-            if (debugEnabled())
-            {
-              TRACER.debugInfo("Returning true because the auth password " +
-                               "history value matched.");
-            }
+            TRACER.debugInfo("Returning true because the auth password " +
+                "history value matched.");
           }
 
           return true;
         }
         else
         {
-          if (debug)
+          if (debugEnabled())
           {
-            if (debugEnabled())
-            {
-              TRACER.debugInfo("Returning false because the auth password " +
-                               "history value did not match.");
-            }
+            TRACER.debugInfo("Returning false because the auth password " +
+                "history value did not match.");
           }
 
           return false;
@@ -4286,26 +3979,20 @@
         if (scheme.passwordMatches(password,
                                    new ASN1OctetString(userPWComponents[1])))
         {
-          if (debug)
+          if (debugEnabled())
           {
-            if (debugEnabled())
-            {
-              TRACER.debugInfo("Returning true because the user password " +
-                               "history value matched.");
-            }
+            TRACER.debugInfo("Returning true because the user password " +
+                "history value matched.");
           }
 
           return true;
         }
         else
         {
-          if (debug)
+          if (debugEnabled())
           {
-            if (debugEnabled())
-            {
-              TRACER.debugInfo("Returning false because the user password " +
-                               "history value did not match.");
-            }
+            TRACER.debugInfo("Returning false because the user password " +
+                "history value did not match.");
           }
 
           return false;
@@ -4313,14 +4000,11 @@
       }
       else
       {
-        if (debug)
+        if (debugEnabled())
         {
-          if (debugEnabled())
-          {
-            TRACER.debugInfo("Returning false because the syntax OID " +
-                             syntaxOID + " didn't match for either the auth " +
-                             "or user password syntax.");
-          }
+          TRACER.debugInfo("Returning false because the syntax OID " +
+              syntaxOID + " didn't match for either the auth " +
+              "or user password syntax.");
         }
 
         return false;
@@ -4332,7 +4016,7 @@
       {
         TRACER.debugCaught(DebugLogLevel.ERROR, e);
 
-        if (debug)
+        if (debugEnabled())
         {
           TRACER.debugInfo("Returning false because of an exception:  " +
                            stackTraceToSingleLineString(e));
@@ -4380,13 +4064,10 @@
   {
     if (! maintainHistory())
     {
-      if (debug)
+      if (debugEnabled())
       {
-        if (debugEnabled())
-        {
-          TRACER.debugInfo("Not doing anything because password history " +
-                           "maintenance is disabled.");
-        }
+        TRACER.debugInfo("Not doing anything because password history " +
+            "maintenance is disabled.");
       }
 
       return;
@@ -4419,13 +4100,10 @@
         iterator.remove();
         numToDelete--;
 
-        if (debug)
+        if (debugEnabled())
         {
-          if (debugEnabled())
-          {
-            TRACER.debugInfo("Removing history value " + v.getStringValue() +
-                             " to preserve the history count.");
-          }
+          TRACER.debugInfo("Removing history value " + v.getStringValue() +
+              " to preserve the history count.");
         }
       }
 
@@ -4455,13 +4133,10 @@
           removeValues.add(v);
           iterator.remove();
 
-          if (debug)
+          if (debugEnabled())
           {
-            if (debugEnabled())
-            {
-              TRACER.debugInfo("Removing history value " + v.getStringValue() +
-                               " to preserve the history duration.");
-            }
+            TRACER.debugInfo("Removing history value " + v.getStringValue() +
+                " to preserve the history duration.");
           }
         }
         else
@@ -4497,12 +4172,9 @@
          new Attribute(historyType, historyType.getPrimaryName(),
                        newHistValues);
 
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Going to add history value " + newHistStr);
-      }
+      TRACER.debugInfo("Going to add history value " + newHistStr);
     }
 
 
@@ -4567,12 +4239,9 @@
    */
   public void clearPasswordHistory()
   {
-    if (debug)
+    if (debugEnabled())
     {
-      if (debugEnabled())
-      {
-        TRACER.debugInfo("Clearing password history for user %s", userDNString);
-      }
+      TRACER.debugInfo("Clearing password history for user %s", userDNString);
     }
 
     AttributeType type = DirectoryServer.getAttributeType(
@@ -4605,7 +4274,7 @@
     PasswordGenerator generator = passwordPolicy.getPasswordGenerator();
     if (generator == null)
     {
-      if (debug)
+      if (debugEnabled())
       {
         TRACER.debugWarning("Unable to generate a new password for user " +
             "%s because no password generator has been defined in the " +
diff --git a/opends/src/server/org/opends/server/core/PluginConfigManager.java b/opends/src/server/org/opends/server/core/PluginConfigManager.java
index d7d3ab6..c237478 100644
--- a/opends/src/server/org/opends/server/core/PluginConfigManager.java
+++ b/opends/src/server/org/opends/server/core/PluginConfigManager.java
@@ -52,79 +52,11 @@
 import org.opends.server.admin.std.server.PluginRootCfg;
 import org.opends.server.admin.std.server.RootCfg;
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.DirectoryServerPlugin;
-import org.opends.server.api.plugin.IntermediateResponsePluginResult;
-import org.opends.server.api.plugin.LDIFPluginResult;
-import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PostConnectPluginResult;
-import org.opends.server.api.plugin.PostDisconnectPluginResult;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PostResponsePluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
-import org.opends.server.api.plugin.PreParsePluginResult;
-import org.opends.server.api.plugin.SearchEntryPluginResult;
-import org.opends.server.api.plugin.SearchReferencePluginResult;
-import org.opends.server.api.plugin.StartupPluginResult;
-import org.opends.server.api.plugin.SubordinateModifyDNPluginResult;
+import org.opends.server.api.plugin.*;
 import org.opends.server.config.ConfigException;
 import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.IntermediateResponse;
-import org.opends.server.types.LDIFExportConfig;
-import org.opends.server.types.LDIFImportConfig;
-import org.opends.server.types.Operation;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchResultEntry;
-import org.opends.server.types.SearchResultReference;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.Modification;
-import org.opends.server.types.operation.PostOperationAbandonOperation;
-import org.opends.server.types.operation.PostOperationAddOperation;
-import org.opends.server.types.operation.PostOperationBindOperation;
-import org.opends.server.types.operation.PostOperationCompareOperation;
-import org.opends.server.types.operation.PostOperationDeleteOperation;
-import org.opends.server.types.operation.PostOperationExtendedOperation;
-import org.opends.server.types.operation.PostOperationModifyDNOperation;
-import org.opends.server.types.operation.PostOperationModifyOperation;
-import org.opends.server.types.operation.PostOperationSearchOperation;
-import org.opends.server.types.operation.PostOperationUnbindOperation;
-import org.opends.server.types.operation.PostResponseAddOperation;
-import org.opends.server.types.operation.PostResponseBindOperation;
-import org.opends.server.types.operation.PostResponseCompareOperation;
-import org.opends.server.types.operation.PostResponseDeleteOperation;
-import org.opends.server.types.operation.PostResponseExtendedOperation;
-import org.opends.server.types.operation.PostResponseModifyDNOperation;
-import org.opends.server.types.operation.PostResponseModifyOperation;
-import org.opends.server.types.operation.PostResponseSearchOperation;
-import org.opends.server.types.operation.PostSynchronizationAddOperation;
-import org.opends.server.types.operation.PostSynchronizationDeleteOperation;
-import org.opends.server.types.operation.PostSynchronizationModifyOperation;
-import org.opends.server.types.operation.PostSynchronizationModifyDNOperation;
-import org.opends.server.types.operation.PreOperationAddOperation;
-import org.opends.server.types.operation.PreOperationBindOperation;
-import org.opends.server.types.operation.PreOperationCompareOperation;
-import org.opends.server.types.operation.PreOperationDeleteOperation;
-import org.opends.server.types.operation.PreOperationExtendedOperation;
-import org.opends.server.types.operation.PreOperationModifyDNOperation;
-import org.opends.server.types.operation.PreOperationModifyOperation;
-import org.opends.server.types.operation.PreOperationSearchOperation;
-import org.opends.server.types.operation.PreParseAbandonOperation;
-import org.opends.server.types.operation.PreParseAddOperation;
-import org.opends.server.types.operation.PreParseBindOperation;
-import org.opends.server.types.operation.PreParseCompareOperation;
-import org.opends.server.types.operation.PreParseDeleteOperation;
-import org.opends.server.types.operation.PreParseModifyDNOperation;
-import org.opends.server.types.operation.PreParseExtendedOperation;
-import org.opends.server.types.operation.PreParseModifyOperation;
-import org.opends.server.types.operation.PreParseSearchOperation;
-import org.opends.server.types.operation.PreParseUnbindOperation;
-import org.opends.server.types.operation.SearchEntrySearchOperation;
-import org.opends.server.types.operation.SearchReferenceSearchOperation;
-import org.opends.server.types.operation.SubordinateModifyDNOperation;
+import org.opends.server.types.*;
+import org.opends.server.types.operation.*;
 import org.opends.server.workflowelement.localbackend.*;
 
 import static org.opends.messages.ConfigMessages.*;
@@ -211,6 +143,16 @@
                DirectoryServerPlugin<? extends PluginCfg>>
                     registeredPlugins;
 
+  // The mapping between an operation and a set of post operation plugins
+  // it should skip. This pairs up pre and post operation plugin processing
+  // such that only plugins that successfully execute its pre op plugin will
+  // have its post op plugin executed on a per operation basis. If an
+  // operation is not registered on this list then all all pre op plugins
+  // executed successfully for this operation so all post op plugins should
+  // execute.
+  private ConcurrentHashMap<PluginOperation, ArrayList<DirectoryServerPlugin>>
+      skippedPreOperationPlugins;
+
   // The plugin root configuration read at server startup.
   private PluginRootCfg pluginRootConfig;
 
@@ -280,6 +222,9 @@
     registeredPlugins                  =
          new ConcurrentHashMap<DN,
                   DirectoryServerPlugin<? extends PluginCfg>>();
+    skippedPreOperationPlugins =
+        new ConcurrentHashMap<PluginOperation,
+                  ArrayList<DirectoryServerPlugin>>();
   }
 
 
@@ -1393,9 +1338,9 @@
    *
    * @return  The result of processing the startup plugins.
    */
-  public StartupPluginResult invokeStartupPlugins()
+  public PluginResult.Startup invokeStartupPlugins()
   {
-    StartupPluginResult result = null;
+    PluginResult.Startup result = null;
 
     for (DirectoryServerPlugin p : startupPlugins)
     {
@@ -1414,8 +1359,7 @@
                 String.valueOf(p.getPluginEntryDN()),
                 stackTraceToSingleLineString(e));
 
-        result = new StartupPluginResult(false, false, message);
-        break;
+        return PluginResult.Startup.stopStartup(message);
       }
 
       if (result == null)
@@ -1423,27 +1367,16 @@
         Message message = ERR_PLUGIN_STARTUP_PLUGIN_RETURNED_NULL.get(
             String.valueOf(p.getPluginEntryDN()));
         logError(message);
-        return new StartupPluginResult(false, false, message);
+        return PluginResult.Startup.stopStartup(message);
       }
-      else if (! result.completedSuccessfully())
+      else if (! result.continueProcessing())
       {
-        if (result.continueStartup())
-        {
-          Message message = ERR_PLUGIN_STARTUP_PLUGIN_FAIL_CONTINUE.
-              get(String.valueOf(p.getPluginEntryDN()),
-                  result.getErrorMessage(),
-                  result.getErrorMessage().getDescriptor().getId());
-          logError(message);
-        }
-        else
-        {
-          Message message = ERR_PLUGIN_STARTUP_PLUGIN_FAIL_ABORT.
-              get(String.valueOf(p.getPluginEntryDN()),
-                  result.getErrorMessage(),
-                  result.getErrorMessage().getDescriptor().getId());
-          logError(message);
-          return result;
-        }
+        Message message = ERR_PLUGIN_STARTUP_PLUGIN_FAIL_ABORT.
+            get(String.valueOf(p.getPluginEntryDN()),
+                result.getErrorMessage(),
+                result.getErrorMessage().getDescriptor().getId());
+        logError(message);
+        return result;
       }
     }
 
@@ -1451,7 +1384,7 @@
     {
       // This should only happen if there were no startup plugins registered,
       // which is fine.
-      result = StartupPluginResult.SUCCESS;
+      result = PluginResult.Startup.continueStartup();
     }
 
     return result;
@@ -1498,10 +1431,10 @@
    *
    * @return  The result of processing the post-connect plugins.
    */
-  public PostConnectPluginResult invokePostConnectPlugins(ClientConnection
-                                                               clientConnection)
+  public PluginResult.PostConnect invokePostConnectPlugins(ClientConnection
+                                                           clientConnection)
   {
-    PostConnectPluginResult result = null;
+    PluginResult.PostConnect result = null;
 
     for (DirectoryServerPlugin p : postConnectPlugins)
     {
@@ -1523,20 +1456,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        try
-        {
-          clientConnection.disconnect(DisconnectReason.SERVER_ERROR, true,
-                  message);
-        }
-        catch (Exception e2)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, e2);
-          }
-        }
-
-        return new PostConnectPluginResult(true, false);
+        return PluginResult.PostConnect.disconnectClient(
+            DisconnectReason.SERVER_ERROR, true, message);
       }
 
 
@@ -1548,23 +1469,10 @@
                 clientConnection.getClientAddress());
         logError(message);
 
-        try
-        {
-          clientConnection.disconnect(DisconnectReason.SERVER_ERROR, true,
-                  message);
-        }
-        catch (Exception e)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, e);
-          }
-        }
-
-        return new PostConnectPluginResult(true, false);
+        return PluginResult.PostConnect.disconnectClient(
+            DisconnectReason.SERVER_ERROR, true, message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -1574,7 +1482,7 @@
     {
       // This should only happen if there were no post-connect plugins
       // registered, which is fine.
-      result = PostConnectPluginResult.SUCCESS;
+      result = PluginResult.PostConnect.continueConnectProcessing();
     }
 
     return result;
@@ -1594,12 +1502,12 @@
    *
    * @return  The result of processing the post-connect plugins.
    */
-  public PostDisconnectPluginResult invokePostDisconnectPlugins(
+  public PluginResult.PostDisconnect invokePostDisconnectPlugins(
                                         ClientConnection clientConnection,
                                         DisconnectReason disconnectReason,
                                         Message message)
   {
-    PostDisconnectPluginResult result = null;
+    PluginResult.PostDisconnect result = null;
 
     for (DirectoryServerPlugin p : postDisconnectPlugins)
     {
@@ -1621,8 +1529,6 @@
                 clientConnection.getClientAddress(),
                 stackTraceToSingleLineString(e));
         logError(msg);
-
-        return new PostDisconnectPluginResult(false);
       }
 
 
@@ -1633,8 +1539,6 @@
                 clientConnection.getConnectionID(),
                 clientConnection.getClientAddress());
         logError(msg);
-
-        return new PostDisconnectPluginResult(false);
       }
       else if (! result.continuePluginProcessing())
       {
@@ -1646,7 +1550,7 @@
     {
       // This should only happen if there were no post-disconnect plugins
       // registered, which is fine.
-      result = PostDisconnectPluginResult.SUCCESS;
+      result = PluginResult.PostDisconnect.continueDisconnectProcessing();
     }
 
     return result;
@@ -1664,10 +1568,10 @@
    *
    * @return  The result of processing the LDIF import plugins.
    */
-  public LDIFPluginResult invokeLDIFImportPlugins(LDIFImportConfig importConfig,
-                                                  Entry entry)
+  public PluginResult.ImportLDIF invokeLDIFImportPlugins(
+      LDIFImportConfig importConfig, Entry entry)
   {
-    LDIFPluginResult result = null;
+    PluginResult.ImportLDIF result = null;
 
     for (DirectoryServerPlugin p : ldifImportPlugins)
     {
@@ -1687,7 +1591,7 @@
                 String.valueOf(entry.getDN()), stackTraceToSingleLineString(e));
         logError(message);
 
-        return new LDIFPluginResult(false, false, message);
+        return PluginResult.ImportLDIF.stopEntryProcessing(message);
       }
 
       if (result == null)
@@ -1697,7 +1601,7 @@
                 String.valueOf(entry.getDN()));
         logError(message);
 
-        return new LDIFPluginResult(false, false, message);
+        return PluginResult.ImportLDIF.stopEntryProcessing(message);
       }
       else if (! result.continuePluginProcessing())
       {
@@ -1709,7 +1613,7 @@
     {
       // This should only happen if there were no LDIF import plugins
       // registered, which is fine.
-      result = LDIFPluginResult.SUCCESS;
+      result = PluginResult.ImportLDIF.continueEntryProcessing();
     }
 
     return result;
@@ -1727,10 +1631,10 @@
    *
    * @return  The result of processing the LDIF export plugins.
    */
-  public LDIFPluginResult invokeLDIFExportPlugins(LDIFExportConfig exportConfig,
-                                                  Entry entry)
+  public PluginResult.ImportLDIF invokeLDIFExportPlugins(
+      LDIFExportConfig exportConfig, Entry entry)
   {
-    LDIFPluginResult result = null;
+    PluginResult.ImportLDIF result = null;
 
     for (DirectoryServerPlugin p : ldifExportPlugins)
     {
@@ -1750,7 +1654,7 @@
                 String.valueOf(entry.getDN()), stackTraceToSingleLineString(e));
         logError(message);
 
-        return new LDIFPluginResult(false, false, message);
+        return PluginResult.ImportLDIF.stopEntryProcessing(message);
       }
 
       if (result == null)
@@ -1760,7 +1664,7 @@
                 String.valueOf(entry.getDN()));
         logError(message);
 
-        return new LDIFPluginResult(false, false, message);
+        return PluginResult.ImportLDIF.stopEntryProcessing(message);
       }
       else if (! result.continuePluginProcessing())
       {
@@ -1772,7 +1676,7 @@
     {
       // This should only happen if there were no LDIF export plugins
       // registered, which is fine.
-      result = LDIFPluginResult.SUCCESS;
+      result = PluginResult.ImportLDIF.continueEntryProcessing();
     }
 
     return result;
@@ -1789,10 +1693,10 @@
    *
    * @return  The result of processing the pre-parse abandon plugins.
    */
-  public PreParsePluginResult invokePreParseAbandonPlugins(
+  public PluginResult.PreParse invokePreParseAbandonPlugins(
                                    PreParseAbandonOperation abandonOperation)
   {
-    PreParsePluginResult result = null;
+    PluginResult.PreParse result = null;
 
     for (DirectoryServerPlugin p : preParseAbandonPlugins)
     {
@@ -1821,11 +1725,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        abandonOperation.setResultCode(
-                              DirectoryServer.getServerErrorResultCode());
-        abandonOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -1837,14 +1738,10 @@
                 String.valueOf(abandonOperation.getOperationID()));
         logError(message);
 
-        abandonOperation.setResultCode(
-             DirectoryServer.getServerErrorResultCode());
-        abandonOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -1854,7 +1751,7 @@
     {
       // This should only happen if there were no pre-parse abandon plugins
       // registered, which is fine.
-      result = PreParsePluginResult.SUCCESS;
+      result = PluginResult.PreParse.continueOperationProcessing();
     }
 
     return result;
@@ -1870,11 +1767,13 @@
    *                       plugins.
    *
    * @return  The result of processing the pre-parse add plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreParsePluginResult invokePreParseAddPlugins(
+  public PluginResult.PreParse invokePreParseAddPlugins(
       PreParseAddOperation addOperation)
-  {
-    PreParsePluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreParse result = null;
 
     for (DirectoryServerPlugin p : preParseAddPlugins)
     {
@@ -1888,6 +1787,10 @@
       {
         result = p.doPreParse(addOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -1902,10 +1805,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        addOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        addOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -1917,13 +1818,10 @@
                 String.valueOf(addOperation.getOperationID()));
         logError(message);
 
-        addOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        addOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -1933,7 +1831,7 @@
     {
       // This should only happen if there were no pre-parse add plugins
       // registered, which is fine.
-      result = PreParsePluginResult.SUCCESS;
+      result = PluginResult.PreParse.continueOperationProcessing();
     }
 
     return result;
@@ -1950,10 +1848,10 @@
    *
    * @return  The result of processing the pre-parse bind plugins.
    */
-  public PreParsePluginResult invokePreParseBindPlugins(
+  public PluginResult.PreParse invokePreParseBindPlugins(
                                    PreParseBindOperation bindOperation)
   {
-    PreParsePluginResult result = null;
+    PluginResult.PreParse result = null;
 
     for (DirectoryServerPlugin p : preParseBindPlugins)
     {
@@ -1981,10 +1879,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        bindOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        bindOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -1996,13 +1892,10 @@
                 String.valueOf(bindOperation.getOperationID()));
         logError(message);
 
-        bindOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        bindOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -2012,7 +1905,7 @@
     {
       // This should only happen if there were no pre-parse bind plugins
       // registered, which is fine.
-      result = PreParsePluginResult.SUCCESS;
+      result = PluginResult.PreParse.continueOperationProcessing();
     }
 
     return result;
@@ -2028,11 +1921,13 @@
    *                           pre-parse plugins.
    *
    * @return  The result of processing the pre-parse compare plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreParsePluginResult invokePreParseComparePlugins(
-    PreParseCompareOperation compareOperation)
-  {
-    PreParsePluginResult result = null;
+  public PluginResult.PreParse invokePreParseComparePlugins(
+      PreParseCompareOperation compareOperation)
+      throws CanceledOperationException {
+    PluginResult.PreParse result = null;
 
     for (DirectoryServerPlugin p : preParseComparePlugins)
     {
@@ -2046,6 +1941,10 @@
       {
         result = p.doPreParse(compareOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -2061,11 +1960,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        compareOperation.setResultCode(
-                              DirectoryServer.getServerErrorResultCode());
-        compareOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2077,14 +1973,10 @@
                 String.valueOf(compareOperation.getOperationID()));
         logError(message);
 
-        compareOperation.setResultCode(
-                              DirectoryServer.getServerErrorResultCode());
-        compareOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -2094,7 +1986,7 @@
     {
       // This should only happen if there were no pre-parse compare plugins
       // registered, which is fine.
-      result = PreParsePluginResult.SUCCESS;
+      result = PluginResult.PreParse.continueOperationProcessing();
     }
 
     return result;
@@ -2110,11 +2002,13 @@
    *                          pre-parse plugins.
    *
    * @return  The result of processing the pre-parse delete plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreParsePluginResult invokePreParseDeletePlugins(
+  public PluginResult.PreParse invokePreParseDeletePlugins(
                               PreParseDeleteOperation deleteOperation)
-  {
-    PreParsePluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreParse result = null;
 
     for (DirectoryServerPlugin p : preParseDeletePlugins)
     {
@@ -2128,6 +2022,10 @@
       {
         result = p.doPreParse(deleteOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -2143,11 +2041,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        deleteOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        deleteOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2159,14 +2054,10 @@
                 String.valueOf(deleteOperation.getOperationID()));
         logError(message);
 
-        deleteOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        deleteOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -2176,7 +2067,7 @@
     {
       // This should only happen if there were no pre-parse delete plugins
       // registered, which is fine.
-      result = PreParsePluginResult.SUCCESS;
+      result = PluginResult.PreParse.continueOperationProcessing();
     }
 
     return result;
@@ -2192,11 +2083,13 @@
    *                            pre-parse plugins.
    *
    * @return  The result of processing the pre-parse extended plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreParsePluginResult invokePreParseExtendedPlugins(
+  public PluginResult.PreParse invokePreParseExtendedPlugins(
                                    PreParseExtendedOperation extendedOperation)
-  {
-    PreParsePluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreParse result = null;
 
     for (DirectoryServerPlugin p : preParseExtendedPlugins)
     {
@@ -2210,6 +2103,10 @@
       {
         result = p.doPreParse(extendedOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -2225,11 +2122,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        extendedOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        extendedOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2241,14 +2135,10 @@
                 String.valueOf(extendedOperation.getOperationID()));
         logError(message);
 
-        extendedOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        extendedOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -2258,7 +2148,7 @@
     {
       // This should only happen if there were no pre-parse extended plugins
       // registered, which is fine.
-      result = PreParsePluginResult.SUCCESS;
+      result = PluginResult.PreParse.continueOperationProcessing();
     }
 
     return result;
@@ -2274,11 +2164,13 @@
    *                          pre-parse plugins.
    *
    * @return  The result of processing the pre-parse modify plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreParsePluginResult invokePreParseModifyPlugins(
+  public PluginResult.PreParse invokePreParseModifyPlugins(
                                    PreParseModifyOperation modifyOperation)
-  {
-    PreParsePluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreParse result = null;
 
     for (DirectoryServerPlugin p : preParseModifyPlugins)
     {
@@ -2292,6 +2184,10 @@
       {
         result = p.doPreParse(modifyOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -2307,11 +2203,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        modifyOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        modifyOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2323,14 +2216,10 @@
                 String.valueOf(modifyOperation.getOperationID()));
         logError(message);
 
-        modifyOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        modifyOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -2340,7 +2229,7 @@
     {
       // This should only happen if there were no pre-parse modify plugins
       // registered, which is fine.
-      result = PreParsePluginResult.SUCCESS;
+      result = PluginResult.PreParse.continueOperationProcessing();
     }
 
     return result;
@@ -2356,11 +2245,13 @@
    *                            pre-parse plugins.
    *
    * @return  The result of processing the pre-parse modify DN plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreParsePluginResult invokePreParseModifyDNPlugins(
+  public PluginResult.PreParse invokePreParseModifyDNPlugins(
                                    PreParseModifyDNOperation modifyDNOperation)
-  {
-    PreParsePluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreParse result = null;
 
     for (DirectoryServerPlugin p : preParseModifyDNPlugins)
     {
@@ -2374,6 +2265,10 @@
       {
         result = p.doPreParse(modifyDNOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -2389,11 +2284,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        modifyDNOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        modifyDNOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2405,14 +2297,10 @@
                 String.valueOf(modifyDNOperation.getOperationID()));
         logError(message);
 
-        modifyDNOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        modifyDNOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -2422,7 +2310,7 @@
     {
       // This should only happen if there were no pre-parse modify DN plugins
       // registered, which is fine.
-      result = PreParsePluginResult.SUCCESS;
+      result = PluginResult.PreParse.continueOperationProcessing();
     }
 
     return result;
@@ -2438,11 +2326,13 @@
    *                          pre-parse plugins.
    *
    * @return  The result of processing the pre-parse search plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreParsePluginResult invokePreParseSearchPlugins(
+  public PluginResult.PreParse invokePreParseSearchPlugins(
                                    PreParseSearchOperation searchOperation)
-  {
-    PreParsePluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreParse result = null;
 
     for (DirectoryServerPlugin p : preParseSearchPlugins)
     {
@@ -2456,6 +2346,10 @@
       {
         result = p.doPreParse(searchOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -2471,11 +2365,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        searchOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        searchOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2487,14 +2378,10 @@
                 String.valueOf(searchOperation.getOperationID()));
         logError(message);
 
-        searchOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        searchOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -2504,7 +2391,7 @@
     {
       // This should only happen if there were no pre-parse search plugins
       // registered, which is fine.
-      result = PreParsePluginResult.SUCCESS;
+      result = PluginResult.PreParse.continueOperationProcessing();
     }
 
     return result;
@@ -2521,10 +2408,10 @@
    *
    * @return  The result of processing the pre-parse unbind plugins.
    */
-  public PreParsePluginResult invokePreParseUnbindPlugins(
+  public PluginResult.PreParse invokePreParseUnbindPlugins(
                                    PreParseUnbindOperation unbindOperation)
   {
-    PreParsePluginResult result = null;
+    PluginResult.PreParse result = null;
 
     for (DirectoryServerPlugin p : preParseUnbindPlugins)
     {
@@ -2553,11 +2440,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        unbindOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        unbindOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2569,14 +2453,10 @@
                 String.valueOf(unbindOperation.getOperationID()));
         logError(message);
 
-        unbindOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        unbindOperation.appendErrorMessage(message);
-
-        return new PreParsePluginResult(false, false, true);
+        return PluginResult.PreParse.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -2586,7 +2466,7 @@
     {
       // This should only happen if there were no pre-parse unbind plugins
       // registered, which is fine.
-      result = PreParsePluginResult.SUCCESS;
+      result = PluginResult.PreParse.continueOperationProcessing();
     }
 
     return result;
@@ -2602,14 +2482,17 @@
    *                       pre-operation plugins.
    *
    * @return  The result of processing the pre-operation add plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreOperationPluginResult invokePreOperationAddPlugins(
+  public PluginResult.PreOperation invokePreOperationAddPlugins(
                                        PreOperationAddOperation addOperation)
-  {
-    PreOperationPluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreOperation result = null;
 
-    for (DirectoryServerPlugin p : preOperationAddPlugins)
+    for (int i = 0; i < preOperationAddPlugins.length; i++)
     {
+      DirectoryServerPlugin p = preOperationAddPlugins[i];
       if (addOperation.isInternalOperation() &&
           (! p.invokeForInternalOperations()))
       {
@@ -2620,6 +2503,10 @@
       {
         result = p.doPreOperation(addOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -2634,10 +2521,11 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        addOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        addOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationAddPlugins,
+            addOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2648,14 +2536,16 @@
                 addOperation.getConnectionID(), addOperation.getOperationID());
         logError(message);
 
-        addOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        addOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationAddPlugins,
+            addOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
+        registerSkippedPreOperationPlugins(i, preOperationAddPlugins,
+            addOperation);
         return result;
       }
     }
@@ -2664,7 +2554,7 @@
     {
       // This should only happen if there were no pre-operation add plugins
       // registered, which is fine.
-      result = PreOperationPluginResult.SUCCESS;
+      result = PluginResult.PreOperation.continueOperationProcessing();
     }
 
     return result;
@@ -2681,13 +2571,14 @@
    *
    * @return  The result of processing the pre-operation bind plugins.
    */
-  public PreOperationPluginResult invokePreOperationBindPlugins(
+  public PluginResult.PreOperation invokePreOperationBindPlugins(
                                        PreOperationBindOperation bindOperation)
   {
-    PreOperationPluginResult result = null;
+    PluginResult.PreOperation result = null;
 
-    for (DirectoryServerPlugin p : preOperationBindPlugins)
+    for (int i = 0; i < preOperationBindPlugins.length; i++)
     {
+      DirectoryServerPlugin p = preOperationBindPlugins[i];
       if (bindOperation.isInternalOperation() &&
           (! p.invokeForInternalOperations()))
       {
@@ -2712,10 +2603,11 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        bindOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        bindOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationBindPlugins,
+            bindOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2727,23 +2619,26 @@
                 bindOperation.getOperationID());
         logError(message);
 
-        bindOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        bindOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationBindPlugins,
+            bindOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
+        registerSkippedPreOperationPlugins(i, preOperationBindPlugins,
+            bindOperation);
+
         return result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no pre-operation bind plugins
+      // This should only happen if there were no pre-operation add plugins
       // registered, which is fine.
-      result = PreOperationPluginResult.SUCCESS;
+      result = PluginResult.PreOperation.continueOperationProcessing();
     }
 
     return result;
@@ -2759,14 +2654,17 @@
    *                           pre-operation plugins.
    *
    * @return  The result of processing the pre-operation compare plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreOperationPluginResult invokePreOperationComparePlugins(
+  public PluginResult.PreOperation invokePreOperationComparePlugins(
      PreOperationCompareOperation compareOperation)
-  {
-    PreOperationPluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreOperation result = null;
 
-    for (DirectoryServerPlugin p : preOperationComparePlugins)
+    for (int i = 0; i < preOperationComparePlugins.length; i++)
     {
+      DirectoryServerPlugin p = preOperationComparePlugins[i];
       if (compareOperation.isInternalOperation() &&
           (! p.invokeForInternalOperations()))
       {
@@ -2777,6 +2675,10 @@
       {
         result = p.doPreOperation(compareOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -2792,11 +2694,11 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        compareOperation.setResultCode(
-                              DirectoryServer.getServerErrorResultCode());
-        compareOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationComparePlugins,
+            compareOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2808,14 +2710,13 @@
                 compareOperation.getOperationID());
         logError(message);
 
-        compareOperation.setResultCode(
-                              DirectoryServer.getServerErrorResultCode());
-        compareOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationComparePlugins,
+            compareOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -2823,9 +2724,9 @@
 
     if (result == null)
     {
-      // This should only happen if there were no pre-operation compare plugins
+      // This should only happen if there were no pre-operation add plugins
       // registered, which is fine.
-      result = PreOperationPluginResult.SUCCESS;
+      result = PluginResult.PreOperation.continueOperationProcessing();
     }
 
     return result;
@@ -2841,14 +2742,17 @@
    *                          pre-operation plugins.
    *
    * @return  The result of processing the pre-operation delete plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreOperationPluginResult invokePreOperationDeletePlugins(
+  public PluginResult.PreOperation invokePreOperationDeletePlugins(
                                   PreOperationDeleteOperation deleteOperation)
-  {
-    PreOperationPluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreOperation result = null;
 
-    for (DirectoryServerPlugin p : preOperationDeletePlugins)
+    for (int i = 0; i < preOperationDeletePlugins.length; i++)
     {
+      DirectoryServerPlugin p = preOperationDeletePlugins[i];
       if (deleteOperation.isInternalOperation() &&
           (! p.invokeForInternalOperations()))
       {
@@ -2859,6 +2763,10 @@
       {
         result = p.doPreOperation(deleteOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -2874,11 +2782,11 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        deleteOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        deleteOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationDeletePlugins,
+            deleteOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2890,24 +2798,26 @@
                 deleteOperation.getOperationID());
         logError(message);
 
-        deleteOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        deleteOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationDeletePlugins,
+            deleteOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
+        registerSkippedPreOperationPlugins(i, preOperationDeletePlugins,
+            deleteOperation);
+
         return result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no pre-operation delete plugins
+      // This should only happen if there were no pre-operation add plugins
       // registered, which is fine.
-      result = PreOperationPluginResult.SUCCESS;
+      result = PluginResult.PreOperation.continueOperationProcessing();
     }
 
     return result;
@@ -2923,17 +2833,21 @@
    *                            pre-operation plugins.
    *
    * @return  The result of processing the pre-operation extended plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreOperationPluginResult invokePreOperationExtendedPlugins(
+  public PluginResult.PreOperation invokePreOperationExtendedPlugins(
                                PreOperationExtendedOperation extendedOperation)
-  {
-    PreOperationPluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreOperation result = null;
 
-    for (DirectoryServerPlugin p : preOperationExtendedPlugins)
+    for (int i = 0; i < preOperationExtendedPlugins.length; i++)
     {
+      DirectoryServerPlugin p = preOperationExtendedPlugins[i];
       if (extendedOperation.isInternalOperation() &&
           (! p.invokeForInternalOperations()))
       {
+        registerSkippedPreOperationPlugin(p, extendedOperation);
         continue;
       }
 
@@ -2941,6 +2855,10 @@
       {
         result = p.doPreOperation(extendedOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -2956,11 +2874,11 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        extendedOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        extendedOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationExtendedPlugins,
+            extendedOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -2972,24 +2890,26 @@
                 extendedOperation.getOperationID());
         logError(message);
 
-        extendedOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        extendedOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationExtendedPlugins,
+            extendedOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
+        registerSkippedPreOperationPlugins(i, preOperationExtendedPlugins,
+            extendedOperation);
+
         return result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no pre-operation extended plugins
+      // This should only happen if there were no pre-operation add plugins
       // registered, which is fine.
-      result = PreOperationPluginResult.SUCCESS;
+      result = PluginResult.PreOperation.continueOperationProcessing();
     }
 
     return result;
@@ -3005,14 +2925,17 @@
    *                          pre-operation plugins.
    *
    * @return  The result of processing the pre-operation modify plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreOperationPluginResult invokePreOperationModifyPlugins(
+  public PluginResult.PreOperation invokePreOperationModifyPlugins(
                                   PreOperationModifyOperation modifyOperation)
-  {
-    PreOperationPluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreOperation result = null;
 
-    for (DirectoryServerPlugin p : preOperationModifyPlugins)
+    for (int i = 0; i < preOperationModifyPlugins.length; i++)
     {
+      DirectoryServerPlugin p = preOperationModifyPlugins[i];
       if (modifyOperation.isInternalOperation() &&
           (! p.invokeForInternalOperations()))
       {
@@ -3023,6 +2946,10 @@
       {
         result = p.doPreOperation(modifyOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -3038,11 +2965,11 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        modifyOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        modifyOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationModifyPlugins,
+            modifyOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -3054,24 +2981,26 @@
                 modifyOperation.getOperationID());
         logError(message);
 
-        modifyOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        modifyOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationModifyPlugins,
+            modifyOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
+        registerSkippedPreOperationPlugins(i, preOperationModifyPlugins,
+            modifyOperation);
+
         return result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no pre-operation modify plugins
+      // This should only happen if there were no pre-operation add plugins
       // registered, which is fine.
-      result = PreOperationPluginResult.SUCCESS;
+      result = PluginResult.PreOperation.continueOperationProcessing();
     }
 
     return result;
@@ -3087,14 +3016,17 @@
    *                            pre-operation plugins.
    *
    * @return  The result of processing the pre-operation modify DN plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreOperationPluginResult invokePreOperationModifyDNPlugins(
+  public PluginResult.PreOperation invokePreOperationModifyDNPlugins(
                               PreOperationModifyDNOperation modifyDNOperation)
-  {
-    PreOperationPluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreOperation result = null;
 
-    for (DirectoryServerPlugin p : preOperationModifyDNPlugins)
+    for (int i = 0; i < preOperationModifyDNPlugins.length; i++)
     {
+      DirectoryServerPlugin p = preOperationModifyDNPlugins[i];
       if (modifyDNOperation.isInternalOperation() &&
           (! p.invokeForInternalOperations()))
       {
@@ -3105,6 +3037,10 @@
       {
         result = p.doPreOperation(modifyDNOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -3120,11 +3056,11 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        modifyDNOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        modifyDNOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationModifyDNPlugins,
+            modifyDNOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -3136,24 +3072,26 @@
                 modifyDNOperation.getOperationID());
         logError(message);
 
-        modifyDNOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        modifyDNOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationModifyDNPlugins,
+            modifyDNOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
+        registerSkippedPreOperationPlugins(i, preOperationModifyDNPlugins,
+            modifyDNOperation);
+
         return result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no pre-operation modify DN
-      // plugins registered, which is fine.
-      result = PreOperationPluginResult.SUCCESS;
+      // This should only happen if there were no pre-operation add plugins
+      // registered, which is fine.
+      result = PluginResult.PreOperation.continueOperationProcessing();
     }
 
     return result;
@@ -3169,14 +3107,17 @@
    *                          pre-operation plugins.
    *
    * @return  The result of processing the pre-operation search plugins.
+   *
+   * @throws CanceledOperationException if the operation should be canceled.
    */
-  public PreOperationPluginResult invokePreOperationSearchPlugins(
+  public PluginResult.PreOperation invokePreOperationSearchPlugins(
                                   PreOperationSearchOperation searchOperation)
-  {
-    PreOperationPluginResult result = null;
+      throws CanceledOperationException {
+    PluginResult.PreOperation result = null;
 
-    for (DirectoryServerPlugin p : preOperationSearchPlugins)
+    for (int i = 0; i < preOperationSearchPlugins.length; i++)
     {
+      DirectoryServerPlugin p = preOperationSearchPlugins[i];
       if (searchOperation.isInternalOperation() &&
           (! p.invokeForInternalOperations()))
       {
@@ -3187,6 +3128,10 @@
       {
         result = p.doPreOperation(searchOperation);
       }
+      catch (CanceledOperationException coe)
+      {
+        throw coe;
+      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -3202,11 +3147,11 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        searchOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        searchOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationSearchPlugins,
+             searchOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -3218,24 +3163,26 @@
                 searchOperation.getOperationID());
         logError(message);
 
-        searchOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        searchOperation.appendErrorMessage(message);
+        registerSkippedPreOperationPlugins(i, preOperationSearchPlugins,
+             searchOperation);
 
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
+        registerSkippedPreOperationPlugins(i, preOperationSearchPlugins,
+             searchOperation);
+
         return result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no pre-operation search plugins
+      // This should only happen if there were no pre-operation add plugins
       // registered, which is fine.
-      result = PreOperationPluginResult.SUCCESS;
+      result = PluginResult.PreOperation.continueOperationProcessing();
     }
 
     return result;
@@ -3252,10 +3199,11 @@
    *
    * @return  The result of processing the post-operation abandon plugins.
    */
-  public PostOperationPluginResult invokePostOperationAbandonPlugins(
+  public PluginResult.PostOperation invokePostOperationAbandonPlugins(
                               PostOperationAbandonOperation abandonOperation)
   {
-    PostOperationPluginResult result = null;
+    PluginResult.PostOperation result = null;
+    PluginResult.PostOperation finalResult = null;
 
     for (DirectoryServerPlugin p : postOperationAbandonPlugins)
     {
@@ -3283,12 +3231,6 @@
                 abandonOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        abandonOperation.setResultCode(
-                              DirectoryServer.getServerErrorResultCode());
-        abandonOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
 
       if (result == null)
@@ -3299,28 +3241,31 @@
                 abandonOperation.getConnectionID(),
                 abandonOperation.getOperationID());
         logError(message);
-
-        abandonOperation.setResultCode(
-                              DirectoryServer.getServerErrorResultCode());
-        abandonOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continueProcessing())
       {
-        return result;
+        // This plugin requested operation processing to stop. However, we
+        // still have to invoke all the post op plugins that successfully
+        // invoked its pre op plugins. We will just take this plugin's
+        // results as the final result.
+        finalResult = result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no post-operation abandon plugins
+      // This should only happen if there were no post-operation add plugins
       // registered, which is fine.
-      result = PostOperationPluginResult.SUCCESS;
+      finalResult = PluginResult.PostOperation.continueOperationProcessing();
+    }
+    else if(finalResult == null)
+    {
+      // None of the plugins requested processing to stop so all results
+      // have equal priority. Just return the last one.
+      finalResult = result;
     }
 
-    return result;
+    return finalResult;
   }
 
 
@@ -3334,10 +3279,11 @@
    *
    * @return  The result of processing the post-operation add plugins.
    */
-  public PostOperationPluginResult invokePostOperationAddPlugins(
+  public PluginResult.PostOperation invokePostOperationAddPlugins(
                                         PostOperationAddOperation addOperation)
   {
-    PostOperationPluginResult result = null;
+    PluginResult.PostOperation result = null;
+    PluginResult.PostOperation finalResult = null;
 
     for (DirectoryServerPlugin p : postOperationAddPlugins)
     {
@@ -3347,6 +3293,13 @@
         continue;
       }
 
+      ArrayList<DirectoryServerPlugin> skippedPlugins =
+          skippedPreOperationPlugins.remove(addOperation);
+      if(skippedPlugins != null && skippedPlugins.contains(p))
+      {
+        continue;
+      }
+
       try
       {
         result = p.doPostOperation(addOperation);
@@ -3364,11 +3317,6 @@
                 addOperation.getConnectionID(), addOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        addOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        addOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
 
       if (result == null)
@@ -3378,16 +3326,14 @@
                 String.valueOf(p.getPluginEntryDN()),
                 addOperation.getConnectionID(), addOperation.getOperationID());
         logError(message);
-
-        addOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        addOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continueProcessing())
       {
-        return result;
+        // This plugin requested operation processing to stop. However, we
+        // still have to invoke all the post op plugins that successfully
+        // invoked its pre op plugins. We will just take this plugin's
+        // results as the final result.
+        finalResult = result;
       }
     }
 
@@ -3395,10 +3341,16 @@
     {
       // This should only happen if there were no post-operation add plugins
       // registered, which is fine.
-      result = PostOperationPluginResult.SUCCESS;
+      finalResult = PluginResult.PostOperation.continueOperationProcessing();
+    }
+    else if(finalResult == null)
+    {
+      // None of the plugins requested processing to stop so all results
+      // have equal priority. Just return the last one.
+      finalResult = result;
     }
 
-    return result;
+    return finalResult;
   }
 
 
@@ -3412,10 +3364,11 @@
    *
    * @return  The result of processing the post-operation bind plugins.
    */
-  public PostOperationPluginResult invokePostOperationBindPlugins(
+  public PluginResult.PostOperation invokePostOperationBindPlugins(
                                    PostOperationBindOperation bindOperation)
   {
-    PostOperationPluginResult result = null;
+    PluginResult.PostOperation result = null;
+    PluginResult.PostOperation finalResult = null;
 
     for (DirectoryServerPlugin p : postOperationBindPlugins)
     {
@@ -3425,6 +3378,13 @@
         continue;
       }
 
+      ArrayList<DirectoryServerPlugin> skippedPlugins =
+          skippedPreOperationPlugins.remove(bindOperation);
+      if(skippedPlugins != null && skippedPlugins.contains(p))
+      {
+        continue;
+      }
+
       try
       {
         result = p.doPostOperation(bindOperation);
@@ -3442,11 +3402,6 @@
                 bindOperation.getConnectionID(), bindOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        bindOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        bindOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
 
       if (result == null)
@@ -3457,27 +3412,31 @@
                 bindOperation.getConnectionID(),
                 bindOperation.getOperationID());
         logError(message);
-
-        bindOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
-        bindOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continueProcessing())
       {
-        return result;
+        // This plugin requested operation processing to stop. However, we
+        // still have to invoke all the post op plugins that successfully
+        // invoked its pre op plugins. We will just take this plugin's
+        // results as the final result.
+        finalResult = result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no post-operation bind plugins
+      // This should only happen if there were no post-operation add plugins
       // registered, which is fine.
-      result = PostOperationPluginResult.SUCCESS;
+      finalResult = PluginResult.PostOperation.continueOperationProcessing();
+    }
+    else if(finalResult == null)
+    {
+      // None of the plugins requested processing to stop so all results
+      // have equal priority. Just return the last one.
+      finalResult = result;
     }
 
-    return result;
+    return finalResult;
   }
 
 
@@ -3491,10 +3450,11 @@
    *
    * @return  The result of processing the post-operation compare plugins.
    */
-  public PostOperationPluginResult invokePostOperationComparePlugins(
+  public PluginResult.PostOperation invokePostOperationComparePlugins(
       PostOperationCompareOperation compareOperation)
   {
-    PostOperationPluginResult result = null;
+    PluginResult.PostOperation result = null;
+    PluginResult.PostOperation finalResult = null;
 
     for (DirectoryServerPlugin p : postOperationComparePlugins)
     {
@@ -3504,6 +3464,13 @@
         continue;
       }
 
+      ArrayList<DirectoryServerPlugin> skippedPlugins =
+          skippedPreOperationPlugins.remove(compareOperation);
+      if(skippedPlugins != null && skippedPlugins.contains(p))
+      {
+        continue;
+      }
+
       try
       {
         result = p.doPostOperation(compareOperation);
@@ -3522,12 +3489,6 @@
                 compareOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        compareOperation.setResultCode(
-                              DirectoryServer.getServerErrorResultCode());
-        compareOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
 
       if (result == null)
@@ -3538,28 +3499,31 @@
                 compareOperation.getConnectionID(),
                 compareOperation.getOperationID());
         logError(message);
-
-        compareOperation.setResultCode(
-                              DirectoryServer.getServerErrorResultCode());
-        compareOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continueProcessing())
       {
-        return result;
+        // This plugin requested operation processing to stop. However, we
+        // still have to invoke all the post op plugins that successfully
+        // invoked its pre op plugins. We will just take this plugin's
+        // results as the final result.
+        finalResult = result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no post-operation compare plugins
+      // This should only happen if there were no post-operation add plugins
       // registered, which is fine.
-      result = PostOperationPluginResult.SUCCESS;
+      finalResult = PluginResult.PostOperation.continueOperationProcessing();
+    }
+    else if(finalResult == null)
+    {
+      // None of the plugins requested processing to stop so all results
+      // have equal priority. Just return the last one.
+      finalResult = result;
     }
 
-    return result;
+    return finalResult;
   }
 
 
@@ -3573,10 +3537,11 @@
    *
    * @return  The result of processing the post-operation delete plugins.
    */
-  public PostOperationPluginResult invokePostOperationDeletePlugins(
+  public PluginResult.PostOperation invokePostOperationDeletePlugins(
                                    PostOperationDeleteOperation deleteOperation)
   {
-    PostOperationPluginResult result = null;
+    PluginResult.PostOperation result = null;
+    PluginResult.PostOperation finalResult = null;
 
     for (DirectoryServerPlugin p : postOperationDeletePlugins)
     {
@@ -3586,6 +3551,13 @@
         continue;
       }
 
+      ArrayList<DirectoryServerPlugin> skippedPlugins =
+          skippedPreOperationPlugins.remove(deleteOperation);
+      if(skippedPlugins != null && skippedPlugins.contains(p))
+      {
+        continue;
+      }
+
       try
       {
         result = p.doPostOperation(deleteOperation);
@@ -3604,12 +3576,6 @@
                 deleteOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        deleteOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        deleteOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
 
       if (result == null)
@@ -3620,28 +3586,31 @@
                 deleteOperation.getConnectionID(),
                 deleteOperation.getOperationID());
         logError(message);
-
-        deleteOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        deleteOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continueProcessing())
       {
-        return result;
+        // This plugin requested operation processing to stop. However, we
+        // still have to invoke all the post op plugins that successfully
+        // invoked its pre op plugins. We will just take this plugin's
+        // results as the final result.
+        finalResult = result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no post-operation delete plugins
+      // This should only happen if there were no post-operation add plugins
       // registered, which is fine.
-      result = PostOperationPluginResult.SUCCESS;
+      finalResult = PluginResult.PostOperation.continueOperationProcessing();
+    }
+    else if(finalResult == null)
+    {
+      // None of the plugins requested processing to stop so all results
+      // have equal priority. Just return the last one.
+      finalResult = result;
     }
 
-    return result;
+    return finalResult;
   }
 
 
@@ -3655,10 +3624,11 @@
    *
    * @return  The result of processing the post-operation extended plugins.
    */
-  public PostOperationPluginResult invokePostOperationExtendedPlugins(
+  public PluginResult.PostOperation invokePostOperationExtendedPlugins(
                              PostOperationExtendedOperation extendedOperation)
   {
-    PostOperationPluginResult result = null;
+    PluginResult.PostOperation result = null;
+    PluginResult.PostOperation finalResult = null;
 
     for (DirectoryServerPlugin p : postOperationExtendedPlugins)
     {
@@ -3668,6 +3638,13 @@
         continue;
       }
 
+      ArrayList<DirectoryServerPlugin> skippedPlugins =
+          skippedPreOperationPlugins.remove(extendedOperation);
+      if(skippedPlugins != null && skippedPlugins.contains(p))
+      {
+        continue;
+      }
+
       try
       {
         result = p.doPostOperation(extendedOperation);
@@ -3686,12 +3663,6 @@
                 extendedOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        extendedOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        extendedOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
 
       if (result == null)
@@ -3702,28 +3673,31 @@
                 extendedOperation.getConnectionID(),
                 extendedOperation.getOperationID());
         logError(message);
-
-        extendedOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        extendedOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continueProcessing())
       {
-        return result;
+        // This plugin requested operation processing to stop. However, we
+        // still have to invoke all the post op plugins that successfully
+        // invoked its pre op plugins. We will just take this plugin's
+        // results as the final result.
+        finalResult = result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no post-operation extended
-      // plugins registered, which is fine.
-      result = PostOperationPluginResult.SUCCESS;
+      // This should only happen if there were no post-operation add plugins
+      // registered, which is fine.
+      finalResult = PluginResult.PostOperation.continueOperationProcessing();
+    }
+    else if(finalResult == null)
+    {
+      // None of the plugins requested processing to stop so all results
+      // have equal priority. Just return the last one.
+      finalResult = result;
     }
 
-    return result;
+    return finalResult;
   }
 
 
@@ -3737,10 +3711,11 @@
    *
    * @return  The result of processing the post-operation modify plugins.
    */
-  public PostOperationPluginResult invokePostOperationModifyPlugins(
+  public PluginResult.PostOperation invokePostOperationModifyPlugins(
                                    PostOperationModifyOperation modifyOperation)
   {
-    PostOperationPluginResult result = null;
+    PluginResult.PostOperation result = null;
+    PluginResult.PostOperation finalResult = null;
 
     for (DirectoryServerPlugin p : postOperationModifyPlugins)
     {
@@ -3750,6 +3725,13 @@
         continue;
       }
 
+      ArrayList<DirectoryServerPlugin> skippedPlugins =
+          skippedPreOperationPlugins.remove(modifyOperation);
+      if(skippedPlugins != null && skippedPlugins.contains(p))
+      {
+        continue;
+      }
+
       try
       {
         result = p.doPostOperation(modifyOperation);
@@ -3768,12 +3750,6 @@
                 modifyOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        modifyOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        modifyOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
 
       if (result == null)
@@ -3784,28 +3760,30 @@
                 modifyOperation.getConnectionID(),
                 modifyOperation.getOperationID());
         logError(message);
-
-        modifyOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        modifyOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continueProcessing())
       {
-        return result;
+        // This plugin requested operation processing to stop. However, we
+        // still have to invoke all the post op plugins that successfully
+        // invoked its pre op plugins. We will just take this plugin's
+        // results as the final result.
+        finalResult = result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no post-operation modify plugins
+      // This should only happen if there were no post-operation add plugins
       // registered, which is fine.
-      result = PostOperationPluginResult.SUCCESS;
+      finalResult = PluginResult.PostOperation.continueOperationProcessing();
     }
-
-    return result;
+    else if(finalResult == null)
+    {
+      // None of the plugins requested processing to stop so all results
+      // have equal priority. Just return the last one.
+      finalResult = result;
+    }
+    return finalResult;
   }
 
 
@@ -3819,10 +3797,11 @@
    *
    * @return  The result of processing the post-operation modify DN plugins.
    */
-  public PostOperationPluginResult invokePostOperationModifyDNPlugins(
+  public PluginResult.PostOperation invokePostOperationModifyDNPlugins(
                              PostOperationModifyDNOperation modifyDNOperation)
   {
-    PostOperationPluginResult result = null;
+    PluginResult.PostOperation result = null;
+    PluginResult.PostOperation finalResult = null;
 
     for (DirectoryServerPlugin p : postOperationModifyDNPlugins)
     {
@@ -3832,6 +3811,13 @@
         continue;
       }
 
+      ArrayList<DirectoryServerPlugin> skippedPlugins =
+          skippedPreOperationPlugins.remove(modifyDNOperation);
+      if(skippedPlugins != null && skippedPlugins.contains(p))
+      {
+        continue;
+      }
+
       try
       {
         result = p.doPostOperation(modifyDNOperation);
@@ -3850,12 +3836,6 @@
                 modifyDNOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        modifyDNOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        modifyDNOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
 
       if (result == null)
@@ -3866,28 +3846,31 @@
                 modifyDNOperation.getConnectionID(),
                 modifyDNOperation.getOperationID());
         logError(message);
-
-        modifyDNOperation.setResultCode(
-                               DirectoryServer.getServerErrorResultCode());
-        modifyDNOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continueProcessing())
       {
-        return result;
+        // This plugin requested operation processing to stop. However, we
+        // still have to invoke all the post op plugins that successfully
+        // invoked its pre op plugins. We will just take this plugin's
+        // results as the final result.
+        finalResult = result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no post-operation modify DN
-      // plugins registered, which is fine.
-      result = PostOperationPluginResult.SUCCESS;
+      // This should only happen if there were no post-operation add plugins
+      // registered, which is fine.
+      finalResult = PluginResult.PostOperation.continueOperationProcessing();
+    }
+    else if(finalResult == null)
+    {
+      // None of the plugins requested processing to stop so all results
+      // have equal priority. Just return the last one.
+      finalResult = result;
     }
 
-    return result;
+    return finalResult;
   }
 
 
@@ -3901,10 +3884,11 @@
    *
    * @return  The result of processing the post-operation search plugins.
    */
-  public PostOperationPluginResult invokePostOperationSearchPlugins(
+  public PluginResult.PostOperation invokePostOperationSearchPlugins(
                                    PostOperationSearchOperation searchOperation)
   {
-    PostOperationPluginResult result = null;
+    PluginResult.PostOperation result = null;
+    PluginResult.PostOperation finalResult = null;
 
     for (DirectoryServerPlugin p : postOperationSearchPlugins)
     {
@@ -3914,6 +3898,13 @@
         continue;
       }
 
+      ArrayList<DirectoryServerPlugin> skippedPlugins =
+          skippedPreOperationPlugins.remove(searchOperation);
+      if(skippedPlugins != null && skippedPlugins.contains(p))
+      {
+        continue;
+      }
+
       try
       {
         result = p.doPostOperation(searchOperation);
@@ -3932,12 +3923,6 @@
                 searchOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        searchOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        searchOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
 
       if (result == null)
@@ -3948,28 +3933,31 @@
                 searchOperation.getConnectionID(),
                 searchOperation.getOperationID());
         logError(message);
-
-        searchOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        searchOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continueProcessing())
       {
-        return result;
+        // This plugin requested operation processing to stop. However, we
+        // still have to invoke all the post op plugins that successfully
+        // invoked its pre op plugins. We will just take this plugin's
+        // results as the final result.
+        finalResult = result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no post-operation search plugins
+      // This should only happen if there were no post-operation add plugins
       // registered, which is fine.
-      result = PostOperationPluginResult.SUCCESS;
+      finalResult = PluginResult.PostOperation.continueOperationProcessing();
+    }
+    else if(finalResult == null)
+    {
+      // None of the plugins requested processing to stop so all results
+      // have equal priority. Just return the last one.
+      finalResult = result;
     }
 
-    return result;
+    return finalResult;
   }
 
 
@@ -3983,10 +3971,11 @@
    *
    * @return  The result of processing the post-operation unbind plugins.
    */
-  public PostOperationPluginResult invokePostOperationUnbindPlugins(
+  public PluginResult.PostOperation invokePostOperationUnbindPlugins(
                                  PostOperationUnbindOperation unbindOperation)
   {
-    PostOperationPluginResult result = null;
+    PluginResult.PostOperation result = null;
+    PluginResult.PostOperation finalResult = null;
 
     for (DirectoryServerPlugin p : postOperationUnbindPlugins)
     {
@@ -3996,6 +3985,13 @@
         continue;
       }
 
+      ArrayList<DirectoryServerPlugin> skippedPlugins =
+          skippedPreOperationPlugins.remove(unbindOperation);
+      if(skippedPlugins != null && skippedPlugins.contains(p))
+      {
+        continue;
+      }
+
       try
       {
         result = p.doPostOperation(unbindOperation);
@@ -4014,12 +4010,6 @@
                 unbindOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        unbindOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        unbindOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
 
       if (result == null)
@@ -4030,28 +4020,31 @@
                 unbindOperation.getConnectionID(),
                 unbindOperation.getOperationID());
         logError(message);
-
-        unbindOperation.setResultCode(
-                             DirectoryServer.getServerErrorResultCode());
-        unbindOperation.appendErrorMessage(message);
-
-        return new PostOperationPluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continueProcessing())
       {
-        return result;
+        // This plugin requested operation processing to stop. However, we
+        // still have to invoke all the post op plugins that successfully
+        // invoked its pre op plugins. We will just take this plugin's
+        // results as the final result.
+        finalResult = result;
       }
     }
 
     if (result == null)
     {
-      // This should only happen if there were no post-operation unbind plugins
+      // This should only happen if there were no post-operation add plugins
       // registered, which is fine.
-      result = PostOperationPluginResult.SUCCESS;
+      finalResult = PluginResult.PostOperation.continueOperationProcessing();
+    }
+    else if(finalResult == null)
+    {
+      // None of the plugins requested processing to stop so all results
+      // have equal priority. Just return the last one.
+      finalResult = result;
     }
 
-    return result;
+    return finalResult;
   }
 
 
@@ -4065,10 +4058,10 @@
    *
    * @return  The result of processing the post-response add plugins.
    */
-  public PostResponsePluginResult invokePostResponseAddPlugins(
+  public PluginResult.PostResponse invokePostResponseAddPlugins(
                                        PostResponseAddOperation addOperation)
   {
-    PostResponsePluginResult result = null;
+    PluginResult.PostResponse result = null;
 
     for (DirectoryServerPlugin p : postResponseAddPlugins)
     {
@@ -4095,8 +4088,6 @@
                 addOperation.getConnectionID(), addOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
 
       if (result == null)
@@ -4106,11 +4097,8 @@
                 String.valueOf(p.getPluginEntryDN()),
                 addOperation.getConnectionID(), addOperation.getOperationID());
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -4120,7 +4108,7 @@
     {
       // This should only happen if there were no post-response add plugins
       // registered, which is fine.
-      result = PostResponsePluginResult.SUCCESS;
+      result = PluginResult.PostResponse.continueOperationProcessing();
     }
 
     return result;
@@ -4137,10 +4125,10 @@
    *
    * @return  The result of processing the post-response bind plugins.
    */
-  public PostResponsePluginResult invokePostResponseBindPlugins(
+  public PluginResult.PostResponse invokePostResponseBindPlugins(
                                        PostResponseBindOperation bindOperation)
   {
-    PostResponsePluginResult result = null;
+    PluginResult.PostResponse result = null;
 
     for (DirectoryServerPlugin p : postResponseBindPlugins)
     {
@@ -4167,8 +4155,6 @@
                 bindOperation.getConnectionID(), bindOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
 
       if (result == null)
@@ -4179,11 +4165,8 @@
                 bindOperation.getConnectionID(),
                 bindOperation.getOperationID());
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -4191,9 +4174,9 @@
 
     if (result == null)
     {
-      // This should only happen if there were no post-response bind plugins
+      // This should only happen if there were no post-response add plugins
       // registered, which is fine.
-      result = PostResponsePluginResult.SUCCESS;
+      result = PluginResult.PostResponse.continueOperationProcessing();
     }
 
     return result;
@@ -4210,10 +4193,10 @@
    *
    * @return  The result of processing the post-response compare plugins.
    */
-  public PostResponsePluginResult invokePostResponseComparePlugins(
+  public PluginResult.PostResponse invokePostResponseComparePlugins(
       PostResponseCompareOperation compareOperation)
   {
-    PostResponsePluginResult result = null;
+    PluginResult.PostResponse result = null;
 
     for (DirectoryServerPlugin p : postResponseComparePlugins)
     {
@@ -4241,8 +4224,6 @@
                 compareOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
 
       if (result == null)
@@ -4253,11 +4234,8 @@
                 compareOperation.getConnectionID(),
                 compareOperation.getOperationID());
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -4265,9 +4243,9 @@
 
     if (result == null)
     {
-      // This should only happen if there were no post-response compare plugins
+      // This should only happen if there were no post-response add plugins
       // registered, which is fine.
-      result = PostResponsePluginResult.SUCCESS;
+      result = PluginResult.PostResponse.continueOperationProcessing();
     }
 
     return result;
@@ -4284,10 +4262,10 @@
    *
    * @return  The result of processing the post-response delete plugins.
    */
-  public PostResponsePluginResult invokePostResponseDeletePlugins(
+  public PluginResult.PostResponse invokePostResponseDeletePlugins(
                           PostResponseDeleteOperation deleteOperation)
   {
-    PostResponsePluginResult result = null;
+    PluginResult.PostResponse result = null;
 
     for (DirectoryServerPlugin p : postResponseDeletePlugins)
     {
@@ -4315,8 +4293,6 @@
                 deleteOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
 
       if (result == null)
@@ -4327,11 +4303,8 @@
                 deleteOperation.getConnectionID(),
                 deleteOperation.getOperationID());
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -4339,11 +4312,10 @@
 
     if (result == null)
     {
-      // This should only happen if there were no post-response delete plugins
+      // This should only happen if there were no post-response add plugins
       // registered, which is fine.
-      result = PostResponsePluginResult.SUCCESS;
+      result = PluginResult.PostResponse.continueOperationProcessing();
     }
-
     return result;
   }
 
@@ -4358,10 +4330,10 @@
    *
    * @return  The result of processing the post-response extended plugins.
    */
-  public PostResponsePluginResult invokePostResponseExtendedPlugins(
+  public PluginResult.PostResponse invokePostResponseExtendedPlugins(
                               PostResponseExtendedOperation extendedOperation)
   {
-    PostResponsePluginResult result = null;
+    PluginResult.PostResponse result = null;
 
     for (DirectoryServerPlugin p : postResponseExtendedPlugins)
     {
@@ -4389,8 +4361,6 @@
                 extendedOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
 
       if (result == null)
@@ -4401,11 +4371,8 @@
                 extendedOperation.getConnectionID(),
                 extendedOperation.getOperationID());
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -4413,9 +4380,9 @@
 
     if (result == null)
     {
-      // This should only happen if there were no post-response extended plugins
+      // This should only happen if there were no post-response add plugins
       // registered, which is fine.
-      result = PostResponsePluginResult.SUCCESS;
+      result = PluginResult.PostResponse.continueOperationProcessing();
     }
 
     return result;
@@ -4432,10 +4399,10 @@
    *
    * @return  The result of processing the post-response modify plugins.
    */
-  public PostResponsePluginResult invokePostResponseModifyPlugins(
+  public PluginResult.PostResponse invokePostResponseModifyPlugins(
                                   PostResponseModifyOperation modifyOperation)
   {
-    PostResponsePluginResult result = null;
+    PluginResult.PostResponse result = null;
 
     for (DirectoryServerPlugin p : postResponseModifyPlugins)
     {
@@ -4463,8 +4430,6 @@
                 modifyOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
 
       if (result == null)
@@ -4475,11 +4440,8 @@
                 modifyOperation.getConnectionID(),
                 modifyOperation.getOperationID());
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -4487,9 +4449,9 @@
 
     if (result == null)
     {
-      // This should only happen if there were no post-response modify plugins
+      // This should only happen if there were no post-response add plugins
       // registered, which is fine.
-      result = PostResponsePluginResult.SUCCESS;
+      result = PluginResult.PostResponse.continueOperationProcessing();
     }
 
     return result;
@@ -4506,10 +4468,10 @@
    *
    * @return  The result of processing the post-response modify DN plugins.
    */
-  public PostResponsePluginResult invokePostResponseModifyDNPlugins(
+  public PluginResult.PostResponse invokePostResponseModifyDNPlugins(
                                PostResponseModifyDNOperation modifyDNOperation)
   {
-    PostResponsePluginResult result = null;
+    PluginResult.PostResponse result = null;
 
     for (DirectoryServerPlugin p : postResponseModifyDNPlugins)
     {
@@ -4537,8 +4499,6 @@
                 modifyDNOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
 
       if (result == null)
@@ -4549,11 +4509,8 @@
                 modifyDNOperation.getConnectionID(),
                 modifyDNOperation.getOperationID());
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -4561,9 +4518,9 @@
 
     if (result == null)
     {
-      // This should only happen if there were no post-response modify DN
-      // plugins registered, which is fine.
-      result = PostResponsePluginResult.SUCCESS;
+      // This should only happen if there were no post-response add plugins
+      // registered, which is fine.
+      result = PluginResult.PostResponse.continueOperationProcessing();
     }
 
     return result;
@@ -4580,10 +4537,10 @@
    *
    * @return  The result of processing the post-response search plugins.
    */
-  public PostResponsePluginResult invokePostResponseSearchPlugins(
+  public PluginResult.PostResponse invokePostResponseSearchPlugins(
                                   PostResponseSearchOperation searchOperation)
   {
-    PostResponsePluginResult result = null;
+    PluginResult.PostResponse result = null;
 
     for (DirectoryServerPlugin p : postResponseSearchPlugins)
     {
@@ -4611,8 +4568,6 @@
                 searchOperation.getOperationID(),
                 stackTraceToSingleLineString(e));
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
 
       if (result == null)
@@ -4623,11 +4578,8 @@
                 searchOperation.getConnectionID(),
                 searchOperation.getOperationID());
         logError(message);
-
-        return new PostResponsePluginResult(false, false);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (!result.continuePluginProcessing())
       {
         return result;
       }
@@ -4635,9 +4587,9 @@
 
     if (result == null)
     {
-      // This should only happen if there were no post-response search plugins
+      // This should only happen if there were no post-response add plugins
       // registered, which is fine.
-      result = PostResponsePluginResult.SUCCESS;
+      result = PluginResult.PostResponse.continueOperationProcessing();
     }
 
     return result;
@@ -4798,11 +4750,11 @@
    *
    * @return  The result of processing the search result entry plugins.
    */
-  public SearchEntryPluginResult invokeSearchResultEntryPlugins(
+  public PluginResult.IntermediateResponse invokeSearchResultEntryPlugins(
                                  LocalBackendSearchOperation searchOperation,
                                  SearchResultEntry searchEntry)
   {
-    SearchEntryPluginResult result = null;
+    PluginResult.IntermediateResponse result = null;
 
     for (DirectoryServerPlugin p : searchResultEntryPlugins)
     {
@@ -4831,7 +4783,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        return new SearchEntryPluginResult(false, false, false, false);
+        return PluginResult.IntermediateResponse.stopProcessing(false,
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -4843,10 +4796,10 @@
                 String.valueOf(searchEntry.getDN()));
         logError(message);
 
-        return new SearchEntryPluginResult(false, false, false, false);
+        return PluginResult.IntermediateResponse.stopProcessing(false,
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (! result.continuePluginProcessing())
       {
         return result;
       }
@@ -4856,7 +4809,8 @@
     {
       // This should only happen if there were no search result entry plugins
       // registered, which is fine.
-      result = SearchEntryPluginResult.SUCCESS;
+      result = PluginResult.IntermediateResponse.
+          continueOperationProcessing(true);
     }
 
     return result;
@@ -4874,11 +4828,11 @@
    *
    * @return  The result of processing the search result entry plugins.
    */
-  public SearchEntryPluginResult invokeSearchResultEntryPlugins(
+  public PluginResult.IntermediateResponse invokeSearchResultEntryPlugins(
       SearchEntrySearchOperation searchOperation,
       SearchResultEntry searchEntry)
   {
-    SearchEntryPluginResult result = null;
+    PluginResult.IntermediateResponse result = null;
 
     for (DirectoryServerPlugin p : searchResultEntryPlugins)
     {
@@ -4913,7 +4867,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        return new SearchEntryPluginResult(false, false, false, false);
+        return PluginResult.IntermediateResponse.stopProcessing(false,
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -4925,10 +4880,10 @@
                 String.valueOf(searchEntry.getDN()));
         logError(message);
 
-        return new SearchEntryPluginResult(false, false, false, false);
+        return PluginResult.IntermediateResponse.stopProcessing(false,
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (! result.continuePluginProcessing())
       {
         return result;
       }
@@ -4938,7 +4893,8 @@
     {
       // This should only happen if there were no search result entry plugins
       // registered, which is fine.
-      result = SearchEntryPluginResult.SUCCESS;
+      result =
+          PluginResult.IntermediateResponse.continueOperationProcessing(true);
     }
 
     return result;
@@ -4956,11 +4912,11 @@
    *
    * @return  The result of processing the search result reference plugins.
    */
-  public SearchReferencePluginResult invokeSearchResultReferencePlugins(
+  public PluginResult.IntermediateResponse invokeSearchResultReferencePlugins(
                                    LocalBackendSearchOperation searchOperation,
                                    SearchResultReference searchReference)
   {
-    SearchReferencePluginResult result = null;
+    PluginResult.IntermediateResponse result = null;
 
     for (DirectoryServerPlugin p : searchResultReferencePlugins)
     {
@@ -4989,7 +4945,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        return new SearchReferencePluginResult(false, false, false, false);
+        return PluginResult.IntermediateResponse.stopProcessing(false,
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -5001,10 +4958,10 @@
                 searchReference.getReferralURLString());
         logError(message);
 
-        return new SearchReferencePluginResult(false, false, false, false);
+        return PluginResult.IntermediateResponse.stopProcessing(false,
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (! result.continuePluginProcessing())
       {
         return result;
       }
@@ -5014,7 +4971,8 @@
     {
       // This should only happen if there were no search result reference
       // plugins registered, which is fine.
-      result = SearchReferencePluginResult.SUCCESS;
+      result =
+          PluginResult.IntermediateResponse.continueOperationProcessing(true);
     }
 
     return result;
@@ -5032,11 +4990,11 @@
    *
    * @return  The result of processing the search result reference plugins.
    */
-  public SearchReferencePluginResult invokeSearchResultReferencePlugins(
+  public PluginResult.IntermediateResponse invokeSearchResultReferencePlugins(
       SearchReferenceSearchOperation searchOperation,
       SearchResultReference searchReference)
   {
-    SearchReferencePluginResult result = null;
+    PluginResult.IntermediateResponse result = null;
 
     for (DirectoryServerPlugin p : searchResultReferencePlugins)
     {
@@ -5065,7 +5023,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        return new SearchReferencePluginResult(false, false, false, false);
+        return PluginResult.IntermediateResponse.stopProcessing(false,
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -5077,10 +5036,10 @@
                 searchReference.getReferralURLString());
         logError(message);
 
-        return new SearchReferencePluginResult(false, false, false, false);
+        return PluginResult.IntermediateResponse.stopProcessing(false,
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (! result.continuePluginProcessing())
       {
         return result;
       }
@@ -5090,7 +5049,8 @@
     {
       // This should only happen if there were no search result reference
       // plugins registered, which is fine.
-      result = SearchReferencePluginResult.SUCCESS;
+      result =
+          PluginResult.IntermediateResponse.continueOperationProcessing(true);
     }
 
     return result;
@@ -5113,11 +5073,11 @@
    *
    * @return  The result of processing the subordinate modify DN plugins.
    */
-  public SubordinateModifyDNPluginResult invokeSubordinateModifyDNPlugins(
+  public PluginResult.SubordinateModifyDN invokeSubordinateModifyDNPlugins(
               SubordinateModifyDNOperation modifyDNOperation, Entry oldEntry,
               Entry newEntry, List<Modification> modifications)
   {
-    SubordinateModifyDNPluginResult result = null;
+    PluginResult.SubordinateModifyDN result = null;
 
     for (DirectoryServerPlugin p : subordinateModifyDNPlugins)
     {
@@ -5140,26 +5100,32 @@
         {
           TRACER.debugCaught(DebugLogLevel.ERROR, e);
         }
-        logError(ERR_PLUGIN_SUBORDINATE_MODIFY_DN_PLUGIN_EXCEPTION.get(
+
+        Message message =
+            ERR_PLUGIN_SUBORDINATE_MODIFY_DN_PLUGIN_EXCEPTION.get(
                 String.valueOf(p.getPluginEntryDN()),
                 modifyDNOperation.getConnectionID(),
                 modifyDNOperation.getOperationID(),
-                stackTraceToSingleLineString(e)));
+                stackTraceToSingleLineString(e));
+        logError(message);
 
-        return new SubordinateModifyDNPluginResult(false, false, true);
+        return PluginResult.SubordinateModifyDN.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
       {
-        logError(ERR_PLUGIN_SUBORDINATE_MODIFY_DN_PLUGIN_RETURNED_NULL.get(
+        Message message =
+            ERR_PLUGIN_SUBORDINATE_MODIFY_DN_PLUGIN_RETURNED_NULL.get(
                         String.valueOf(p.getPluginEntryDN()),
                         modifyDNOperation.getConnectionID(),
-                        String.valueOf(modifyDNOperation.getOperationID())));
+                        String.valueOf(modifyDNOperation.getOperationID()));
+        logError(message);
 
-        return new SubordinateModifyDNPluginResult(false, false, true);
+        return PluginResult.SubordinateModifyDN.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (! result.continuePluginProcessing())
       {
         return result;
       }
@@ -5169,7 +5135,7 @@
     {
       // This should only happen if there were no subordinate modify DN plugins
       // registered, which is fine.
-      result = SubordinateModifyDNPluginResult.SUCCESS;
+      result = PluginResult.SubordinateModifyDN.continueOperationProcessing();
     }
 
     return result;
@@ -5186,11 +5152,11 @@
    *
    * @return  The result of processing the intermediate response plugins.
    */
-  public IntermediateResponsePluginResult
+  public PluginResult.IntermediateResponse
               invokeIntermediateResponsePlugins(
                    IntermediateResponse intermediateResponse)
   {
-    IntermediateResponsePluginResult result = null;
+    PluginResult.IntermediateResponse result = null;
     Operation operation = intermediateResponse.getOperation();
 
     for (DirectoryServerPlugin p : intermediateResponsePlugins)
@@ -5212,7 +5178,8 @@
                 stackTraceToSingleLineString(e));
         logError(message);
 
-        return new IntermediateResponsePluginResult(false, false, false, false);
+        return PluginResult.IntermediateResponse.stopProcessing
+            (false, DirectoryServer.getServerErrorResultCode(), message);
       }
 
       if (result == null)
@@ -5222,10 +5189,10 @@
                 operation.getConnectionID(), operation.getOperationID());
         logError(message);
 
-        return new IntermediateResponsePluginResult(false, false, false, false);
+        return PluginResult.IntermediateResponse.stopProcessing
+            (false, DirectoryServer.getServerErrorResultCode(), message);
       }
-      else if (result.connectionTerminated() ||
-               (! result.continuePluginProcessing()))
+      else if (! result.continuePluginProcessing())
       {
         return result;
       }
@@ -5235,7 +5202,8 @@
     {
       // This should only happen if there were no intermediate response plugins
       // registered, which is fine.
-      result = IntermediateResponsePluginResult.SUCCESS;
+      result =
+          PluginResult.IntermediateResponse.continueOperationProcessing(true);
     }
 
     return result;
@@ -5478,5 +5446,31 @@
 
     return new ConfigChangeResult(resultCode, adminActionRequired, messages);
   }
+
+  private void registerSkippedPreOperationPlugins(int i,
+                                                DirectoryServerPlugin[] plugins,
+                                                 PluginOperation operation)
+  {
+    ArrayList<DirectoryServerPlugin> skippedPlugins =
+        new ArrayList<DirectoryServerPlugin>(plugins.length - i);
+    for(int j = i; j < plugins.length; j++)
+    {
+      skippedPlugins.add(plugins[j]);
+    }
+    skippedPreOperationPlugins.put(operation, skippedPlugins);
+  }
+
+  private void registerSkippedPreOperationPlugin(DirectoryServerPlugin plugin,
+                                                 PluginOperation operation)
+  {
+    ArrayList<DirectoryServerPlugin> existingList =
+        skippedPreOperationPlugins.get(operation);
+    if(existingList == null)
+    {
+      existingList = new ArrayList<DirectoryServerPlugin>();
+    }
+    existingList.add(plugin);
+    skippedPreOperationPlugins.put(operation, existingList);
+  }
 }
 
diff --git a/opends/src/server/org/opends/server/core/RootDseWorkflowTopology.java b/opends/src/server/org/opends/server/core/RootDseWorkflowTopology.java
index 3ec7f01..ea88331 100644
--- a/opends/src/server/org/opends/server/core/RootDseWorkflowTopology.java
+++ b/opends/src/server/org/opends/server/core/RootDseWorkflowTopology.java
@@ -27,10 +27,7 @@
 package org.opends.server.core;
 
 
-import org.opends.server.types.DN;
-import org.opends.server.types.Operation;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.SearchScope;
+import org.opends.server.types.*;
 
 
 /**
@@ -70,11 +67,12 @@
    * Executes an operation on the root DSE entry.
    *
    * @param operation the operation to execute
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public void execute(
-      Operation operation
-      )
-  {
+  public void execute(Operation operation)
+      throws CanceledOperationException {
     // Execute the operation.
     OperationType operationType = operation.getOperationType();
     if (operationType != OperationType.SEARCH)
@@ -94,11 +92,12 @@
    * Executes a search operation on the the root DSE entry.
    *
    * @param searchOp the operation to execute
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  private void executeSearch(
-      SearchOperation searchOp
-      )
-  {
+  private void executeSearch(SearchOperation searchOp)
+      throws CanceledOperationException {
     // Keep a the original search scope because we will alter it in the
     // operation.
     SearchScope originalScope = searchOp.getScope();
diff --git a/opends/src/server/org/opends/server/core/SearchOperationBasis.java b/opends/src/server/org/opends/server/core/SearchOperationBasis.java
index c435408..eeb8611 100644
--- a/opends/src/server/org/opends/server/core/SearchOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -36,37 +36,14 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.PreParsePluginResult;
-import org.opends.server.api.plugin.SearchEntryPluginResult;
-import org.opends.server.api.plugin.SearchReferencePluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.controls.AccountUsableResponseControl;
 import org.opends.server.controls.MatchedValuesControl;
 import org.opends.server.loggers.debug.DebugLogger;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.protocols.ldap.LDAPFilter;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.AttributeValue;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DereferencePolicy;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.Entry;
-import org.opends.server.types.FilterType;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.RawFilter;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchFilter;
-import org.opends.server.types.SearchResultEntry;
-import org.opends.server.types.SearchResultReference;
-import org.opends.server.types.SearchScope;
+import org.opends.server.types.*;
 import org.opends.server.types.operation.PostResponseSearchOperation;
 import org.opends.server.types.operation.PreParseSearchOperation;
 import org.opends.server.types.operation.SearchEntrySearchOperation;
@@ -122,9 +99,6 @@
   // The raw, unprocessed base DN as included in the request from the client.
   private ByteString rawBaseDN;
 
-  // The cancel request that has been issued for this search operation.
-  private CancelRequest cancelRequest;
-
   // The dereferencing policy for the search operation.
   private DereferencePolicy derefPolicy;
 
@@ -694,8 +668,7 @@
       try
       {
         // FIXME -- Need a way to enable PWP debugging.
-        PasswordPolicyState pwpState = new PasswordPolicyState(entry, false,
-                                                               false);
+        PasswordPolicyState pwpState = new PasswordPolicyState(entry, false);
 
         boolean isInactive           = pwpState.isDisabled() ||
                                        pwpState.isAccountExpired();
@@ -997,23 +970,12 @@
         .getAccessControlHandler().filterEntry(this, searchEntry);
 
     // Invoke any search entry plugins that may be registered with the server.
-    SearchEntryPluginResult pluginResult =
+    PluginResult.IntermediateResponse pluginResult =
          DirectoryServer.getPluginConfigManager().
               invokeSearchResultEntryPlugins(this, searchEntry);
-    if (pluginResult.connectionTerminated())
-    {
-      // We won't attempt to send this entry, and we won't continue with
-      // any processing.  Just update the operation to indicate that it was
-      // cancelled and return false.
-      setResultCode(ResultCode.CANCELED);
-      appendErrorMessage(ERR_CANCELED_BY_SEARCH_ENTRY_DISCONNECT.get(
-              String.valueOf(entry.getDN())));
-      return false;
-    }
-
 
     // Send the entry to the client.
-    if (pluginResult.sendEntry())
+    if (pluginResult.sendResponse())
     {
       try
       {
@@ -1035,7 +997,7 @@
       }
     }
 
-    return pluginResult.continueSearch();
+    return pluginResult.continueProcessing();
   }
 
   /**
@@ -1080,26 +1042,15 @@
 
     // Invoke any search reference plugins that may be registered with the
     // server.
-    SearchReferencePluginResult pluginResult =
+    PluginResult.IntermediateResponse pluginResult =
          DirectoryServer.getPluginConfigManager().
               invokeSearchResultReferencePlugins(this, reference);
-    if (pluginResult.connectionTerminated())
-    {
-      // We won't attempt to send this entry, and we won't continue with
-      // any processing.  Just update the operation to indicate that it was
-      // cancelled and return false.
-      setResultCode(ResultCode.CANCELED);
-      appendErrorMessage(ERR_CANCELED_BY_SEARCH_REF_DISCONNECT.get(
-              String.valueOf(reference.getReferralURLString())));
-      return false;
-    }
-
 
     // Send the reference to the client.  Note that this could throw an
     // exception, which would indicate that the associated client can't handle
     // referrals.  If that't the case, then set a flag so we'll know not to try
     // to send any more.
-    if (pluginResult.sendReference())
+    if (pluginResult.sendResponse())
     {
       try
       {
@@ -1130,7 +1081,7 @@
       }
     }
 
-    return pluginResult.continueSearch();
+    return pluginResult.continueProcessing();
   }
 
   /**
@@ -1171,17 +1122,6 @@
    * {@inheritDoc}
    */
   @Override()
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, Message message
-  )
-  {
-    clientConnection.disconnect(disconnectReason, sendNotification, message);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
   public final String[][] getRequestLogElements()
   {
     // Note that no debugging will be done in this method because it is a likely
@@ -1323,71 +1263,27 @@
     responseControls.remove(control);
   }
 
+
+
   /**
    * {@inheritDoc}
    */
   @Override()
-  public final CancelResult cancel(CancelRequest cancelRequest)
+  public void abort(CancelRequest cancelRequest)
   {
-    this.cancelRequest = cancelRequest;
-
-    if (persistentSearch != null)
+    if(cancelResult == null && this.cancelRequest == null)
     {
-      DirectoryServer.deregisterPersistentSearch(persistentSearch);
-      persistentSearch = null;
-    }
+      this.cancelRequest = cancelRequest;
 
-    CancelResult cancelResult = getCancelResult();
-    long stopWaitingTime = System.currentTimeMillis() + 5000;
-    while ((cancelResult == null) &&
-           (System.currentTimeMillis() < stopWaitingTime))
-    {
-      try
+      if (persistentSearch != null)
       {
-        Thread.sleep(50);
+        DirectoryServer.deregisterPersistentSearch(persistentSearch);
+        persistentSearch = null;
       }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-      }
-
-      cancelResult = getCancelResult();
     }
-
-    if (cancelResult == null)
-    {
-      // This can happen in some rare cases (e.g., if a client disconnects and
-      // there is still a lot of data to send to that client), and in this case
-      // we'll prevent the cancel thread from blocking for a long period of
-      // time.
-      cancelResult = CancelResult.CANNOT_CANCEL;
-    }
-
-    return cancelResult;
   }
 
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelRequest getCancelRequest()
-  {
-    return cancelRequest;
-  }
 
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public
-  boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-    return true;
-  }
 
   /**
    * {@inheritDoc}
@@ -1600,15 +1496,19 @@
   public final void run()
   {
     setResultCode(ResultCode.UNDEFINED);
+
+    // Start the processing timer.
+    setProcessingStartTime();
+
+    // Log the search request message.
+    logSearchRequest(this);
+
     setSendResponse(true);
 
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
-      DirectoryServer.getPluginConfigManager();
+        DirectoryServer.getPluginConfigManager();
 
-
-    // Start the processing timer.
-    setProcessingStartTime();
     int timeLimit = getTimeLimit();
     Long timeLimitExpiration;
     if (timeLimit <= 0)
@@ -1619,69 +1519,36 @@
     {
       // FIXME -- Factor in the user's effective time limit.
       timeLimitExpiration =
-        getProcessingStartTime() + (1000L * timeLimit);
+          getProcessingStartTime() + (1000L * timeLimit);
     }
     setTimeLimitExpiration(timeLimitExpiration);
 
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
+    try
     {
-      indicateCancelled(cancelRequest);
-      setProcessingStopTime();
-      logSearchResultDone(this);
-      return;
-    }
+      // Check for and handle a request to cancel this operation.
+      checkIfCanceled(false);
 
+      PluginResult.PreParse preParseResult =
+          pluginConfigManager.invokePreParseSearchPlugins(this);
 
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-searchProcessing:
-    {
-      PreParsePluginResult preParseResult =
-        pluginConfigManager.invokePreParseSearchPlugins(this);
-      if (preParseResult.connectionTerminated())
+      if(!preParseResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the request and
-        // result and return.
-        setResultCode(ResultCode.CANCELED);
-
-        appendErrorMessage(ERR_CANCELED_BY_PREPARSE_DISCONNECT.get());
-
-        setProcessingStopTime();
-
-        logSearchRequest(this);
-        logSearchResultDone(this);
-        pluginConfigManager.invokePostResponseSearchPlugins(this);
+        setResultCode(preParseResult.getResultCode());
+        appendErrorMessage(preParseResult.getErrorMessage());
+        setMatchedDN(preParseResult.getMatchedDN());
+        setReferralURLs(preParseResult.getReferralURLs());
         return;
       }
-      else if (preParseResult.sendResponseImmediately())
-      {
-        logSearchRequest(this);
-        break searchProcessing;
-      }
-      else if (preParseResult.skipCoreProcessing())
-      {
-        break searchProcessing;
-      }
-
-
-      // Log the search request message.
-      logSearchRequest(this);
-
 
       // Check for and handle a request to cancel this operation.
-      if (cancelRequest != null)
-      {
-        break searchProcessing;
-      }
-
+      checkIfCanceled(false);
 
       // 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.
       DN baseDN = getBaseDN();
       if (baseDN == null){
-        break searchProcessing;
+        return;
       }
 
 
@@ -1694,61 +1561,56 @@
         // We have found no workflow for the requested base DN, just return
         // a no such entry result code and stop the processing.
         updateOperationErrMsgAndResCode();
-        break searchProcessing;
+        return;
       }
       workflow.execute(this);
     }
+    catch(CanceledOperationException coe)
+    {
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, coe);
+      }
 
+      setResultCode(ResultCode.CANCELED);
+      cancelResult = new CancelResult(ResultCode.CANCELED, null);
 
-    // Check for a terminated connection.
-    if (getCancelResult() == CancelResult.CANCELED)
+      appendErrorMessage(coe.getCancelRequest().getCancelReason());
+    }
+    finally
     {
       // Stop the processing timer.
       setProcessingStopTime();
 
-      // Log the add response message.
-      logSearchResultDone(this);
+      if(cancelRequest == null || cancelResult == null ||
+          cancelResult.getResultCode() != ResultCode.CANCELED)
+      {
+        // If everything is successful to this point and it is not a persistent
+        // search, then send the search result done message to the client.
+        // Otherwise, we'll want to make the size and time limit values
+        // unlimited to ensure that the remainder of the persistent search
+        // isn't subject to those restrictions.
+        if (isSendResponse())
+        {
+          sendSearchResultDone();
+        }
+        else
+        {
+          setSizeLimit(0);
+          setTimeLimit(0);
+        }
+      }
+      else if(cancelRequest.notifyOriginalRequestor() ||
+          DirectoryServer.notifyAbandonedOperations())
+      {
+        sendSearchResultDone();
+      }
 
-      return;
-    }
-
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
-    {
-      indicateCancelled(cancelRequest);
-
-      // Stop the processing timer.
-      setProcessingStopTime();
-
-      // Log the search response message.
-      logSearchResultDone(this);
-
-      // Invoke the post-response search plugins.
-      invokePostResponsePlugins();
-
-      return;
-    }
-
-
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
-
-    // Stop the processing timer.
-    setProcessingStopTime();
-
-    // If everything is successful to this point and it is not a persistent
-    // search, then send the search result done message to the client.
-    // Otherwise, we'll want to make the size and time limit values unlimited
-    // to ensure that the remainder of the persistent search isn't subject to
-    // those restrictions.
-    if (isSendResponse())
-    {
-      sendSearchResultDone();
-    }
-    else
-    {
-      setSizeLimit(0);
-      setTimeLimit(0);
+      // If no cancel result, set it
+      if(cancelResult == null)
+      {
+        cancelResult = new CancelResult(ResultCode.TOO_LATE, null);
+      }
     }
   }
 
diff --git a/opends/src/server/org/opends/server/core/UnbindOperationBasis.java b/opends/src/server/org/opends/server/core/UnbindOperationBasis.java
index f4cefce..4db93c1 100644
--- a/opends/src/server/org/opends/server/core/UnbindOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/UnbindOperationBasis.java
@@ -25,8 +25,6 @@
  *      Copyright 2006-2008 Sun Microsystems, Inc.
  */
 package org.opends.server.core;
-import org.opends.messages.Message;
-
 
 
 import java.util.ArrayList;
@@ -35,12 +33,7 @@
 import org.opends.server.api.ClientConnection;
 import org.opends.server.loggers.debug.DebugLogger;
 import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.OperationType;
+import org.opends.server.types.*;
 import org.opends.server.types.operation.PostOperationUnbindOperation;
 import org.opends.server.types.operation.PreParseUnbindOperation;
 
@@ -78,6 +71,8 @@
   {
     super(clientConnection, operationID, messageID, requestControls);
 
+    cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL,
+        ERR_CANNOT_CANCEL_UNBIND.get());
   }
 
 
@@ -100,19 +95,6 @@
    * {@inheritDoc}
    */
   @Override()
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, Message message)
-  {
-    clientConnection.disconnect(disconnectReason, sendNotification,
-            message);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
   public final String[][] getRequestLogElements()
   {
     // Note that no debugging will be done in this method because it is a likely
@@ -186,7 +168,6 @@
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
          DirectoryServer.getPluginConfigManager();
-    boolean skipPostOperation = false;
 
     setProcessingStartTime();
 
@@ -221,41 +202,6 @@
    * {@inheritDoc}
    */
   @Override()
-  public final CancelResult cancel(CancelRequest cancelRequest)
-  {
-    cancelRequest.addResponseMessage(ERR_CANNOT_CANCEL_UNBIND.get());
-    return CancelResult.CANNOT_CANCEL;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelRequest getCancelRequest()
-  {
-    return null;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    // Unbind operations cannot be canceled.
-    return false;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
   public final void toString(StringBuilder buffer)
   {
     buffer.append("UnbindOperation(connID=");
diff --git a/opends/src/server/org/opends/server/core/Workflow.java b/opends/src/server/org/opends/server/core/Workflow.java
index 6e7efcb..ef6f431 100644
--- a/opends/src/server/org/opends/server/core/Workflow.java
+++ b/opends/src/server/org/opends/server/core/Workflow.java
@@ -29,6 +29,7 @@
 
 import org.opends.server.types.DN;
 import org.opends.server.types.Operation;
+import org.opends.server.types.CanceledOperationException;
 
 
 /**
@@ -68,6 +69,10 @@
    * operation.
    *
    * @param operation  the operation to execute
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public void execute(Operation operation);
+  public void execute(Operation operation)
+      throws CanceledOperationException;
 }
diff --git a/opends/src/server/org/opends/server/core/WorkflowImpl.java b/opends/src/server/org/opends/server/core/WorkflowImpl.java
index 1921f13..f0a729e 100644
--- a/opends/src/server/org/opends/server/core/WorkflowImpl.java
+++ b/opends/src/server/org/opends/server/core/WorkflowImpl.java
@@ -33,10 +33,7 @@
 import java.util.Collection;
 import java.util.TreeMap;
 
-import org.opends.server.types.DN;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.Operation;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 import org.opends.server.workflowelement.WorkflowElement;
 
 
@@ -159,11 +156,11 @@
    * operation.
    *
    * @param operation  the operation to execute
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public void execute(
-      Operation operation
-      )
-  {
+  public void execute(Operation operation) throws CanceledOperationException {
     rootWorkflowElement.execute(operation);
   }
 
diff --git a/opends/src/server/org/opends/server/core/WorkflowTopologyNode.java b/opends/src/server/org/opends/server/core/WorkflowTopologyNode.java
index ad3367f..858b540 100644
--- a/opends/src/server/org/opends/server/core/WorkflowTopologyNode.java
+++ b/opends/src/server/org/opends/server/core/WorkflowTopologyNode.java
@@ -29,10 +29,7 @@
 
 import java.util.ArrayList;
 
-import org.opends.server.types.DN;
-import org.opends.server.types.Operation;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.SearchScope;
+import org.opends.server.types.*;
 import org.opends.server.workflowelement.WorkflowElement;
 
 
@@ -93,11 +90,12 @@
    * workflow node base DN.
    *
    * @param operation the operation to execute
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  public void execute(
-      Operation operation
-      )
-  {
+  public void execute(Operation operation)
+      throws CanceledOperationException {
     // Execute the operation
     getWorkflowImpl().execute(operation);
 
@@ -114,11 +112,12 @@
    * Executes a search operation on the subordinate workflows.
    *
    * @param searchOp the search operation to execute
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
    */
-  private void executeSearchOnSubordinates(
-      SearchOperation searchOp
-      )
-  {
+  private void executeSearchOnSubordinates(SearchOperation searchOp)
+      throws CanceledOperationException {
     // If the scope of the search is 'base' then it's useless to search
     // in the subordinate workflows.
     SearchScope originalScope = searchOp.getScope();
diff --git a/opends/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java b/opends/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java
index e38090d..afd8b15 100644
--- a/opends/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java
+++ b/opends/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java
@@ -443,7 +443,7 @@
     try
     {
       PasswordPolicyState pwPolicyState =
-           new PasswordPolicyState(userEntry, false, false);
+           new PasswordPolicyState(userEntry, false);
       clearPasswords = pwPolicyState.getClearPasswords();
       if ((clearPasswords == null) || clearPasswords.isEmpty())
       {
diff --git a/opends/src/server/org/opends/server/extensions/CancelExtendedOperation.java b/opends/src/server/org/opends/server/extensions/CancelExtendedOperation.java
index 88a63a8..b84684f 100644
--- a/opends/src/server/org/opends/server/extensions/CancelExtendedOperation.java
+++ b/opends/src/server/org/opends/server/extensions/CancelExtendedOperation.java
@@ -29,7 +29,6 @@
 
 
 import org.opends.messages.Message;
-import org.opends.messages.MessageBuilder;
 import org.opends.server.admin.std.server.CancelExtendedOperationHandlerCfg;
 import org.opends.server.api.ClientConnection;
 import org.opends.server.api.ExtendedOperationHandler;
@@ -171,9 +170,7 @@
     // Create the cancel request for the target operation.
     Message cancelReason =
         INFO_EXTOP_CANCEL_REASON.get(operation.getMessageID());
-    MessageBuilder cancelResultMessage = new MessageBuilder();
-    CancelRequest cancelRequest = new CancelRequest(true, cancelReason,
-                                                    cancelResultMessage);
+    CancelRequest cancelRequest = new CancelRequest(true, cancelReason);
 
 
     // Get the client connection and attempt the cancel.
@@ -184,7 +181,7 @@
 
     // Update the result of the extended operation and return.
     operation.setResultCode(cancelResult.getResultCode());
-    operation.setErrorMessage(cancelResultMessage);
+    operation.appendErrorMessage(cancelResult.getResponseMessage());
   }
 }
 
diff --git a/opends/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandler.java b/opends/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandler.java
index 21a0936..c1e1b9e 100644
--- a/opends/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandler.java
+++ b/opends/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandler.java
@@ -1020,7 +1020,7 @@
     try
     {
       PasswordPolicyState pwPolicyState =
-           new PasswordPolicyState(userEntry, false, false);
+           new PasswordPolicyState(userEntry, false);
       clearPasswords = pwPolicyState.getClearPasswords();
       if ((clearPasswords == null) || clearPasswords.isEmpty())
       {
diff --git a/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java b/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
index 15abf5c..4c15ec8 100644
--- a/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
+++ b/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
@@ -486,7 +486,7 @@
       PasswordPolicyState pwPolicyState;
       try
       {
-        pwPolicyState = new PasswordPolicyState(userEntry, false, false);
+        pwPolicyState = new PasswordPolicyState(userEntry, false);
       }
       catch (DirectoryException de)
       {
diff --git a/opends/src/server/org/opends/server/extensions/PasswordPolicyStateExtendedOperation.java b/opends/src/server/org/opends/server/extensions/PasswordPolicyStateExtendedOperation.java
index f2be395..50ee497 100644
--- a/opends/src/server/org/opends/server/extensions/PasswordPolicyStateExtendedOperation.java
+++ b/opends/src/server/org/opends/server/extensions/PasswordPolicyStateExtendedOperation.java
@@ -645,7 +645,7 @@
     PasswordPolicy      policy;
     try
     {
-      pwpState = new PasswordPolicyState(userEntry, false, false);
+      pwpState = new PasswordPolicyState(userEntry, false);
       policy   = pwpState.getPolicy();
     }
     catch (DirectoryException de)
diff --git a/opends/src/server/org/opends/server/extensions/PlainSASLMechanismHandler.java b/opends/src/server/org/opends/server/extensions/PlainSASLMechanismHandler.java
index fc5c6b8..ee3a4b2 100644
--- a/opends/src/server/org/opends/server/extensions/PlainSASLMechanismHandler.java
+++ b/opends/src/server/org/opends/server/extensions/PlainSASLMechanismHandler.java
@@ -510,7 +510,7 @@
     try
     {
       PasswordPolicyState pwPolicyState =
-           new PasswordPolicyState(userEntry, false, false);
+           new PasswordPolicyState(userEntry, false);
       if (! pwPolicyState.passwordMatches(new ASN1OctetString(password)))
       {
         bindOperation.setResultCode(ResultCode.INVALID_CREDENTIALS);
diff --git a/opends/src/server/org/opends/server/extensions/TraditionalWorkQueue.java b/opends/src/server/org/opends/server/extensions/TraditionalWorkQueue.java
index a833bc8..a007102 100644
--- a/opends/src/server/org/opends/server/extensions/TraditionalWorkQueue.java
+++ b/opends/src/server/org/opends/server/extensions/TraditionalWorkQueue.java
@@ -46,7 +46,6 @@
 import org.opends.server.monitors.TraditionalWorkQueueMonitor;
 import org.opends.server.types.AbstractOperation;
 import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
 import org.opends.server.types.ConfigChangeResult;
 import org.opends.server.types.DebugLogLevel;
 import org.opends.server.types.DirectoryException;
@@ -231,8 +230,7 @@
         // The operation has no chance of responding to the cancel
         // request so avoid waiting for a cancel response.
         if (o.getCancelResult() == null) {
-          o.setCancelResult(CancelResult.CANCELED);
-          o.cancel(cancelRequest);
+          o.abort(cancelRequest);
         }
       }
       catch (Exception e)
diff --git a/opends/src/server/org/opends/server/extensions/TraditionalWorkerThread.java b/opends/src/server/org/opends/server/extensions/TraditionalWorkerThread.java
index 1cff4ff..d7c164f 100644
--- a/opends/src/server/org/opends/server/extensions/TraditionalWorkerThread.java
+++ b/opends/src/server/org/opends/server/extensions/TraditionalWorkerThread.java
@@ -35,7 +35,6 @@
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.AbstractOperation;
 import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
 import org.opends.server.types.DebugLogLevel;
 import org.opends.server.types.DisconnectReason;
 
@@ -159,19 +158,9 @@
         else
         {
           // The operation is not null, so process it.  Make sure that when
-          // processing is complete the cancel status is properly set.
-          try
-          {
-            operation.run();
-            operation.operationCompleted();
-          }
-          finally
-          {
-            if (operation.getCancelResult() == null)
-            {
-              operation.setCancelResult(CancelResult.TOO_LATE);
-            }
-          }
+          // processing is complete.
+          operation.run();
+          operation.operationCompleted();
         }
       }
       catch (Throwable t)
diff --git a/opends/src/server/org/opends/server/plugins/EntryUUIDPlugin.java b/opends/src/server/org/opends/server/plugins/EntryUUIDPlugin.java
index 30481f7..f7e3e32 100644
--- a/opends/src/server/org/opends/server/plugins/EntryUUIDPlugin.java
+++ b/opends/src/server/org/opends/server/plugins/EntryUUIDPlugin.java
@@ -41,10 +41,7 @@
 import org.opends.server.admin.std.meta.PluginCfgDefn;
 import org.opends.server.admin.std.server.EntryUUIDPluginCfg;
 import org.opends.server.admin.std.server.PluginCfg;
-import org.opends.server.api.plugin.DirectoryServerPlugin;
-import org.opends.server.api.plugin.LDIFPluginResult;
-import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.*;
 import org.opends.server.config.ConfigException;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.AttributeType;
@@ -172,15 +169,15 @@
    * {@inheritDoc}
    */
   @Override()
-  public final LDIFPluginResult doLDIFImport(LDIFImportConfig importConfig,
-                                             Entry entry)
+  public final PluginResult.ImportLDIF
+               doLDIFImport(LDIFImportConfig importConfig, Entry entry)
   {
     // See if the entry being imported already contains an entryUUID attribute.
     // If so, then leave it alone.
     List<Attribute> uuidList = entry.getAttribute(entryUUIDType);
     if (uuidList != null)
     {
-      return LDIFPluginResult.SUCCESS;
+      return PluginResult.ImportLDIF.continueEntryProcessing();
     }
 
 
@@ -201,7 +198,7 @@
 
 
     // We shouldn't ever need to return a non-success result.
-    return LDIFPluginResult.SUCCESS;
+    return PluginResult.ImportLDIF.continueEntryProcessing();
   }
 
 
@@ -210,8 +207,8 @@
    * {@inheritDoc}
    */
   @Override()
-  public final PreOperationPluginResult
-       doPreOperation(PreOperationAddOperation addOperation)
+  public final PluginResult.PreOperation
+               doPreOperation(PreOperationAddOperation addOperation)
   {
     // See if the entry being added already contains an entryUUID attribute.
     // It shouldn't, since it's NO-USER-MODIFICATION, but if it does then leave
@@ -221,7 +218,7 @@
     List<Attribute> uuidList = operationalAttributes.get(entryUUIDType);
     if (uuidList != null)
     {
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
 
 
@@ -239,7 +236,7 @@
 
     // Add the attribute to the entry and return.
     addOperation.setAttribute(entryUUIDType, uuidList);
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
diff --git a/opends/src/server/org/opends/server/plugins/LDAPADListPlugin.java b/opends/src/server/org/opends/server/plugins/LDAPADListPlugin.java
index 502408c..4ce5a41 100644
--- a/opends/src/server/org/opends/server/plugins/LDAPADListPlugin.java
+++ b/opends/src/server/org/opends/server/plugins/LDAPADListPlugin.java
@@ -38,7 +38,7 @@
 import org.opends.server.admin.std.server.PluginCfg;
 import org.opends.server.api.plugin.DirectoryServerPlugin;
 import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PreParsePluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.config.ConfigException;
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.ConfigChangeResult;
@@ -145,8 +145,8 @@
    * {@inheritDoc}
    */
   @Override()
-  public final PreParsePluginResult
-       doPreParse(PreParseSearchOperation searchOperation)
+  public final PluginResult.PreParse
+               doPreParse(PreParseSearchOperation searchOperation)
   {
     // Iterate through the requested attributes to see if any of them start with
     // an "@" symbol.  If not, then we don't need to do anything.  If so, then
@@ -207,7 +207,7 @@
     }
 
 
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
diff --git a/opends/src/server/org/opends/server/plugins/LastModPlugin.java b/opends/src/server/org/opends/server/plugins/LastModPlugin.java
index 17c3f4a..c1287c3 100644
--- a/opends/src/server/org/opends/server/plugins/LastModPlugin.java
+++ b/opends/src/server/org/opends/server/plugins/LastModPlugin.java
@@ -40,7 +40,7 @@
 import org.opends.server.admin.std.server.PluginCfg;
 import org.opends.server.api.plugin.DirectoryServerPlugin;
 import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.config.ConfigException;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.types.Attribute;
@@ -172,8 +172,8 @@
    * {@inheritDoc}
    */
   @Override()
-  public final PreOperationPluginResult
-       doPreOperation(PreOperationAddOperation addOperation)
+  public final PluginResult.PreOperation
+               doPreOperation(PreOperationAddOperation addOperation)
   {
     // Create the attribute list for the creatorsName attribute, if appropriate.
     DN creatorDN = addOperation.getAuthorizationDN();
@@ -212,7 +212,7 @@
 
 
     // We shouldn't ever need to return a non-success result.
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -221,7 +221,7 @@
    * {@inheritDoc}
    */
   @Override()
-  public final PreOperationPluginResult
+  public final PluginResult.PreOperation
        doPreOperation(PreOperationModifyOperation modifyOperation)
   {
     // Create the modifiersName attribute.
@@ -255,9 +255,8 @@
       }
 
       // This should never happen.
-      modifyOperation.setResultCode(DirectoryConfig.getServerErrorResultCode());
-      modifyOperation.appendErrorMessage(de.getMessageObject());
-      return new PreOperationPluginResult(false, false, true);
+      return PluginResult.PreOperation.stopProcessing(
+          DirectoryConfig.getServerErrorResultCode(), de.getMessageObject());
     }
 
 
@@ -282,14 +281,13 @@
       }
 
       // This should never happen.
-      modifyOperation.setResultCode(DirectoryConfig.getServerErrorResultCode());
-      modifyOperation.appendErrorMessage(de.getMessageObject());
-      return new PreOperationPluginResult(false, false, true);
+      return PluginResult.PreOperation.stopProcessing(
+          DirectoryConfig.getServerErrorResultCode(), de.getMessageObject());
     }
 
 
     // We shouldn't ever need to return a non-success result.
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -298,7 +296,7 @@
    * {@inheritDoc}
    */
   @Override()
-  public final PreOperationPluginResult
+  public final PluginResult.PreOperation
        doPreOperation(PreOperationModifyDNOperation modifyDNOperation)
   {
     // Create the modifiersName attribute.
@@ -336,7 +334,7 @@
 
 
     // We shouldn't ever need to return a non-success result.
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
diff --git a/opends/src/server/org/opends/server/plugins/PasswordPolicyImportPlugin.java b/opends/src/server/org/opends/server/plugins/PasswordPolicyImportPlugin.java
index 61aec91..8595253 100644
--- a/opends/src/server/org/opends/server/plugins/PasswordPolicyImportPlugin.java
+++ b/opends/src/server/org/opends/server/plugins/PasswordPolicyImportPlugin.java
@@ -46,8 +46,8 @@
 import org.opends.server.api.ImportTaskListener;
 import org.opends.server.api.PasswordStorageScheme;
 import org.opends.server.api.plugin.DirectoryServerPlugin;
-import org.opends.server.api.plugin.LDIFPluginResult;
 import org.opends.server.api.plugin.PluginType;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.PasswordPolicy;
@@ -335,8 +335,8 @@
    * {@inheritDoc}
    */
   @Override()
-  public final LDIFPluginResult doLDIFImport(LDIFImportConfig importConfig,
-                                             Entry entry)
+  public final PluginResult.ImportLDIF
+               doLDIFImport(LDIFImportConfig importConfig, Entry entry)
   {
     // Create a list that we will use to hold new encoded values.
     ArrayList<ByteString> encodedValueList = new ArrayList<ByteString>();
@@ -384,7 +384,7 @@
           attrList = entry.getAttribute(policy.getPasswordAttribute());
           if (attrList == null)
           {
-            return LDIFPluginResult.SUCCESS;
+            return PluginResult.ImportLDIF.continueEntryProcessing();
           }
 
           for (Attribute a : attrList)
@@ -470,7 +470,7 @@
             }
           }
 
-          return LDIFPluginResult.SUCCESS;
+          return PluginResult.ImportLDIF.continueEntryProcessing();
         }
       }
     }
@@ -592,7 +592,7 @@
     }
 
 
-    return LDIFPluginResult.SUCCESS;
+    return PluginResult.ImportLDIF.continueEntryProcessing();
   }
 
 
diff --git a/opends/src/server/org/opends/server/plugins/ReferentialIntegrityPlugin.java b/opends/src/server/org/opends/server/plugins/ReferentialIntegrityPlugin.java
index 98f382a..e38a507 100644
--- a/opends/src/server/org/opends/server/plugins/ReferentialIntegrityPlugin.java
+++ b/opends/src/server/org/opends/server/plugins/ReferentialIntegrityPlugin.java
@@ -51,10 +51,7 @@
 import org.opends.server.api.Backend;
 import org.opends.server.api.DirectoryThread;
 import org.opends.server.api.ServerShutdownListener;
-import org.opends.server.api.plugin.DirectoryServerPlugin;
-import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.SubordinateModifyDNPluginResult;
+import org.opends.server.api.plugin.*;
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.ModifyOperation;
@@ -377,7 +374,7 @@
    * {@inheritDoc}
    */
   @SuppressWarnings("unchecked")
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
          doPostOperation(PostOperationModifyDNOperation
           modifyDNOperation)
   {
@@ -385,7 +382,7 @@
     // nothing changed.
     if (modifyDNOperation.getResultCode() != ResultCode.SUCCESS)
     {
-      return PostOperationPluginResult.SUCCESS;
+      return PluginResult.PostOperation.continueOperationProcessing();
     }
 
     if (modifyDNOperation.getNewSuperior() == null)
@@ -406,7 +403,7 @@
       processModifyDN(modDNmap, (interval != 0));
     }
 
-    return PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -414,25 +411,25 @@
   /**
    * {@inheritDoc}
    */
-  public PostOperationPluginResult doPostOperation(
+  public PluginResult.PostOperation doPostOperation(
               PostOperationDeleteOperation deleteOperation)
   {
     // If the operation itself failed, then we don't need to do anything because
     // nothing changed.
     if (deleteOperation.getResultCode() != ResultCode.SUCCESS)
     {
-      return PostOperationPluginResult.SUCCESS;
+      return PluginResult.PostOperation.continueOperationProcessing();
     }
 
     processDelete(deleteOperation.getEntryDN(), (interval != 0));
-    return  PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
   /**
    * {@inheritDoc}
    */
   @SuppressWarnings("unchecked")
-  public SubordinateModifyDNPluginResult processSubordinateModifyDN(
+  public PluginResult.SubordinateModifyDN processSubordinateModifyDN(
           SubordinateModifyDNOperation modifyDNOperation, Entry oldEntry,
           Entry newEntry, List<Modification> modifications)
   {
@@ -448,7 +445,7 @@
       modifyDNOperation.setAttachment(MODIFYDN_DNS, modDNmap);
     }
     modDNmap.put(oldEntry.getDN(), newEntry.getDN());
-    return SubordinateModifyDNPluginResult.SUCCESS;
+    return PluginResult.SubordinateModifyDN.continueOperationProcessing();
   }
 
 
diff --git a/opends/src/server/org/opends/server/plugins/SevenBitCleanPlugin.java b/opends/src/server/org/opends/server/plugins/SevenBitCleanPlugin.java
index fce3962..797fed8 100644
--- a/opends/src/server/org/opends/server/plugins/SevenBitCleanPlugin.java
+++ b/opends/src/server/org/opends/server/plugins/SevenBitCleanPlugin.java
@@ -36,10 +36,7 @@
 import org.opends.server.admin.std.meta.PluginCfgDefn;
 import org.opends.server.admin.std.server.SevenBitCleanPluginCfg;
 import org.opends.server.admin.std.server.PluginCfg;
-import org.opends.server.api.plugin.DirectoryServerPlugin;
-import org.opends.server.api.plugin.LDIFPluginResult;
-import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PreParsePluginResult;
+import org.opends.server.api.plugin.*;
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.Attribute;
@@ -81,15 +78,6 @@
 
 
 
-  /**
-   * The result that should be returned if a pre-parse operation fails the 7-bit
-   * clean check.
-   */
-  private static final PreParsePluginResult PRE_PARSE_FAILURE_RESULT =
-       new PreParsePluginResult(false, false, false, true);
-
-
-
   // The current configuration for this plugin.
   private SevenBitCleanPluginCfg currentConfig;
 
@@ -157,8 +145,8 @@
    * {@inheritDoc}
    */
   @Override()
-  public final LDIFPluginResult doLDIFImport(LDIFImportConfig importConfig,
-                                             Entry entry)
+  public final PluginResult.ImportLDIF
+               doLDIFImport(LDIFImportConfig importConfig, Entry entry)
   {
     // Get the current configuration for this plugin.
     SevenBitCleanPluginCfg config = currentConfig;
@@ -184,7 +172,7 @@
       if (! found)
       {
         // The entry is out of scope, so we won't process it.
-        return LDIFPluginResult.SUCCESS;
+        return PluginResult.ImportLDIF.continueEntryProcessing();
       }
     }
 
@@ -204,7 +192,7 @@
               Message rejectMessage =
                    ERR_PLUGIN_7BIT_IMPORT_ATTR_NOT_CLEAN.get(
                         a.getNameWithOptions());
-              return new LDIFPluginResult(false, false, rejectMessage);
+              return PluginResult.ImportLDIF.stopEntryProcessing(rejectMessage);
             }
           }
         }
@@ -213,7 +201,7 @@
 
 
     // If we've gotten here, then everything is acceptable.
-    return LDIFPluginResult.SUCCESS;
+    return PluginResult.ImportLDIF.continueEntryProcessing();
   }
 
 
@@ -222,8 +210,8 @@
    * {@inheritDoc}
    */
   @Override()
-  public final PreParsePluginResult
-                    doPreParse(PreParseAddOperation addOperation)
+  public final PluginResult.PreParse
+               doPreParse(PreParseAddOperation addOperation)
   {
     // Get the current configuration for this plugin.
     SevenBitCleanPluginCfg config = currentConfig;
@@ -238,9 +226,8 @@
     }
     catch (DirectoryException de)
     {
-      addOperation.appendErrorMessage(
-           ERR_PLUGIN_7BIT_CANNOT_DECODE_DN.get(de.getMessageObject()));
-      return PRE_PARSE_FAILURE_RESULT;
+      return PluginResult.PreParse.stopProcessing(de.getResultCode(),
+          ERR_PLUGIN_7BIT_CANNOT_DECODE_DN.get(de.getMessageObject()));
     }
 
     if (isInScope(config, entryDN))
@@ -254,9 +241,10 @@
         }
         catch (LDAPException le)
         {
-          addOperation.appendErrorMessage(
-               ERR_PLUGIN_7BIT_CANNOT_DECODE_DN.get(le.getMessageObject()));
-          return PRE_PARSE_FAILURE_RESULT;
+          return PluginResult.PreParse.stopProcessing(
+              ResultCode.valueOf(le.getResultCode()),
+              ERR_PLUGIN_7BIT_CANNOT_DECODE_ATTR.get(
+                  rawAttr.getAttributeType(), le.getErrorMessage()));
         }
 
         if (! config.getAttributeType().contains(a.getAttributeType()))
@@ -268,10 +256,10 @@
         {
           if (! is7BitClean(v.getValue()))
           {
-            addOperation.appendErrorMessage(
-                 ERR_PLUGIN_7BIT_ADD_ATTR_NOT_CLEAN.get(
-                      rawAttr.getAttributeType()));
-            return PRE_PARSE_FAILURE_RESULT;
+            return PluginResult.PreParse.stopProcessing(
+                ResultCode.CONSTRAINT_VIOLATION,
+                ERR_PLUGIN_7BIT_MODIFYDN_ATTR_NOT_CLEAN.get(
+                    rawAttr.getAttributeType()));
           }
         }
       }
@@ -279,7 +267,7 @@
 
 
     // If we've gotten here, then everything is acceptable.
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -288,7 +276,7 @@
    * {@inheritDoc}
    */
   @Override()
-  public final PreParsePluginResult
+  public final PluginResult.PreParse
                     doPreParse(PreParseModifyOperation modifyOperation)
   {
     // Get the current configuration for this plugin.
@@ -304,9 +292,8 @@
     }
     catch (DirectoryException de)
     {
-      modifyOperation.appendErrorMessage(
-           ERR_PLUGIN_7BIT_CANNOT_DECODE_DN.get(de.getMessageObject()));
-      return PRE_PARSE_FAILURE_RESULT;
+      return PluginResult.PreParse.stopProcessing(de.getResultCode(),
+          ERR_PLUGIN_7BIT_CANNOT_DECODE_DN.get(de.getMessageObject()));
     }
 
     if (isInScope(config, entryDN))
@@ -332,9 +319,10 @@
         }
         catch (LDAPException le)
         {
-          modifyOperation.appendErrorMessage(
-               ERR_PLUGIN_7BIT_CANNOT_DECODE_DN.get(le.getMessageObject()));
-          return PRE_PARSE_FAILURE_RESULT;
+          return PluginResult.PreParse.stopProcessing(
+              ResultCode.valueOf(le.getResultCode()),
+              ERR_PLUGIN_7BIT_CANNOT_DECODE_ATTR.get(
+                  rawAttr.getAttributeType(), le.getErrorMessage()));
         }
 
         if (! config.getAttributeType().contains(a.getAttributeType()))
@@ -346,10 +334,10 @@
         {
           if (! is7BitClean(v.getValue()))
           {
-            modifyOperation.appendErrorMessage(
-                 ERR_PLUGIN_7BIT_MODIFY_ATTR_NOT_CLEAN.get(
-                      rawAttr.getAttributeType()));
-            return PRE_PARSE_FAILURE_RESULT;
+            return PluginResult.PreParse.stopProcessing(
+                ResultCode.CONSTRAINT_VIOLATION,
+                ERR_PLUGIN_7BIT_MODIFYDN_ATTR_NOT_CLEAN.get(
+                    rawAttr.getAttributeType()));
           }
         }
       }
@@ -357,7 +345,7 @@
 
 
     // If we've gotten here, then everything is acceptable.
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -366,7 +354,7 @@
    * {@inheritDoc}
    */
   @Override()
-  public final PreParsePluginResult
+  public final PluginResult.PreParse
                     doPreParse(PreParseModifyDNOperation modifyDNOperation)
   {
     // Get the current configuration for this plugin.
@@ -382,9 +370,8 @@
     }
     catch (DirectoryException de)
     {
-      modifyDNOperation.appendErrorMessage(
-           ERR_PLUGIN_7BIT_CANNOT_DECODE_DN.get(de.getMessageObject()));
-      return PRE_PARSE_FAILURE_RESULT;
+      return PluginResult.PreParse.stopProcessing(de.getResultCode(),
+          ERR_PLUGIN_7BIT_CANNOT_DECODE_DN.get(de.getMessageObject()));
     }
 
     if (isInScope(config, entryDN))
@@ -398,9 +385,8 @@
       }
       catch (DirectoryException de)
       {
-        modifyDNOperation.appendErrorMessage(
-             ERR_PLUGIN_7BIT_CANNOT_DECODE_NEW_RDN.get(de.getMessageObject()));
-        return PRE_PARSE_FAILURE_RESULT;
+        return PluginResult.PreParse.stopProcessing(de.getResultCode(),
+            ERR_PLUGIN_7BIT_CANNOT_DECODE_NEW_RDN.get(de.getMessageObject()));
       }
 
       int numValues = newRDN.getNumValues();
@@ -413,17 +399,17 @@
 
         if (! is7BitClean(newRDN.getAttributeValue(i).getValue()))
         {
-          modifyDNOperation.appendErrorMessage(
-               ERR_PLUGIN_7BIT_MODIFYDN_ATTR_NOT_CLEAN.get(
-                    newRDN.getAttributeName(i)));
-          return PRE_PARSE_FAILURE_RESULT;
+          return PluginResult.PreParse.stopProcessing(
+              ResultCode.CONSTRAINT_VIOLATION,
+              ERR_PLUGIN_7BIT_MODIFYDN_ATTR_NOT_CLEAN.get(
+                  newRDN.getAttributeName(i)));
         }
       }
     }
 
 
     // If we've gotten here, then everything is acceptable.
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
diff --git a/opends/src/server/org/opends/server/plugins/UniqueAttributePlugin.java b/opends/src/server/org/opends/server/plugins/UniqueAttributePlugin.java
index 6cb155c..7fe1a98 100644
--- a/opends/src/server/org/opends/server/plugins/UniqueAttributePlugin.java
+++ b/opends/src/server/org/opends/server/plugins/UniqueAttributePlugin.java
@@ -43,7 +43,7 @@
 import org.opends.server.api.Backend;
 import org.opends.server.api.plugin.DirectoryServerPlugin;
 import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.loggers.debug.DebugTracer;
@@ -101,15 +101,6 @@
 
 
   /**
-   * The pre-operation plugin result that should be returned if an operation
-   * would have resulted in a unique attribute conflict.
-   */
-  private static final PreOperationPluginResult FAILED_PREOP_RESULT =
-       new PreOperationPluginResult(false, false, false, true);
-
-
-
-  /**
    * The set of attributes that will be requested when performing internal
    * search operations.  This indicates that no attributes should be returned.
    */
@@ -200,7 +191,7 @@
    * {@inheritDoc}
    */
   @Override()
-  public final PreOperationPluginResult
+  public final PluginResult.PreOperation
                doPreOperation(PreOperationAddOperation addOperation)
   {
     UniqueAttributePluginCfg config = currentConfiguration;
@@ -210,7 +201,7 @@
     if (baseDNs == null)
     {
       // The entry is outside the scope of this plugin.
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
 
     for (AttributeType t : config.getType())
@@ -228,11 +219,11 @@
                                                     config, v);
               if (conflictDN != null)
               {
-                addOperation.appendErrorMessage(
-                     ERR_PLUGIN_UNIQUEATTR_ATTR_NOT_UNIQUE.get(t.getNameOrOID(),
-                          v.getStringValue(), conflictDN.toString()));
-                addOperation.setResultCode(ResultCode.CONSTRAINT_VIOLATION);
-                return FAILED_PREOP_RESULT;
+                Message msg = ERR_PLUGIN_UNIQUEATTR_ATTR_NOT_UNIQUE.get(
+                    t.getNameOrOID(), v.getStringValue(),
+                    conflictDN.toString());
+                return PluginResult.PreOperation.stopProcessing(
+                    ResultCode.CONSTRAINT_VIOLATION, msg);
               }
             }
             catch (DirectoryException de)
@@ -246,17 +237,15 @@
                                de.getResultCode().toString(),
                                de.getMessageObject());
 
-              addOperation.setResultCode(
-                   DirectoryServer.getServerErrorResultCode());
-              addOperation.appendErrorMessage(m);
-              return FAILED_PREOP_RESULT;
+              return PluginResult.PreOperation.stopProcessing(
+                    DirectoryServer.getServerErrorResultCode(), m);
             }
           }
         }
       }
     }
 
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -265,7 +254,7 @@
    * {@inheritDoc}
    */
   @Override()
-  public final PreOperationPluginResult
+  public final PluginResult.PreOperation
                doPreOperation(PreOperationModifyOperation modifyOperation)
   {
     UniqueAttributePluginCfg config = currentConfiguration;
@@ -275,7 +264,7 @@
     if (baseDNs == null)
     {
       // The entry is outside the scope of this plugin.
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
 
     for (Modification m : modifyOperation.getModifications())
@@ -300,11 +289,11 @@
                                                     v);
               if (conflictDN != null)
               {
-                modifyOperation.appendErrorMessage(
-                     ERR_PLUGIN_UNIQUEATTR_ATTR_NOT_UNIQUE.get(t.getNameOrOID(),
-                          v.getStringValue(), conflictDN.toString()));
-                modifyOperation.setResultCode(ResultCode.CONSTRAINT_VIOLATION);
-                return FAILED_PREOP_RESULT;
+                Message msg = ERR_PLUGIN_UNIQUEATTR_ATTR_NOT_UNIQUE.get(
+                    t.getNameOrOID(), v.getStringValue(),
+                    conflictDN.toString());
+                return PluginResult.PreOperation.stopProcessing(
+                    ResultCode.CONSTRAINT_VIOLATION, msg);
               }
             }
             catch (DirectoryException de)
@@ -318,10 +307,8 @@
                                      de.getResultCode().toString(),
                                      de.getMessageObject());
 
-              modifyOperation.setResultCode(
-                   DirectoryServer.getServerErrorResultCode());
-              modifyOperation.appendErrorMessage(message);
-              return FAILED_PREOP_RESULT;
+              return PluginResult.PreOperation.stopProcessing(
+                    DirectoryServer.getServerErrorResultCode(), message);
             }
           }
           break;
@@ -349,13 +336,11 @@
                                                         config, v);
                   if (conflictDN != null)
                   {
-                    modifyOperation.appendErrorMessage(
-                         ERR_PLUGIN_UNIQUEATTR_ATTR_NOT_UNIQUE.get(
-                              t.getNameOrOID(), v.getStringValue(),
-                              conflictDN.toString()));
-                    modifyOperation.setResultCode(
-                         ResultCode.CONSTRAINT_VIOLATION);
-                    return FAILED_PREOP_RESULT;
+                    Message msg = ERR_PLUGIN_UNIQUEATTR_ATTR_NOT_UNIQUE.get(
+                        t.getNameOrOID(), v.getStringValue(),
+                        conflictDN.toString());
+                    return PluginResult.PreOperation.stopProcessing(
+                        ResultCode.CONSTRAINT_VIOLATION, msg);
                   }
                 }
                 catch (DirectoryException de)
@@ -369,10 +354,8 @@
                                          de.getResultCode().toString(),
                                          de.getMessageObject());
 
-                  modifyOperation.setResultCode(
-                       DirectoryServer.getServerErrorResultCode());
-                  modifyOperation.appendErrorMessage(message);
-                  return FAILED_PREOP_RESULT;
+                  return PluginResult.PreOperation.stopProcessing(
+                      DirectoryServer.getServerErrorResultCode(), message);
                 }
               }
             }
@@ -386,7 +369,7 @@
       }
     }
 
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -395,7 +378,7 @@
    * {@inheritDoc}
    */
   @Override()
-  public final PreOperationPluginResult doPreOperation(
+  public final PluginResult.PreOperation doPreOperation(
                     PreOperationModifyDNOperation modifyDNOperation)
   {
     UniqueAttributePluginCfg config = currentConfiguration;
@@ -405,7 +388,7 @@
     if (baseDNs == null)
     {
       // The entry is outside the scope of this plugin.
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
 
     RDN newRDN = modifyDNOperation.getNewRDN();
@@ -422,14 +405,14 @@
       {
         AttributeValue v = newRDN.getAttributeValue(i);
         DN conflictDN = getConflictingEntryDN(baseDNs,
-                             modifyDNOperation.getEntryDN(), config, v);
+            modifyDNOperation.getEntryDN(), config, v);
         if (conflictDN != null)
         {
-          modifyDNOperation.appendErrorMessage(
-               ERR_PLUGIN_UNIQUEATTR_ATTR_NOT_UNIQUE.get(t.getNameOrOID(),
-                    v.getStringValue(), conflictDN.toString()));
-          modifyDNOperation.setResultCode(ResultCode.CONSTRAINT_VIOLATION);
-          return FAILED_PREOP_RESULT;
+          Message msg = ERR_PLUGIN_UNIQUEATTR_ATTR_NOT_UNIQUE.get(
+              t.getNameOrOID(), v.getStringValue(),
+              conflictDN.toString());
+          return PluginResult.PreOperation.stopProcessing(
+              ResultCode.CONSTRAINT_VIOLATION, msg);
         }
       }
       catch (DirectoryException de)
@@ -443,14 +426,12 @@
                          de.getResultCode().toString(),
                          de.getMessageObject());
 
-        modifyDNOperation.setResultCode(
-             DirectoryServer.getServerErrorResultCode());
-        modifyDNOperation.appendErrorMessage(m);
-        return FAILED_PREOP_RESULT;
+        return PluginResult.PreOperation.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), m);
       }
     }
 
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
diff --git a/opends/src/server/org/opends/server/plugins/profiler/ProfilerPlugin.java b/opends/src/server/org/opends/server/plugins/profiler/ProfilerPlugin.java
index 0519510..f8b07d5 100644
--- a/opends/src/server/org/opends/server/plugins/profiler/ProfilerPlugin.java
+++ b/opends/src/server/org/opends/server/plugins/profiler/ProfilerPlugin.java
@@ -40,7 +40,7 @@
 import org.opends.server.admin.std.server.ProfilerPluginCfg;
 import org.opends.server.api.plugin.DirectoryServerPlugin;
 import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.StartupPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.config.ConfigException;
 import org.opends.server.types.ConfigChangeResult;
 import org.opends.server.types.DirectoryConfig;
@@ -223,7 +223,7 @@
    * {@inheritDoc}
    */
   @Override()
-  public final StartupPluginResult doStartup()
+  public final PluginResult.Startup doStartup()
   {
     ProfilerPluginCfg config = currentConfig;
 
@@ -234,7 +234,7 @@
       profilerThread.start();
     }
 
-    return StartupPluginResult.SUCCESS;
+    return PluginResult.Startup.continueStartup();
   }
 
 
diff --git a/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java b/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java
index 300ef39..f778f8e 100644
--- a/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java
+++ b/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java
@@ -2964,7 +2964,9 @@
                                       CancelRequest cancelRequest)
   {
     // Internal operations cannot be cancelled.
-    return CancelResult.CANNOT_CANCEL;
+    // TODO: i18n
+    return new CancelResult(ResultCode.CANNOT_CANCEL,
+        Message.raw("Internal operations cannot be cancelled"));
   }
 
 
diff --git a/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java b/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
index bbbcdb2..179a4dd 100644
--- a/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
+++ b/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
@@ -1158,7 +1158,9 @@
                                       CancelRequest cancelRequest)
   {
     // Jmx operations cannot be cancelled.
-    return CancelResult.CANNOT_CANCEL;
+    // TODO: i18n
+    return new CancelResult(ResultCode.CANNOT_CANCEL,
+        Message.raw("Jmx operations cannot be cancelled"));
   }
 
 
diff --git a/opends/src/server/org/opends/server/protocols/jmx/RmiAuthenticator.java b/opends/src/server/org/opends/server/protocols/jmx/RmiAuthenticator.java
index 73a0afb..2cf741a 100644
--- a/opends/src/server/org/opends/server/protocols/jmx/RmiAuthenticator.java
+++ b/opends/src/server/org/opends/server/protocols/jmx/RmiAuthenticator.java
@@ -32,7 +32,7 @@
 import javax.management.remote.JMXAuthenticator;
 import javax.security.auth.Subject;
 
-import org.opends.server.api.plugin.PostConnectPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.core.BindOperationBasis;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.PluginConfigManager;
@@ -199,11 +199,22 @@
     // invoke the post-connect plugins.
     PluginConfigManager pluginManager = DirectoryServer
         .getPluginConfigManager();
-    PostConnectPluginResult pluginResult = pluginManager
+    PluginResult.PostConnect pluginResult = pluginManager
         .invokePostConnectPlugins(jmxClientConnection);
-    if (pluginResult.connectionTerminated())
+    if (!pluginResult.continueProcessing())
     {
-      SecurityException se = new SecurityException(pluginResult.toString());
+      jmxClientConnection.disconnect(pluginResult.getDisconnectReason(),
+          pluginResult.sendDisconnectNotification(),
+          pluginResult.getErrorMessage());
+
+      if (debugEnabled())
+      {
+        TRACER.debugVerbose("Disconnect result from post connect plugins: " +
+            "%s: %s ", pluginResult.getDisconnectReason(),
+            pluginResult.getErrorMessage());
+      }
+
+      SecurityException se = new SecurityException();
       throw se;
     }
 
diff --git a/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java b/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
index 6ed56e6..6091c41 100644
--- a/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
+++ b/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
@@ -975,8 +975,11 @@
     // Indicate that this connection is no longer valid.
     connectionValid = false;
 
-
-    cancelAllOperations(new CancelRequest(true, message));
+    MessageBuilder msgBuilder = new MessageBuilder();
+    msgBuilder.append(disconnectReason.getClosureMessage());
+    msgBuilder.append(": ");
+    msgBuilder.append(message);
+    cancelAllOperations(new CancelRequest(true, msgBuilder.toMessage()));
     finalizeConnectionInternal();
 
 
@@ -1271,7 +1274,8 @@
           CancelResult cancelResult =
                ps.getSearchOperation().cancel(cancelRequest);
 
-          if (keepStats && (cancelResult == CancelResult.CANCELED))
+          if (keepStats && (cancelResult.getResultCode() ==
+              ResultCode.CANCELED))
           {
             statTracker.updateAbandonedOperation();
           }
@@ -1280,12 +1284,12 @@
         }
       }
 
-      return CancelResult.NO_SUCH_OPERATION;
+      return new CancelResult(ResultCode.NO_SUCH_OPERATION, null);
     }
     else
     {
       CancelResult cancelResult = op.cancel(cancelRequest);
-      if (keepStats && (cancelResult == CancelResult.CANCELED))
+      if (keepStats && (cancelResult.getResultCode() == ResultCode.CANCELED))
       {
         statTracker.updateAbandonedOperation();
       }
@@ -1313,16 +1317,10 @@
         {
           try
           {
-            CancelResult cancelResult = o.getCancelResult();
-            if (cancelResult == null) {
-              // Before calling cancelling the operation, we need to
-              // mark this operation as cancelled so that the attempt to
-              // cancel it later won't cause an unnecessary delay.
-              o.setCancelResult(CancelResult.CANCELED);
-              cancelResult = o.cancel(cancelRequest);
-            }
+              o.abort(cancelRequest);
 
-            if (keepStats && (cancelResult == CancelResult.CANCELED))
+            // TODO: Assume its cancelled?
+            if (keepStats)
             {
               statTracker.updateAbandonedOperation();
             }
@@ -1391,8 +1389,10 @@
           {
             try
             {
-              CancelResult cancelResult = o.cancel(cancelRequest);
-              if (keepStats && (cancelResult == CancelResult.CANCELED))
+              o.abort(cancelRequest);
+
+              // TODO: Assume its cancelled?
+              if (keepStats)
               {
                 statTracker.updateAbandonedOperation();
               }
diff --git a/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java b/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
index f66c37c..68ef206 100644
--- a/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
+++ b/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
@@ -61,7 +61,7 @@
 import org.opends.server.api.ConnectionHandler;
 import org.opends.server.api.ConnectionSecurityProvider;
 import org.opends.server.api.ServerShutdownListener;
-import org.opends.server.api.plugin.PostConnectPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.PluginConfigManager;
@@ -1000,9 +1000,14 @@
                   try {
                     PluginConfigManager pluginManager = DirectoryServer
                         .getPluginConfigManager();
-                    PostConnectPluginResult pluginResult = pluginManager
+                    PluginResult.PostConnect pluginResult = pluginManager
                         .invokePostConnectPlugins(clientConnection);
-                    if (pluginResult.connectionTerminated()) {
+                    if (!pluginResult.continueProcessing()) {
+                      clientConnection.disconnect(
+                          pluginResult.getDisconnectReason(),
+                          pluginResult.sendDisconnectNotification(),
+                          pluginResult.getErrorMessage());
+
                       iterator.remove();
                       continue;
                     }
diff --git a/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java b/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java
index 81798bf..924be2b 100644
--- a/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java
+++ b/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java
@@ -387,7 +387,7 @@
     ReplicationDomain domain =
       findDomain(modifyOperation.getEntryDN(), modifyOperation);
     if (domain == null)
-      return new SynchronizationProviderResult(true);
+      return new SynchronizationProviderResult.ContinueProcessing();
 
     return domain.handleConflictResolution(modifyOperation);
   }
@@ -402,7 +402,7 @@
     ReplicationDomain domain =
       findDomain(addOperation.getEntryDN(), addOperation);
     if (domain == null)
-      return new SynchronizationProviderResult(true);
+      return new SynchronizationProviderResult.ContinueProcessing();
 
     return domain.handleConflictResolution(addOperation);
   }
@@ -417,7 +417,7 @@
     ReplicationDomain domain =
       findDomain(deleteOperation.getEntryDN(), deleteOperation);
     if (domain == null)
-      return new SynchronizationProviderResult(true);
+      return new SynchronizationProviderResult.ContinueProcessing();
 
     return domain.handleConflictResolution(deleteOperation);
   }
@@ -432,7 +432,7 @@
     ReplicationDomain domain =
       findDomain(modifyDNOperation.getEntryDN(), modifyDNOperation);
     if (domain == null)
-      return new SynchronizationProviderResult(true);
+      return new SynchronizationProviderResult.ContinueProcessing();
 
     return domain.handleConflictResolution(modifyDNOperation);
   }
@@ -448,7 +448,7 @@
     ReplicationDomain domain = findDomain(operationDN, modifyOperation);
 
     if ((domain == null) || (!domain.solveConflict()))
-      return new SynchronizationProviderResult(true);
+      return new SynchronizationProviderResult.ContinueProcessing();
 
     Historical historicalInformation = (Historical)
                             modifyOperation.getAttachment(
@@ -463,7 +463,7 @@
 
     historicalInformation.generateState(modifyOperation);
 
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
   /**
@@ -473,7 +473,7 @@
   public SynchronizationProviderResult doPreOperation(
          PreOperationDeleteOperation deleteOperation) throws DirectoryException
   {
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
   /**
@@ -484,7 +484,7 @@
          PreOperationModifyDNOperation modifyDNOperation)
          throws DirectoryException
   {
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
   /**
@@ -497,12 +497,12 @@
     ReplicationDomain domain =
       findDomain(addOperation.getEntryDN(), addOperation);
     if (domain == null)
-      return new SynchronizationProviderResult(true);
+      return new SynchronizationProviderResult.ContinueProcessing();
 
     if (!addOperation.isSynchronizationOperation())
       domain.doPreOperation(addOperation);
 
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
 
diff --git a/opends/src/server/org/opends/server/replication/plugin/ReplicationDomain.java b/opends/src/server/org/opends/server/replication/plugin/ReplicationDomain.java
index 1fb063b..7c43a7c 100644
--- a/opends/src/server/org/opends/server/replication/plugin/ReplicationDomain.java
+++ b/opends/src/server/org/opends/server/replication/plugin/ReplicationDomain.java
@@ -522,7 +522,9 @@
     if ((!deleteOperation.isSynchronizationOperation())
         && (!brokerIsConnected(deleteOperation)))
     {
-      return new SynchronizationProviderResult(false);
+      Message msg = ERR_REPLICATION_COULD_NOT_CONNECT.get(baseDN.toString());
+      return new SynchronizationProviderResult.StopProcessing(
+          ResultCode.UNWILLING_TO_PERFORM, msg);
     }
 
     DeleteContext ctx =
@@ -551,8 +553,8 @@
          * operation will try to find the correct entry and restart a new
          * operation.
          */
-        deleteOperation.setResultCode(ResultCode.NO_SUCH_OBJECT);
-        return new SynchronizationProviderResult(false);
+        return new SynchronizationProviderResult.StopProcessing(
+            ResultCode.NO_SUCH_OBJECT, null);
       }
     }
     else
@@ -564,7 +566,7 @@
       ctx = new DeleteContext(changeNumber, modifiedEntryUUID);
       deleteOperation.setAttachment(SYNCHROCONTEXT, ctx);
     }
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
   /**
@@ -580,7 +582,9 @@
     if ((!addOperation.isSynchronizationOperation())
         && (!brokerIsConnected(addOperation)))
     {
-      return new SynchronizationProviderResult(false);
+      Message msg = ERR_REPLICATION_COULD_NOT_CONNECT.get(baseDN.toString());
+      return new SynchronizationProviderResult.StopProcessing(
+          ResultCode.UNWILLING_TO_PERFORM, msg);
     }
 
     if (addOperation.isSynchronizationOperation())
@@ -593,8 +597,8 @@
       String uuid = ctx.getEntryUid();
       if (findEntryDN(uuid) != null)
       {
-        addOperation.setResultCode(ResultCode.CANCELED);
-        return new SynchronizationProviderResult(false);
+        return new SynchronizationProviderResult.StopProcessing(
+            ResultCode.CANCELED, null);
       }
 
       /* The parent entry may have been renamed here since the change was done
@@ -616,8 +620,8 @@
           // The parent does not exist with the specified unique id
           // stop the operation with NO_SUCH_OBJECT and let the
           // conflict resolution or the dependency resolution solve this.
-          addOperation.setResultCode(ResultCode.NO_SUCH_OBJECT);
-          return new SynchronizationProviderResult(false);
+          return new SynchronizationProviderResult.StopProcessing(
+              ResultCode.NO_SUCH_OBJECT, null);
         }
         else
         {
@@ -629,13 +633,13 @@
             // parentEntry has been renamed
             // replication name conflict resolution is expected to fix that
             // later in the flow
-            addOperation.setResultCode(ResultCode.NO_SUCH_OBJECT);
-            return new SynchronizationProviderResult(false);
+            return new SynchronizationProviderResult.StopProcessing(
+                ResultCode.NO_SUCH_OBJECT, null);
           }
         }
       }
     }
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
   /**
@@ -645,7 +649,7 @@
    * If not set the ResultCode and the response message,
    * interrupt the operation, and return false
    *
-   * @param   Operation  The Operation that needs to be checked.
+   * @param   op  The Operation that needs to be checked.
    *
    * @return  true when it OK to process the Operation, false otherwise.
    *          When false is returned the resultCode and the reponse message
@@ -662,21 +666,7 @@
     {
       // this isolation policy specifies that the updates are denied
       // when the broker is not connected.
-      if (broker.isConnected())
-      {
-        return true;
-      }
-      else
-      {
-        Message msg = ERR_REPLICATION_COULD_NOT_CONNECT.get(baseDN.toString());
-        DirectoryException result =
-          new DirectoryException(
-              ResultCode.UNWILLING_TO_PERFORM, msg);
-
-        op.setResponseData(result);
-
-        return false;
-      }
+      return broker.isConnected();
     }
     // we should never get there as the only possible policies are
     // ACCEPT_ALL_UPDATES and REJECT_ALL_UPDATES
@@ -697,7 +687,9 @@
     if ((!modifyDNOperation.isSynchronizationOperation())
         && (!brokerIsConnected(modifyDNOperation)))
     {
-      return new SynchronizationProviderResult(false);
+      Message msg = ERR_REPLICATION_COULD_NOT_CONNECT.get(baseDN.toString());
+      return new SynchronizationProviderResult.StopProcessing(
+          ResultCode.UNWILLING_TO_PERFORM, msg);
     }
 
     ModifyDnContext ctx =
@@ -724,8 +716,8 @@
          * operation will try to find the correct entry and restart a new
          * operation.
          */
-        modifyDNOperation.setResultCode(ResultCode.NO_SUCH_OBJECT);
-        return new SynchronizationProviderResult(false);
+        return new SynchronizationProviderResult.StopProcessing(
+            ResultCode.NO_SUCH_OBJECT, null);
       }
       if (modifyDNOperation.getNewSuperior() != null)
       {
@@ -737,8 +729,8 @@
         if ((newParentId != null) &&
             (!newParentId.equals(ctx.getNewParentId())))
         {
-          modifyDNOperation.setResultCode(ResultCode.NO_SUCH_OBJECT);
-          return new SynchronizationProviderResult(false);
+        return new SynchronizationProviderResult.StopProcessing(
+            ResultCode.NO_SUCH_OBJECT, null);
         }
       }
     }
@@ -758,7 +750,7 @@
       ctx = new ModifyDnContext(changeNumber, modifiedEntryUUID, newParentId);
       modifyDNOperation.setAttachment(SYNCHROCONTEXT, ctx);
     }
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
   /**
@@ -774,7 +766,9 @@
     if ((!modifyOperation.isSynchronizationOperation())
         && (!brokerIsConnected(modifyOperation)))
     {
-      return new SynchronizationProviderResult(false);
+      Message msg = ERR_REPLICATION_COULD_NOT_CONNECT.get(baseDN.toString());
+      return new SynchronizationProviderResult.StopProcessing(
+          ResultCode.UNWILLING_TO_PERFORM, msg);
     }
 
     ModifyContext ctx =
@@ -813,8 +807,8 @@
          * operation will try to find the correct entry and restart a new
          * operation.
          */
-        modifyOperation.setResultCode(ResultCode.NO_SUCH_OBJECT);
-        return new SynchronizationProviderResult(false);
+         return new SynchronizationProviderResult.StopProcessing(
+              ResultCode.NO_SUCH_OBJECT, null);
       }
 
       /*
@@ -835,11 +829,11 @@
          * This operation becomes a no-op due to conflict resolution
          * stop the processing and send an OK result
          */
-        modifyOperation.setResultCode(ResultCode.SUCCESS);
-        return new SynchronizationProviderResult(false);
+        return new SynchronizationProviderResult.StopProcessing(
+            ResultCode.SUCCESS, null);
       }
     }
-    return new SynchronizationProviderResult(true);
+    return new SynchronizationProviderResult.ContinueProcessing();
   }
 
   /**
diff --git a/opends/src/server/org/opends/server/tools/VerifyIndex.java b/opends/src/server/org/opends/server/tools/VerifyIndex.java
index d6f66cd..5150bd1 100644
--- a/opends/src/server/org/opends/server/tools/VerifyIndex.java
+++ b/opends/src/server/org/opends/server/tools/VerifyIndex.java
@@ -30,6 +30,7 @@
 
 import org.opends.server.api.Backend;
 import org.opends.server.api.ErrorLogPublisher;
+import org.opends.server.api.DebugLogPublisher;
 import org.opends.server.backends.jeb.BackendImpl;
 import org.opends.server.backends.jeb.VerifyConfig;
 import org.opends.server.config.ConfigException;
@@ -40,6 +41,8 @@
 import org.opends.server.loggers.ThreadFilterTextErrorLogPublisher;
 import org.opends.server.loggers.TextWriter;
 import org.opends.server.loggers.ErrorLogger;
+import org.opends.server.loggers.debug.TextDebugLogPublisher;
+import org.opends.server.loggers.debug.DebugLogger;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.DN;
 import org.opends.server.types.InitializationException;
@@ -73,6 +76,7 @@
 public class VerifyIndex
 {
   private static ErrorLogPublisher errorLogPublisher = null;
+  private static DebugLogPublisher debugLogPublisher = null;
   /**
    * Processes the command-line arguments and invokes the verify process.
    *
@@ -86,6 +90,10 @@
     {
       ErrorLogger.removeErrorLogPublisher(errorLogPublisher);
     }
+    if(debugLogPublisher != null)
+    {
+      DebugLogger.removeDebugLogPublisher(debugLogPublisher);
+    }
 
     if(retCode != 0)
     {
@@ -388,6 +396,11 @@
                                                   new TextWriter.STREAM(out));
         ErrorLogger.addErrorLogPublisher(errorLogPublisher);
 
+        debugLogPublisher =
+          TextDebugLogPublisher.getStartupTextDebugPublisher(
+              new TextWriter.STDOUT());
+        DebugLogger.addDebugLogPublisher(debugLogPublisher);
+
       }
       catch(Exception e)
       {
diff --git a/opends/src/server/org/opends/server/types/AbstractOperation.java b/opends/src/server/org/opends/server/types/AbstractOperation.java
index 3a79fa0..e9a365b 100644
--- a/opends/src/server/org/opends/server/types/AbstractOperation.java
+++ b/opends/src/server/org/opends/server/types/AbstractOperation.java
@@ -39,6 +39,10 @@
 import org.opends.server.types.operation.PostResponseOperation;
 import org.opends.server.types.operation.PreParseOperation;
 import org.opends.server.core.DirectoryServer;
+import static org.opends.server.loggers.debug.
+    DebugLogger.debugEnabled;
+import static org.opends.server.loggers.debug.DebugLogger.getTracer;
+import org.opends.server.loggers.debug.DebugTracer;
 
 
 /**
@@ -61,6 +65,11 @@
                   Runnable
 {
   /**
+   * The tracer object for the debug logger.
+   */
+  private static final DebugTracer TRACER = getTracer();
+
+  /**
    * The set of response controls that will always be returned for
    * an abandon operation.
    */
@@ -93,6 +102,16 @@
   protected final boolean useNanoTime;
 
 
+  /**
+   * The cancel request for this operation.
+   */
+  protected CancelRequest cancelRequest;
+
+
+  /**
+   * The cancel result for this operation.
+   */
+  protected CancelResult cancelResult;
 
   // Indicates whether this is an internal operation triggered within
   // the server itself rather than requested by an external client.
@@ -102,9 +121,6 @@
   // synchronization processing.
   private boolean isSynchronizationOperation;
 
-  // The cancel result for this operation.
-  private CancelResult cancelResult;
-
   // The matched DN for this operation.
   private DN matchedDN;
 
@@ -223,10 +239,13 @@
    *                           may be {@code null} if no notification
    *                           is to be sent.
    */
-  public abstract void disconnectClient(
-          DisconnectReason disconnectReason,
-          boolean sendNotification,
-          Message message);
+  public void disconnectClient(DisconnectReason disconnectReason,
+                               boolean sendNotification,
+                               Message message)
+  {
+    clientConnection.disconnect(disconnectReason, sendNotification,
+            message);
+  }
 
 
 
@@ -911,94 +930,91 @@
    * @return  A code providing information on the result of the
    *          cancellation.
    */
-  public abstract CancelResult cancel(CancelRequest cancelRequest);
-
-
-
-  /**
-   * Sets the cancel request for this operation, if applicable.  This
-   * should only be used for testing purposes (e.g., for ensuring a
-   * cancel request is submitted before processing begins on an
-   * operation, or to allow for cancelling an internal operation).  It
-   * must not be used for any other purpose.
-   *
-   * @param  cancelRequest  The cancel request to set for this
-   *                        operation.
-   *
-   * @return  {@code true} if the cancel request was set, or
-   *          {@code false} if it was not for some reason (e.g., the
-   *          specified operation cannot be cancelled).
-   */
-  public abstract boolean setCancelRequest(CancelRequest
-      cancelRequest);
-
-
-
-  /**
-   * Retrieves the cancel request that has been issued for this
-   * operation, if there is one.  This method should not be called by
-   * post-operation or post-response plugins.
-   *
-   * @return  The cancel request that has been issued for this
-   *          operation, or {@code null} if there has not been any
-   *          request to cancel.
-   */
-  public abstract CancelRequest getCancelRequest();
-
-
-
-  /**
-   * Retrieves the cancel result for this operation.
-   *
-   * @return  The cancel result for this operation.  It will be
-   *          {@code null} if the operation has not seen and reacted
-   *          to a cancel request.
-   */
-  public final CancelResult getCancelResult()
+  public CancelResult cancel(CancelRequest cancelRequest)
   {
+    abort(cancelRequest);
+
+    long stopWaitingTime = System.currentTimeMillis() + 5000;
+    while ((cancelResult == null) &&
+        (System.currentTimeMillis() < stopWaitingTime))
+    {
+      try
+      {
+        Thread.sleep(50);
+      }
+      catch (Exception e)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, e);
+        }
+      }
+    }
+
+    if (cancelResult == null)
+    {
+      // This can happen in some rare cases (e.g., if a client
+      // disconnects and there is still a lot of data to send to
+      // that client), and in this case we'll prevent the cancel
+      // thread from blocking for a long period of time.
+      cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL, null);
+    }
+
     return cancelResult;
   }
 
 
 
   /**
-   * Specifies the cancel result for this operation.
+   * Attempts to cancel this operation before processing has
+   * completed without waiting for a cancel result.
    *
-   * @param  cancelResult  The cancel result for this operation.
+   * @param  cancelRequest  Information about the way in which the
+   *                        operation should be canceled.
    */
-  public final void setCancelResult(CancelResult cancelResult)
+  public synchronized void abort(CancelRequest cancelRequest)
   {
-    this.cancelResult = cancelResult;
+    if(cancelResult == null && this.cancelRequest == null)
+    {
+      this.cancelRequest = cancelRequest;
+    }
   }
 
 
 
   /**
-   * Indicates that this operation has been cancelled.  If
-   * appropriate, it will send a response to the client to indicate
-   * that.  This method must not be called by abandon, bind, or unbind
-   * operations under any circumstances, nor by extended operations if
-   * the request OID is that of the cancel or the StartTLS operation.
-   *
-   * @param  cancelRequest  The request to cancel this operation.
+   * {@inheritDoc}
    */
-  public final void indicateCancelled(CancelRequest cancelRequest)
-  {
-    setCancelResult(CancelResult.CANCELED);
-
-    if (cancelRequest.notifyOriginalRequestor() ||
-        DirectoryServer.notifyAbandonedOperations())
+  public synchronized final void
+    checkIfCanceled(boolean signalTooLate)
+      throws CanceledOperationException {
+    if(cancelRequest != null)
     {
-      setResultCode(ResultCode.CANCELED);
-
-      Message cancelReason = cancelRequest.getCancelReason();
-      if (cancelReason != null)
-      {
-        appendErrorMessage(cancelReason);
-      }
-
-      clientConnection.sendResponse(this);
+      throw new CanceledOperationException(cancelRequest);
     }
+
+    if(signalTooLate && cancelResult != null)
+    {
+      cancelResult = new CancelResult(ResultCode.TOO_LATE, null);
+    }
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public final CancelRequest getCancelRequest()
+  {
+    return cancelRequest;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public final CancelResult getCancelResult()
+  {
+    return cancelResult;
   }
 
 
diff --git a/opends/src/server/org/opends/server/types/CancelRequest.java b/opends/src/server/org/opends/server/types/CancelRequest.java
index ab24230..9d45e51 100644
--- a/opends/src/server/org/opends/server/types/CancelRequest.java
+++ b/opends/src/server/org/opends/server/types/CancelRequest.java
@@ -27,9 +27,6 @@
 package org.opends.server.types;
 import org.opends.messages.Message;
 
-
-import org.opends.messages.MessageBuilder;
-
 /**
  * This class defines a data structure that can be used to hold
  * information about a request to cancel or abandon an operation in
@@ -50,10 +47,6 @@
   // included in the response to the original requestor).
   private final Message cancelReason;
 
-  // A buffer to hold a human-readable response that the server
-  // provided for the result of the cancellation.
-  private MessageBuilder responseMessage;
-
 
 
   /**
@@ -71,32 +64,6 @@
   {
     this.notifyOriginalRequestor = notifyOriginalRequestor;
     this.cancelReason            = cancelReason;
-    this.responseMessage         = new MessageBuilder();
-  }
-
-
-
-  /**
-   * Creates a new cancel request with the provided information.
-   *
-   * @param  notifyOriginalRequestor  Indicates whether the original
-   *                                  requestor should receive a
-   *                                  response if the operation is
-   *                                  canceled.
-   * @param  cancelReason             A message that explains the
-   *                                  purpose for this cancellation.
-   * @param  responseMessage          A buffer to hold a
-   *                                  human-readable response that the
-   *                                  server provided for the result
-   *                                  of the cancellation.
-   */
-  public CancelRequest(boolean notifyOriginalRequestor,
-                       Message cancelReason,
-                       MessageBuilder responseMessage)
-  {
-    this.notifyOriginalRequestor = notifyOriginalRequestor;
-    this.cancelReason            = cancelReason;
-    this.responseMessage         = responseMessage;
   }
 
 
@@ -127,35 +94,5 @@
   {
     return cancelReason;
   }
-
-
-
-  /**
-   * Retrieves the buffer that is used to hold a human-readable
-   * response that the server provided for the result of the
-   * cancellation.  The caller may alter the contents of this buffer.
-   *
-   * @return  The buffer that is used to hold a human-readable
-   *          response that the server provided for the result of this
-   *          cancellation.
-   */
-  public MessageBuilder getResponseMessage()
-  {
-    return responseMessage;
-  }
-
-
-
-  /**
-   * Appends the provided message to the buffer used to hold
-   * information about the result of the cancellation.
-   *
-   * @param  message  The message to append to the response message
-   *                  buffer.
-   */
-  public void addResponseMessage(Message message)
-  {
-    responseMessage.append(message);
-  }
 }
 
diff --git a/opends/src/server/org/opends/server/types/CancelResult.java b/opends/src/server/org/opends/server/types/CancelResult.java
index 0879558..df692b2 100644
--- a/opends/src/server/org/opends/server/types/CancelResult.java
+++ b/opends/src/server/org/opends/server/types/CancelResult.java
@@ -26,6 +26,7 @@
  */
 package org.opends.server.types;
 
+import org.opends.messages.Message;
 
 
 /**
@@ -38,59 +39,29 @@
      mayInstantiate=false,
      mayExtend=false,
      mayInvoke=true)
-public enum CancelResult
+public class CancelResult
 {
-  /**
-   * The cancel result that indicates that the target operation was
-   * canceled successfully and in a manner that should have no
-   * permanent effects on the server or the data it contains.
-   */
-  CANCELED(ResultCode.CANCELED),
-
-
-
-  /**
-   * The cancel result that indicates that the target operation could
-   * not be found, which may mean that it either does not exist or has
-   * already completed.
-   */
-  NO_SUCH_OPERATION(ResultCode.NO_SUCH_OPERATION),
-
-
-
-  /**
-   * The cancel result that indicates that processing on the target
-   * operation had already progressed to a point in which it was too
-   * late to be able to cancel.
-   */
-  TOO_LATE(ResultCode.TOO_LATE),
-
-
-
-  /**
-   * The cancel result that indicates that the operation exists but
-   * cannot be canceled for some reason (e.g., it is an abandon, bind,
-   * cancel, or unbind operation, or if it is one that would impact
-   * the security of the underlying connection).
-   */
-  CANNOT_CANCEL(ResultCode.CANNOT_CANCEL);
-
-
-
   // The result code associated with this cancel result.
   private final ResultCode resultCode;
 
-
+  // A human-readable response that the server
+  // provided for the result of the cancellation.
+  private final Message responseMessage;
 
   /**
    * Creates a new cancel result with the provided result code.
    *
    * @param  resultCode  The result code associated with this cancel
    *                     result.
+   *
+   * @param  responseMessage A human-readable response that the
+   *                         server provided for the result
+   *                         of the cancellation.
    */
-  private CancelResult(ResultCode resultCode)
+  public CancelResult(ResultCode resultCode, Message responseMessage)
   {
     this.resultCode = resultCode;
+    this.responseMessage = responseMessage;
   }
 
 
@@ -105,7 +76,19 @@
     return resultCode;
   }
 
-
+  /**
+   * Retrieves the human-readable response that the server provided
+   * for the result of the cancellation.  The caller may alter the
+   * contents of this buffer.
+   *
+   * @return  The buffer that is used to hold a human-readable
+   *          response that the server provided for the result of this
+   *          cancellation.
+   */
+  public Message getResponseMessage()
+  {
+    return responseMessage;
+  }
 
   /**
    * Retrieves a string representation of this cancel result.
diff --git a/opends/src/server/org/opends/server/types/CancelledOperationException.java b/opends/src/server/org/opends/server/types/CanceledOperationException.java
similarity index 79%
rename from opends/src/server/org/opends/server/types/CancelledOperationException.java
rename to opends/src/server/org/opends/server/types/CanceledOperationException.java
index 47e9eae..39a8bdd 100644
--- a/opends/src/server/org/opends/server/types/CancelledOperationException.java
+++ b/opends/src/server/org/opends/server/types/CanceledOperationException.java
@@ -39,8 +39,8 @@
      mayInstantiate=true,
      mayExtend=false,
      mayInvoke=true)
-public final class CancelledOperationException
-       extends IdentifiedException
+public final class CanceledOperationException
+    extends IdentifiedException
 {
   /**
    * The serial version identifier required to satisfy the compiler
@@ -55,7 +55,7 @@
 
   // The cancel result that provides information about the status of
   // the cancellation.
-  private final CancelResult cancelResult;
+  private final CancelRequest cancelRequest;
 
 
 
@@ -63,14 +63,14 @@
    * Creates a new cancelled operation exception with the provided
    * result and no additional message.
    *
-   * @param  cancelResult  The result of the cancel processing.
+   * @param  cancelRequest  The result of the cancel processing.
    */
-  public CancelledOperationException(CancelResult cancelResult)
+  public CanceledOperationException(CancelRequest cancelRequest)
   {
     super();
 
 
-    this.cancelResult = cancelResult;
+    this.cancelRequest = cancelRequest;
   }
 
 
@@ -79,32 +79,32 @@
    * Creates a new cancelled operation exception with the provided
    * information.
    *
-   * @param  cancelResult  The result of the cancel processing.
+   * @param  cancelRequest The request of the cancel processing.
    * @param  message       The message providing additional
    *                       information about the cancel processing, or
    *                       <CODE>null</CODE> if there is no message.
    */
-  public CancelledOperationException(CancelResult cancelResult,
+  public CanceledOperationException(CancelRequest cancelRequest,
                                      Message message)
   {
     super(message);
 
 
-    this.cancelResult = cancelResult;
+    this.cancelRequest = cancelRequest;
   }
 
 
 
   /**
-   * Retrieves the cancel result for this cancelled operation
+   * Retrieves the cancel request for this cancelled operation
    * exception.
    *
-   * @return  The cancel result for this cancelled operation
+   * @return  The cancel request for this cancelled operation
    *          exception.
    */
-  public CancelResult getCancelResult()
+  public CancelRequest getCancelRequest()
   {
-    return cancelResult;
+    return cancelRequest;
   }
 }
 
diff --git a/opends/src/server/org/opends/server/types/Entry.java b/opends/src/server/org/opends/server/types/Entry.java
index 7852c2d..b591bf5 100644
--- a/opends/src/server/org/opends/server/types/Entry.java
+++ b/opends/src/server/org/opends/server/types/Entry.java
@@ -47,7 +47,7 @@
 import org.opends.server.api.AttributeValueDecoder;
 import org.opends.server.api.CompressedSchema;
 import org.opends.server.api.ProtocolElement;
-import org.opends.server.api.plugin.LDIFPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.PluginConfigManager;
 import org.opends.server.protocols.asn1.ASN1Element;
@@ -5646,10 +5646,10 @@
     {
       PluginConfigManager pluginConfigManager =
            DirectoryServer.getPluginConfigManager();
-      LDIFPluginResult pluginResult =
+      PluginResult.ImportLDIF pluginResult =
            pluginConfigManager.invokeLDIFExportPlugins(exportConfig,
                                                     this);
-      if (! pluginResult.continueEntryProcessing())
+      if (! pluginResult.continueProcessing())
       {
         return false;
       }
diff --git a/opends/src/server/org/opends/server/types/Operation.java b/opends/src/server/org/opends/server/types/Operation.java
index ba9a588..2e46443 100644
--- a/opends/src/server/org/opends/server/types/Operation.java
+++ b/opends/src/server/org/opends/server/types/Operation.java
@@ -543,21 +543,14 @@
   public abstract CancelResult cancel(CancelRequest cancelRequest);
 
   /**
-   * Sets the cancel request for this operation, if applicable.  This
-   * should only be used for testing purposes (e.g., for ensuring a
-   * cancel request is submitted before processing begins on an
-   * operation, or to allow for cancelling an internal operation).  It
-   * must not be used for any other purpose.
+   * Attempts to abort this operation before processing has
+   * completed.
    *
-   * @param  cancelRequest  The cancel request to set for this
-   *                        operation.
-   *
-   * @return  {@code true} if the cancel request was set, or
-   *          {@code false} if it was not for some reason (e.g., the
-   *          specified operation cannot be cancelled).
+   * @param  cancelRequest  Information about the way in which the
+   *                        operation should be canceled.
    */
-  public abstract boolean setCancelRequest(CancelRequest
-      cancelRequest);
+  public abstract void abort(CancelRequest cancelRequest);
+
 
   /**
    * Retrieves the cancel request that has been issued for this
@@ -580,24 +573,6 @@
   public abstract CancelResult getCancelResult();
 
   /**
-   * Specifies the cancel result for this operation.
-   *
-   * @param  cancelResult  The cancel result for this operation.
-   */
-  public abstract void setCancelResult(CancelResult cancelResult);
-
-  /**
-   * Indicates that this operation has been cancelled.  If
-   * appropriate, it will send a response to the client to indicate
-   * that.  This method must not be called by abandon, bind, or unbind
-   * operations under any circumstances, nor by extended operations if
-   * the request OID is that of the cancel or the StartTLS operation.
-   *
-   * @param  cancelRequest  The request to cancel this operation.
-   */
-  public abstract void indicateCancelled(CancelRequest cancelRequest);
-
-  /**
    * Retrieves a string representation of this operation.
    *
    * @return  A string representation of this operation.
@@ -624,18 +599,6 @@
   public abstract boolean dontSynchronize();
 
   /**
-   * Set the time at which the processing stopped for this operation.
-   * This will actually hold a time immediately before the response
-   * was sent to the client.
-   */
-  public abstract void setProcessingStopTime();
-
-  /**
-   * Set the time at which the processing started for this operation.
-   */
-  public abstract void setProcessingStartTime();
-
-  /**
    * Set the attachments to the operation.
    *
    * @param attachments - Attachments to register within the
@@ -644,5 +607,20 @@
   public abstract void setAttachments(Map<String,
       Object> attachments);
 
+  /**
+   * Checks to see if this operation requested to cancel in which case
+   * CanceledOperationException will be thrown.
+   *
+   * @param signalTooLate <code>true</code> to signal that any further
+   *                      cancel requests will be too late after
+   *                      return from this call or <code>false</code>
+   *                      otherwise.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
+   */
+  public void checkIfCanceled(boolean signalTooLate)
+      throws CanceledOperationException;
+
 }
 
diff --git a/opends/src/server/org/opends/server/types/SynchronizationProviderResult.java b/opends/src/server/org/opends/server/types/SynchronizationProviderResult.java
index 1c415ae..acac01a 100644
--- a/opends/src/server/org/opends/server/types/SynchronizationProviderResult.java
+++ b/opends/src/server/org/opends/server/types/SynchronizationProviderResult.java
@@ -26,39 +26,22 @@
  */
 package org.opends.server.types;
 
+import org.opends.messages.Message;
+
+import java.util.List;
+
 
 /**
  * This class defines a data structure that holds information about
  * the result of processing by a synchronization provider.
  */
 @org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.VOLATILE,
-     mayInstantiate=false,
-     mayExtend=false,
-     mayInvoke=true)
-public final class SynchronizationProviderResult
+    stability=org.opends.server.types.StabilityLevel.VOLATILE,
+    mayInstantiate=false,
+    mayExtend=false,
+    mayInvoke=true)
+public interface SynchronizationProviderResult
 {
-  // Indicates whether processing should continue on the operation.
-  private boolean continueOperationProcessing;
-
-
-
-  /**
-   * Creates a new synchronization provider result with the provided
-   * information.
-   *
-   * @param  continueOperationProcessing  Indicates whether processing
-   *                                      should continue on the
-   *                                      associated operation.
-   */
-  public SynchronizationProviderResult(
-              boolean continueOperationProcessing)
-  {
-    this.continueOperationProcessing = continueOperationProcessing;
-  }
-
-
-
   /**
    * Indicates whether processing on the associated operation should
    * continue.
@@ -67,58 +50,182 @@
    *          operation should continue, or <CODE>false</CODE> if it
    *          should stop.
    */
-  public boolean continueOperationProcessing()
-  {
-    return continueOperationProcessing;
-  }
-
-
+  public boolean continueProcessing();
 
   /**
-   * Specifies whether processing on the associated operation should
-   * continue.
+   * Retrieves the error message if <code>continueProcessing</code>
+   * returned <code>false</code>.
    *
-   * @param  continueOperationProcessing  Indicates whether processing
-   *                                      should continue on the
-   *                                      associated operation.
+   * @return An error message explaining why processing should
+   * stop or <code>null</code> if none is provided.
    */
-  public void setContinueOperationProcessing(
-                   boolean continueOperationProcessing)
-  {
-    this.continueOperationProcessing = continueOperationProcessing;
-  }
-
-
+  public Message getErrorMessage();
 
   /**
-   * Retrieves a string representation of this post-response plugin
-   * result.
+   * Retrieves the result code for the operation
+   * if <code>continueProcessing</code> returned <code>false</code>.
    *
-   * @return  A string representation of this post-response plugin
-   *          result.
+   * @return the result code for the operation or <code>null</code>
+   * if none is provided.
    */
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    toString(buffer);
-    return buffer.toString();
-  }
-
-
+  public ResultCode getResultCode();
 
   /**
-   * Appends a string representation of this post-response plugin
-   * result to the provided buffer.
+   * Retrieves the matched DN for the operation
+   * if <code>continueProcessing</code> returned <code>false</code>.
    *
-   * @param  buffer  The buffer to which the information should be
-   *                 appended.
+   * @return the matched DN for the operation or <code>null</code>
+   * if none is provided.
    */
-  public void toString(StringBuilder buffer)
+  public DN getMatchedDN();
+
+  /**
+   * Retrieves the referral URLs for the operation
+   * if <code>continueProcessing</code> returned <code>false</code>.
+   *
+   * @return the refferal URLs for the operation or
+   * <code>null</code> if none is provided.
+   */
+  public List<String> getReferralURLs();
+
+  /**
+   * Defines a continue processing synchronization provider result.
+   */
+  public class ContinueProcessing
+      implements SynchronizationProviderResult
   {
-    buffer.append("SynchronizationProviderResult(" +
-                  "continueOperationProcessing=");
-    buffer.append(continueOperationProcessing);
-    buffer.append(")");
+    /**
+     * {@inheritDoc}
+     */
+    public ResultCode getResultCode()
+    {
+      return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public DN getMatchedDN()
+    {
+      return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public List<String> getReferralURLs()
+    {
+      return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean continueProcessing()
+    {
+      return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Message getErrorMessage()
+    {
+      return null;
+    }
+  }
+
+  /**
+   * Defines a stop processing synchronization provider result.
+   */
+  public class StopProcessing
+      implements SynchronizationProviderResult
+  {
+    // The matched DN for this result.
+    private final DN matchedDN;
+
+    // The set of referral URLs for this result.
+    private final List<String> referralURLs;
+
+    // The result code for this result.
+    private final ResultCode resultCode;
+
+    private final Message errorMessage;
+
+    /**
+     * Contrust a new stop processing synchronization provider
+     *  result.
+     *
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     * @param matchedDN The matched DN for this result.
+     * @param referralURLs The set of referral URLs for this result.
+     */
+    public StopProcessing(ResultCode resultCode, Message errorMessage,
+                          DN matchedDN, List<String> referralURLs)
+    {
+      this.errorMessage = errorMessage;
+      this.matchedDN = matchedDN;
+      this.resultCode = resultCode;
+      this.referralURLs = referralURLs;
+    }
+
+    /**
+     * Contrust a new stop processing synchronization provider
+     *  result.
+     *
+     * @param resultCode The result code for this result.
+     * @param errorMessage An message explaining why processing
+     * should stop.
+     */
+    public StopProcessing(ResultCode resultCode, Message errorMessage)
+    {
+      this.errorMessage = errorMessage;
+      this.resultCode = resultCode;
+      this.matchedDN = null;
+      this.referralURLs = null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ResultCode getResultCode()
+    {
+      return resultCode;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public DN getMatchedDN()
+    {
+      return matchedDN;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public List<String> getReferralURLs()
+    {
+      return referralURLs;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean continueProcessing()
+    {
+      return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Message getErrorMessage()
+    {
+      return errorMessage;
+    }
   }
 }
 
diff --git a/opends/src/server/org/opends/server/types/operation/PluginOperation.java b/opends/src/server/org/opends/server/types/operation/PluginOperation.java
index c53d280..3098a78 100644
--- a/opends/src/server/org/opends/server/types/operation/PluginOperation.java
+++ b/opends/src/server/org/opends/server/types/operation/PluginOperation.java
@@ -33,11 +33,7 @@
 import java.util.Map;
 
 import org.opends.server.api.ClientConnection;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.Control;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.OperationType;
-
+import org.opends.server.types.*;
 
 
 /**
@@ -230,18 +226,6 @@
 
 
   /**
-   * Retrieves the cancel request that has been issued for this
-   * operation, if there is one.
-   *
-   * @return  The cancel request that has been issued for this
-   *          operation, or <CODE>null</CODE> if there has not been
-   *          any request to cancel.
-   */
-  public CancelRequest getCancelRequest();
-
-
-
-  /**
    * Retrieves a string representation of this operation.
    *
    * @return  A string representation of this operation.
@@ -258,5 +242,22 @@
    *                 this operation should be appended.
    */
   public void toString(StringBuilder buffer);
+
+
+
+  /**
+   * Checks to see if this operation requested to cancel in which case
+   * CanceledOperationException will be thrown.
+   *
+   * @param signalTooLate <code>true</code> to signal that any further
+   *                      cancel requests will be too late after
+   *                      return from this call or <code>false</code>
+   *                      otherwise.
+   *
+   * @throws CanceledOperationException if this operation should
+   * be cancelled.
+   */
+  public void checkIfCanceled(boolean signalTooLate)
+      throws CanceledOperationException;
 }
 
diff --git a/opends/src/server/org/opends/server/types/operation/PreOperationOperation.java b/opends/src/server/org/opends/server/types/operation/PreOperationOperation.java
index bc346ea..fcc65e7 100644
--- a/opends/src/server/org/opends/server/types/operation/PreOperationOperation.java
+++ b/opends/src/server/org/opends/server/types/operation/PreOperationOperation.java
@@ -28,13 +28,8 @@
 import org.opends.messages.Message;
 
 
-
-import java.util.List;
-
 import org.opends.server.types.Control;
-import org.opends.server.types.DirectoryException;
 import org.opends.server.types.DN;
-import org.opends.server.types.ResultCode;
 
 import org.opends.messages.MessageBuilder;
 
@@ -76,26 +71,6 @@
 
 
   /**
-   * Retrieves the result code for this operation.
-   *
-   * @return  The result code associated for this operation, or
-   *          <CODE>UNDEFINED</CODE> if the operation has not yet
-   *          completed.
-   */
-  public ResultCode getResultCode();
-
-
-
-  /**
-   * Specifies the result code for this operation.
-   *
-   * @param  resultCode  The result code for this operation.
-   */
-  public void setResultCode(ResultCode resultCode);
-
-
-
-  /**
    * Retrieves the error message for this operation.  Its contents may
    * be altered by the caller.
    *
@@ -162,61 +137,6 @@
 
 
   /**
-   * Retrieves the matched DN for this operation.
-   *
-   * @return  The matched DN for this operation, or <CODE>null</CODE>
-   *          if the operation has not yet completed or does not have
-   *          a matched DN.
-   */
-  public DN getMatchedDN();
-
-
-
-  /**
-   * Specifies the matched DN for this operation.
-   *
-   * @param  matchedDN  The matched DN for this operation.
-   */
-  public void setMatchedDN(DN matchedDN);
-
-
-
-  /**
-   * Retrieves the set of referral URLs for this operation.  Its
-   * contents must not be altered by the caller.
-   *
-   * @return  The set of referral URLs for this operation, or
-   *          <CODE>null</CODE> if the operation is not yet complete
-   *          or does not have a set of referral URLs.
-   */
-  public List<String> getReferralURLs();
-
-
-
-  /**
-   * Specifies the set of referral URLs for this operation.
-   *
-   * @param  referralURLs  The set of referral URLs for this
-   *                       operation.
-   */
-  public void setReferralURLs(List<String> referralURLs);
-
-
-
-  /**
-   * Sets the response elements for this operation based on the
-   * information contained in the provided
-   * <CODE>DirectoryException</CODE> object.
-   *
-   * @param  directoryException  The exception containing the
-   *                             information to use for the response
-   *                             elements.
-   */
-  public void setResponseData(DirectoryException directoryException);
-
-
-
-  /**
    * Retrieves the authorization DN for this operation.  In many
    * cases, it will be the same as the DN of the authenticated user
    * for the underlying connection, or the null DN if no
diff --git a/opends/src/server/org/opends/server/types/operation/PreParseOperation.java b/opends/src/server/org/opends/server/types/operation/PreParseOperation.java
index c0e2bd5..63a1215 100644
--- a/opends/src/server/org/opends/server/types/operation/PreParseOperation.java
+++ b/opends/src/server/org/opends/server/types/operation/PreParseOperation.java
@@ -29,12 +29,7 @@
 
 
 
-import java.util.List;
-
-import org.opends.server.types.Control;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DN;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 
 import org.opends.messages.MessageBuilder;
 
@@ -98,26 +93,6 @@
 
 
   /**
-   * Retrieves the result code for this operation.
-   *
-   * @return  The result code associated for this operation, or
-   *          <CODE>UNDEFINED</CODE> if the operation has not yet
-   *          completed.
-   */
-  public ResultCode getResultCode();
-
-
-
-  /**
-   * Specifies the result code for this operation.
-   *
-   * @param  resultCode  The result code for this operation.
-   */
-  public void setResultCode(ResultCode resultCode);
-
-
-
-  /**
    * Retrieves the error message for this operation.  Its contents may
    * be altered by the caller.
    *
@@ -180,60 +155,5 @@
    *                  additional log information for this operation.
    */
   public void appendAdditionalLogMessage(Message message);
-
-
-
-  /**
-   * Retrieves the matched DN for this operation.
-   *
-   * @return  The matched DN for this operation, or <CODE>null</CODE>
-   *          if the operation has not yet completed or does not have
-   *          a matched DN.
-   */
-  public DN getMatchedDN();
-
-
-
-  /**
-   * Specifies the matched DN for this operation.
-   *
-   * @param  matchedDN  The matched DN for this operation.
-   */
-  public void setMatchedDN(DN matchedDN);
-
-
-
-  /**
-   * Retrieves the set of referral URLs for this operation.  Its
-   * contents must not be altered by the caller.
-   *
-   * @return  The set of referral URLs for this operation, or
-   *          <CODE>null</CODE> if the operation is not yet complete
-   *          or does not have a set of referral URLs.
-   */
-  public List<String> getReferralURLs();
-
-
-
-  /**
-   * Specifies the set of referral URLs for this operation.
-   *
-   * @param  referralURLs  The set of referral URLs for this
-   *                       operation.
-   */
-  public void setReferralURLs(List<String> referralURLs);
-
-
-
-  /**
-   * Sets the response elements for this operation based on the
-   * information contained in the provided
-   * <CODE>DirectoryException</CODE> object.
-   *
-   * @param  directoryException  The exception containing the
-   *                             information to use for the response
-   *                             elements.
-   */
-  public void setResponseData(DirectoryException directoryException);
 }
 
diff --git a/opends/src/server/org/opends/server/util/LDIFReader.java b/opends/src/server/org/opends/server/util/LDIFReader.java
index 0d2986a..73581b8 100644
--- a/opends/src/server/org/opends/server/util/LDIFReader.java
+++ b/opends/src/server/org/opends/server/util/LDIFReader.java
@@ -48,7 +48,6 @@
 import java.util.LinkedList;
 import java.util.List;
 
-import org.opends.server.api.plugin.LDIFPluginResult;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.PluginConfigManager;
 import org.opends.server.protocols.asn1.ASN1OctetString;
@@ -69,6 +68,7 @@
 import org.opends.server.types.ObjectClass;
 import org.opends.server.types.RawModification;
 import org.opends.server.types.RDN;
+import org.opends.server.api.plugin.PluginResult;
 
 
 /**
@@ -299,12 +299,12 @@
       // If we should invoke import plugins, then do so.
       if (importConfig.invokeImportPlugins())
       {
-        LDIFPluginResult pluginResult =
+        PluginResult.ImportLDIF pluginResult =
              pluginConfigManager.invokeLDIFImportPlugins(importConfig, entry);
-        if (! pluginResult.continueEntryProcessing())
+        if (! pluginResult.continueProcessing())
         {
           Message m;
-          Message rejectMessage = pluginResult.getRejectMessage();
+          Message rejectMessage = pluginResult.getErrorMessage();
           if (rejectMessage == null)
           {
             m = ERR_LDIF_REJECTED_BY_PLUGIN_NOMESSAGE.get(
diff --git a/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java b/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java
index b5b4bf8..0e0b74e 100644
--- a/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java
+++ b/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java
@@ -41,6 +41,7 @@
 import org.opends.server.types.Entry;
 import org.opends.server.types.Operation;
 import org.opends.server.types.SearchResultReference;
+import org.opends.server.types.CanceledOperationException;
 
 
 /**
@@ -170,8 +171,12 @@
    * Executes the workflow element for an operation.
    *
    * @param operation the operation to execute
+   *
+   * @throws CanceledOperationException if this operation should be
+   * cancelled
    */
-  public abstract void execute(Operation operation);
+  public abstract void execute(Operation operation)
+      throws CanceledOperationException;
 
 
   /**
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
index 46ec638..b2a7f33 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
@@ -46,8 +46,7 @@
 import org.opends.server.api.PasswordStorageScheme;
 import org.opends.server.api.PasswordValidator;
 import org.opends.server.api.SynchronizationProvider;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.controls.LDAPAssertionRequestControl;
 import org.opends.server.controls.LDAPPostReadRequestControl;
 import org.opends.server.controls.LDAPPostReadResponseControl;
@@ -70,8 +69,7 @@
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.AttributeValue;
 import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelledOperationException;
-import org.opends.server.types.CancelResult;
+import org.opends.server.types.CanceledOperationException;
 import org.opends.server.types.Control;
 import org.opends.server.types.DebugLogLevel;
 import org.opends.server.types.DirectoryException;
@@ -123,9 +121,6 @@
   // Indicates whether the request includes the LDAP no-op control.
   private boolean noOp;
 
-  // Indicates whether to skip post-operation plugin processing.
-  private boolean skipPostOperation;
-
   // The DN of the entry to be added.
   private DN entryDN;
 
@@ -181,22 +176,22 @@
    *
    * @param  backend  The backend in which the add operation should be
    *                  processed.
+   *
+   * @throws CanceledOperationException if this operation should be
+   * cancelled
    */
-  void processLocalAdd(Backend backend)
-  {
+  void processLocalAdd(Backend backend) throws CanceledOperationException {
+    boolean executePostOpPlugins = false;
+
     this.backend = backend;
     ClientConnection clientConnection = getClientConnection();
 
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
          DirectoryServer.getPluginConfigManager();
-    skipPostOperation = false;
 
     // Check for a request to cancel this operation.
-    if (cancelIfRequested())
-    {
-      return;
-    }
+    checkIfCanceled(false);
 
     // Create a labeled block of code that we can break out of if a problem is
     // detected.
@@ -222,10 +217,7 @@
       }
 
       // Check for a request to cancel this operation.
-      if (cancelIfRequested())
-      {
-        return;
-      }
+      checkIfCanceled(false);
 
 
       // Grab a read lock on the parent entry, if there is one.  We need to do
@@ -254,10 +246,7 @@
       try
       {
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
+        checkIfCanceled(false);
 
 
         // Grab a write lock on the target entry.  We'll need to do this
@@ -280,7 +269,6 @@
           appendErrorMessage(ERR_ADD_CANNOT_LOCK_ENTRY.get(
                                   String.valueOf(entryDN)));
 
-          skipPostOperation = true;
           break addProcessing;
         }
 
@@ -293,9 +281,13 @@
           try
           {
             SynchronizationProviderResult result =
-                 provider.handleConflictResolution(this);
-            if (! result.continueOperationProcessing())
+                provider.handleConflictResolution(this);
+            if (! result.continueProcessing())
             {
+              setResultCode(result.getResultCode());
+              appendErrorMessage(result.getErrorMessage());
+              setMatchedDN(result.getMatchedDN());
+              setReferralURLs(result.getReferralURLs());
               break addProcessing;
             }
           }
@@ -591,50 +583,32 @@
           setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
           appendErrorMessage(ERR_ADD_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS.get(
                                   String.valueOf(entryDN)));
-          skipPostOperation = true;
           break addProcessing;
         }
 
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
-
+        checkIfCanceled(false);
 
         // If the operation is not a synchronization operation,
         // Invoke the pre-operation add plugins.
         if (! isSynchronizationOperation())
         {
-          PreOperationPluginResult preOpResult =
+          executePostOpPlugins = true;
+          PluginResult.PreOperation preOpResult =
             pluginConfigManager.invokePreOperationAddPlugins(this);
-          if (preOpResult.connectionTerminated())
+          if (!preOpResult.continueProcessing())
           {
-            // There's no point in continuing with anything.  Log the result
-            // and return.
-            setResultCode(ResultCode.CANCELED);
-            appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-
-            return;
-          }
-          else if (preOpResult.sendResponseImmediately())
-          {
-            skipPostOperation = true;
-            break addProcessing;
-          }
-          else if (preOpResult.skipCoreProcessing())
-          {
-            skipPostOperation = false;
+            setResultCode(preOpResult.getResultCode());
+            appendErrorMessage(preOpResult.getErrorMessage());
+            setMatchedDN(preOpResult.getMatchedDN());
+            setReferralURLs(preOpResult.getReferralURLs());
             break addProcessing;
           }
         }
 
 
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
+        checkIfCanceled(true);
 
 
         // If it is not a private backend, then check to see if the server or
@@ -696,9 +670,13 @@
               try
               {
                 SynchronizationProviderResult result =
-                     provider.doPreOperation(this);
-                if (! result.continueOperationProcessing())
+                    provider.doPreOperation(this);
+                if (! result.continueProcessing())
                 {
+                  setResultCode(result.getResultCode());
+                  appendErrorMessage(result.getErrorMessage());
+                  setMatchedDN(result.getMatchedDN());
+                  setReferralURLs(result.getReferralURLs());
                   break addProcessing;
                 }
               }
@@ -740,26 +718,6 @@
           setResponseData(de);
           break addProcessing;
         }
-        catch (CancelledOperationException coe)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, coe);
-          }
-
-          CancelResult cancelResult = coe.getCancelResult();
-
-          setCancelResult(cancelResult);
-          setResultCode(cancelResult.getResultCode());
-
-          Message message = coe.getMessageObject();
-          if ((message != null) && (message.length() > 0))
-          {
-            appendErrorMessage(message);
-          }
-
-          break addProcessing;
-        }
       }
       finally
       {
@@ -772,35 +730,29 @@
         {
           LockManager.unlock(parentDN, parentLock);
         }
-
-
-        for (SynchronizationProvider provider :
-             DirectoryServer.getSynchronizationProviders())
-        {
-          try
-          {
-            provider.doPostOperation(this);
-          }
-          catch (DirectoryException de)
-          {
-            if (debugEnabled())
-            {
-              TRACER.debugCaught(DebugLogLevel.ERROR, de);
-            }
-
-            logError(ERR_ADD_SYNCH_POSTOP_FAILED.get(getConnectionID(),
-                          getOperationID(), getExceptionMessage(de)));
-            setResponseData(de);
-            break;
-          }
-        }
       }
     }
 
+    for (SynchronizationProvider provider :
+        DirectoryServer.getSynchronizationProviders())
+    {
+      try
+      {
+        provider.doPostOperation(this);
+      }
+      catch (DirectoryException de)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, de);
+        }
 
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
-
+        logError(ERR_ADD_SYNCH_POSTOP_FAILED.get(getConnectionID(),
+            getOperationID(), getExceptionMessage(de)));
+        setResponseData(de);
+        break;
+      }
+    }
 
     // Invoke the post-operation or post-synchronization add plugins.
     if (isSynchronizationOperation())
@@ -810,18 +762,17 @@
         pluginConfigManager.invokePostSynchronizationAddPlugins(this);
       }
     }
-    else if (! skipPostOperation)
+    else if (executePostOpPlugins)
     {
       // FIXME -- Should this also be done while holding the locks?
-      PostOperationPluginResult postOpResult =
-           pluginConfigManager.invokePostOperationAddPlugins(this);
-      if (postOpResult.connectionTerminated())
+      PluginResult.PostOperation postOpResult =
+          pluginConfigManager.invokePostOperationAddPlugins(this);
+      if(!postOpResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the result and
-        // return.
-        setResultCode(ResultCode.CANCELED);
-        appendErrorMessage(ERR_CANCELED_BY_POSTOP_DISCONNECT.get());
-
+        setResultCode(postOpResult.getResultCode());
+        appendErrorMessage(postOpResult.getErrorMessage());
+        setMatchedDN(postOpResult.getMatchedDN());
+        setReferralURLs(postOpResult.getReferralURLs());
         return;
       }
     }
@@ -855,27 +806,6 @@
 
 
   /**
-   * Checks to determine whether there has been a request to cancel this
-   * operation.  If so, then set the cancel result and processing stop time.
-   *
-   * @return  {@code true} if there was a cancel request, or {@code false} if
-   *          not.
-   */
-  private boolean cancelIfRequested()
-  {
-    if (getCancelRequest() == null)
-    {
-      return false;
-    }
-
-    indicateCancelled(getCancelRequest());
-    setProcessingStopTime();
-    return true;
-  }
-
-
-
-  /**
    * Acquire a read lock on the parent of the entry to add.
    *
    * @return  The acquired read lock.
@@ -1576,7 +1506,6 @@
         if (!AccessControlConfigManager.getInstance().
                 getAccessControlHandler().isAllowed(parentDN, this, c))
         {
-          skipPostOperation = true;
           throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
                          ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid));
         }
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
index a130f82..0e15a35 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
@@ -38,8 +38,7 @@
 import org.opends.server.api.Backend;
 import org.opends.server.api.ClientConnection;
 import org.opends.server.api.SASLMechanismHandler;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.controls.AuthorizationIdentityResponseControl;
 import org.opends.server.controls.PasswordExpiredControl;
 import org.opends.server.controls.PasswordExpiringControl;
@@ -119,8 +118,8 @@
   // control in the bind response.
   private boolean returnAuthzID;
 
-  // Indicates whether to skip post-operation plugin processing.
-  private boolean skipPostOperation;
+  // Indicates whether to execute post-operation plugins.
+  private boolean executePostOpPlugins;
 
   // The client connection associated with this bind operation.
   private ClientConnection clientConnection;
@@ -194,7 +193,7 @@
     // Initialize a number of variables for use during the bind processing.
     clientConnection         = getClientConnection();
     returnAuthzID            = false;
-    skipPostOperation        = false;
+    executePostOpPlugins     = false;
     sizeLimit                = DirectoryServer.getSizeLimit();
     timeLimit                = DirectoryServer.getTimeLimit();
     lookthroughLimit         = DirectoryServer.getLookthroughLimit();
@@ -229,7 +228,6 @@
         setResultCode(ResultCode.INVALID_CREDENTIALS);
         setAuthFailureReason(ERR_BIND_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS.get(
                                   String.valueOf(bindDN)));
-        skipPostOperation = true;
         break bindProcessing;
       }
 
@@ -260,7 +258,7 @@
           {
             if (! processSimpleBind())
             {
-              return;
+              break bindProcessing;
             }
           }
           catch (DirectoryException de)
@@ -289,7 +287,7 @@
           {
             if (! processSASLBind())
             {
-              return;
+              break bindProcessing;
             }
           }
           catch (DirectoryException de)
@@ -316,7 +314,7 @@
         default:
           // Send a protocol error response to the client and disconnect.
           // NYI
-          return;
+          setResultCode(ResultCode.PROTOCOL_ERROR);
       }
     }
 
@@ -342,18 +340,16 @@
 
 
     // Invoke the post-operation bind plugins.
-    if (! skipPostOperation)
+    if (executePostOpPlugins)
     {
-      PostOperationPluginResult postOpResult =
+      PluginResult.PostOperation postOpResult =
            pluginConfigManager.invokePostOperationBindPlugins(this);
-      if (postOpResult.connectionTerminated())
+      if (!postOpResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the result
-        // and return.
-        setResultCode(ResultCode.CANCELED);
-        appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-        setProcessingStopTime();
-        return;
+        setResultCode(postOpResult.getResultCode());
+        appendErrorMessage(postOpResult.getErrorMessage());
+        setMatchedDN(postOpResult.getMatchedDN());
+        setReferralURLs(postOpResult.getReferralURLs());
       }
     }
 
@@ -421,9 +417,6 @@
         }
       }
     }
-
-    // Stop the processing timer.
-    setProcessingStopTime();
   }
 
 
@@ -448,7 +441,6 @@
         if (! AccessControlConfigManager.getInstance().
                  getAccessControlHandler(). isAllowed(bindDN, this, c))
         {
-          skipPostOperation = true;
           throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
                          ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid));
         }
@@ -557,7 +549,7 @@
 
       // Check to see if the user has a password.  If not, then fail.
       // FIXME -- We need to have a way to enable/disable debugging.
-      pwPolicyState = new PasswordPolicyState(userEntry, false, false);
+      pwPolicyState = new PasswordPolicyState(userEntry, false);
       policy = pwPolicyState.getPolicy();
       AttributeType  pwType = policy.getPasswordAttribute();
 
@@ -575,23 +567,17 @@
 
 
       // Invoke the pre-operation bind plugins.
-      PreOperationPluginResult preOpResult =
-           pluginConfigManager.invokePreOperationBindPlugins(this);
-      if (preOpResult.connectionTerminated())
+      executePostOpPlugins = true;
+      PluginResult.PreOperation preOpResult =
+          pluginConfigManager.invokePreOperationBindPlugins(this);
+      if (!preOpResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the result
-        // and return.
-        setResultCode(ResultCode.CANCELED);
-        appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-        setProcessingStopTime();
+        setResultCode(preOpResult.getResultCode());
+        appendErrorMessage(preOpResult.getErrorMessage());
+        setMatchedDN(preOpResult.getMatchedDN());
+        setReferralURLs(preOpResult.getReferralURLs());
         return false;
       }
-      else if (preOpResult.sendResponseImmediately()  ||
-               preOpResult.skipCoreProcessing())
-      {
-        skipPostOperation = false;
-        return true;
-      }
 
 
       // Determine whether the provided password matches any of the stored
@@ -719,23 +705,17 @@
 
 
     // Invoke the pre-operation bind plugins.
-    PreOperationPluginResult preOpResult =
-         pluginConfigManager.invokePreOperationBindPlugins(this);
-    if (preOpResult.connectionTerminated())
+    executePostOpPlugins = true;
+    PluginResult.PreOperation preOpResult =
+        pluginConfigManager.invokePreOperationBindPlugins(this);
+    if (!preOpResult.continueProcessing())
     {
-      // There's no point in continuing with anything.  Log the result
-      // and return.
-      setResultCode(ResultCode.CANCELED);
-      appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-      setProcessingStopTime();
+      setResultCode(preOpResult.getResultCode());
+      appendErrorMessage(preOpResult.getErrorMessage());
+      setMatchedDN(preOpResult.getMatchedDN());
+      setReferralURLs(preOpResult.getReferralURLs());
       return false;
     }
-    else if (preOpResult.sendResponseImmediately() ||
-             preOpResult.skipCoreProcessing())
-    {
-      skipPostOperation = true;
-      return true;
-    }
 
     setResultCode(ResultCode.SUCCESS);
     setAuthenticationInfo(new AuthenticationInfo());
@@ -773,23 +753,16 @@
 
 
     // Invoke the pre-operation bind plugins.
-    PreOperationPluginResult preOpResult =
-         pluginConfigManager.invokePreOperationBindPlugins(this);
-    if (preOpResult.connectionTerminated())
+    PluginResult.PreOperation preOpResult =
+        pluginConfigManager.invokePreOperationBindPlugins(this);
+    if (!preOpResult.continueProcessing())
     {
-      // There's no point in continuing with anything.  Log the result
-      // and return.
-      setResultCode(ResultCode.CANCELED);
-      appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-      setProcessingStopTime();
+      setResultCode(preOpResult.getResultCode());
+      appendErrorMessage(preOpResult.getErrorMessage());
+      setMatchedDN(preOpResult.getMatchedDN());
+      setReferralURLs(preOpResult.getReferralURLs());
       return false;
     }
-    else if (preOpResult.sendResponseImmediately() ||
-             preOpResult.skipCoreProcessing())
-    {
-      skipPostOperation = false;
-      return true;
-    }
 
     // Actually process the SASL bind.
     saslHandler.processSASLBind(this);
@@ -822,8 +795,7 @@
     else
     {
       // FIXME -- Need to have a way to enable debugging.
-      pwPolicyState = new PasswordPolicyState(saslAuthUserEntry, false,
-                                              false);
+      pwPolicyState = new PasswordPolicyState(saslAuthUserEntry, false);
       policy = pwPolicyState.getPolicy();
       setUserEntryDN(saslAuthUserEntry.getDN());
 
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 6e9f864..057bac0 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
@@ -34,8 +34,7 @@
 
 import org.opends.server.api.Backend;
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.controls.LDAPAssertionRequestControl;
 import org.opends.server.controls.ProxiedAuthV1Control;
 import org.opends.server.controls.ProxiedAuthV2Control;
@@ -45,19 +44,7 @@
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.PluginConfigManager;
 import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.AttributeValue;
-import org.opends.server.types.Control;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.LDAPException;
-import org.opends.server.types.LockManager;
-import org.opends.server.types.Privilege;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchFilter;
+import org.opends.server.types.*;
 import org.opends.server.types.operation.PostOperationCompareOperation;
 import org.opends.server.types.operation.PostResponseCompareOperation;
 import org.opends.server.types.operation.PreOperationCompareOperation;
@@ -89,9 +76,6 @@
   // The backend in which the comparison is to be performed.
   private Backend backend;
 
-  // Indicates whether to skip post-operation processing.
-  private boolean skipPostOperation;
-
   // The client connection for this operation.
   private ClientConnection clientConnection;
 
@@ -134,13 +118,16 @@
    *
    * @param  backend  The backend in which the compare operation should be
    *                  processed.
+   *
+   * @throws CanceledOperationException if this operation should be
+   * cancelled
    */
-  void processLocalCompare(Backend backend)
-  {
+  void processLocalCompare(Backend backend) throws CanceledOperationException {
+    boolean executePostOpPlugins = false;
+
     this.backend = backend;
 
     clientConnection  = getClientConnection();
-    skipPostOperation = false;
 
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
@@ -152,10 +139,7 @@
 
 
     // Check for a request to cancel this operation.
-    if (cancelIfRequested())
-    {
-      return;
-    }
+    checkIfCanceled(false);
 
 
     // Create a labeled block of code that we can break out of if a problem is
@@ -167,7 +151,6 @@
       entryDN = getEntryDN();
       if (entryDN == null)
       {
-        skipPostOperation = true;
         break compareProcessing;
       }
 
@@ -179,16 +162,12 @@
       {
         appendErrorMessage(ERR_COMPARE_CONFIG_INSUFFICIENT_PRIVILEGES.get());
         setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-        skipPostOperation = true;
         break compareProcessing;
       }
 
 
       // Check for a request to cancel this operation.
-      if (cancelIfRequested())
-      {
-        return;
-      }
+      checkIfCanceled(false);
 
 
       // Grab a read lock on the entry.
@@ -208,7 +187,6 @@
         appendErrorMessage(ERR_COMPARE_CANNOT_LOCK_ENTRY.get(
                                 String.valueOf(entryDN)));
 
-        skipPostOperation = true;
         break compareProcessing;
       }
 
@@ -297,39 +275,25 @@
           setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
           appendErrorMessage(ERR_COMPARE_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS.get(
                                   String.valueOf(entryDN)));
-          skipPostOperation = true;
           break compareProcessing;
         }
 
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
+        checkIfCanceled(false);
 
 
         // Invoke the pre-operation compare plugins.
-        PreOperationPluginResult preOpResult =
+        executePostOpPlugins = true;
+        PluginResult.PreOperation preOpResult =
              pluginConfigManager.invokePreOperationComparePlugins(this);
-        if (preOpResult.connectionTerminated())
-        {
-          // There's no point in continuing with anything.  Log the request and
-          // result and return.
-          setResultCode(ResultCode.CANCELED);
-          appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-          setProcessingStopTime();
-          return;
-        }
-        else if (preOpResult.sendResponseImmediately())
-        {
-          skipPostOperation = true;
-          break compareProcessing;
-        }
-        else if (preOpResult.skipCoreProcessing())
-        {
-          skipPostOperation = false;
-          break compareProcessing;
-        }
+          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.
@@ -415,22 +379,20 @@
 
 
     // Check for a request to cancel this operation.
-    if (cancelIfRequested())
-    {
-      return;
-    }
+    checkIfCanceled(false);
 
 
     // Invoke the post-operation compare plugins.
-    if (! skipPostOperation)
+    if (executePostOpPlugins)
     {
-      PostOperationPluginResult postOperationResult =
+      PluginResult.PostOperation postOpResult =
            pluginConfigManager.invokePostOperationComparePlugins(this);
-      if (postOperationResult.connectionTerminated())
+      if (!postOpResult.continueProcessing())
       {
-        setResultCode(ResultCode.CANCELED);
-        appendErrorMessage(ERR_CANCELED_BY_POSTOP_DISCONNECT.get());
-        return;
+        setResultCode(postOpResult.getResultCode());
+        appendErrorMessage(postOpResult.getErrorMessage());
+        setMatchedDN(postOpResult.getMatchedDN());
+        setReferralURLs(postOpResult.getReferralURLs());
       }
     }
   }
@@ -438,27 +400,6 @@
 
 
   /**
-   * Checks to determine whether there has been a request to cancel this
-   * operation.  If so, then set the cancel result and processing stop time.
-   *
-   * @return  {@code true} if there was a cancel request, or {@code false} if
-   *          not.
-   */
-  private boolean cancelIfRequested()
-  {
-    if (getCancelRequest() == null)
-    {
-      return false;
-    }
-
-    indicateCancelled(getCancelRequest());
-    setProcessingStopTime();
-    return true;
-  }
-
-
-
-  /**
    * Performs any processing required for the controls included in the request.
    *
    * @throws  DirectoryException  If a problem occurs that should prevent the
@@ -478,7 +419,6 @@
         if (! AccessControlConfigManager.getInstance().
                    getAccessControlHandler().isAllowed(entryDN, this, c))
         {
-          skipPostOperation = true;
           throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
                          ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid));
         }
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
index 330a523..89f4c67 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
@@ -37,8 +37,7 @@
 import org.opends.server.api.ChangeNotificationListener;
 import org.opends.server.api.ClientConnection;
 import org.opends.server.api.SynchronizationProvider;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.controls.LDAPAssertionRequestControl;
 import org.opends.server.controls.LDAPPreReadRequestControl;
 import org.opends.server.controls.LDAPPreReadResponseControl;
@@ -51,8 +50,7 @@
 import org.opends.server.core.PluginConfigManager;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.types.AttributeType;
-import org.opends.server.types.CancelledOperationException;
-import org.opends.server.types.CancelResult;
+import org.opends.server.types.CanceledOperationException;
 import org.opends.server.types.Control;
 import org.opends.server.types.DebugLogLevel;
 import org.opends.server.types.DirectoryException;
@@ -101,9 +99,6 @@
   // Indicates whether the LDAP no-op control has been requested.
   private boolean noOp;
 
-  // Indicates whether to skip post-operation processing.
-  private boolean skipPostOperation;
-
   // The client connection on which this operation was requested.
   private ClientConnection clientConnection;
 
@@ -150,9 +145,13 @@
    *
    * @param  backend  The backend in which the delete operation should be
    *                  processed.
+   *
+   * @throws CanceledOperationException if this operation should be
+   * cancelled
    */
-  void processLocalDelete(Backend backend)
-  {
+  void processLocalDelete(Backend backend) throws CanceledOperationException {
+    boolean executePostOpPlugins = false;
+
     this.backend = backend;
 
     clientConnection = getClientConnection();
@@ -160,13 +159,9 @@
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
          DirectoryServer.getPluginConfigManager();
-    skipPostOperation = false;
 
     // Check for a request to cancel this operation.
-    if (cancelIfRequested())
-    {
-      return;
-    }
+    checkIfCanceled(false);
 
     // Create a labeled block of code that we can break out of if a problem is
     // detected.
@@ -256,8 +251,12 @@
           {
             SynchronizationProviderResult result =
                  provider.handleConflictResolution(this);
-            if (! result.continueOperationProcessing())
+            if (! result.continueProcessing())
             {
+              setResultCode(result.getResultCode());
+              appendErrorMessage(result.getErrorMessage());
+              setMatchedDN(result.getMatchedDN());
+              setReferralURLs(result.getReferralURLs());
               break deleteProcessing;
             }
           }
@@ -309,46 +308,33 @@
           setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
           appendErrorMessage(ERR_DELETE_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS.get(
                                   String.valueOf(entryDN)));
-          skipPostOperation = true;
           break deleteProcessing;
         }
 
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
+        checkIfCanceled(false);
 
 
         // If the operation is not a synchronization operation,
         // invoke the pre-delete plugins.
         if (! isSynchronizationOperation())
         {
-          PreOperationPluginResult preOpResult =
+          executePostOpPlugins = true;
+          PluginResult.PreOperation preOpResult =
                pluginConfigManager.invokePreOperationDeletePlugins(this);
-          if (preOpResult.connectionTerminated())
+          if (!preOpResult.continueProcessing())
           {
-            // There's no point in continuing with anything.  Log the request
-            // and result and return.
-            setResultCode(ResultCode.CANCELED);
-            appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-            setProcessingStopTime();
-            return;
-          }
-          else if (preOpResult.sendResponseImmediately() ||
-                   preOpResult.skipCoreProcessing())
-          {
-            skipPostOperation = true;
+            setResultCode(preOpResult.getResultCode());
+            appendErrorMessage(preOpResult.getErrorMessage());
+            setMatchedDN(preOpResult.getMatchedDN());
+            setReferralURLs(preOpResult.getReferralURLs());
             break deleteProcessing;
           }
         }
 
 
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
+        checkIfCanceled(true);
 
 
         // Get the backend to use for the delete.  If there is none, then fail.
@@ -442,9 +428,13 @@
               try
               {
                 SynchronizationProviderResult result =
-                     provider.doPreOperation(this);
-                if (! result.continueOperationProcessing())
+                    provider.doPreOperation(this);
+                if (! result.continueProcessing())
                 {
+                  setResultCode(result.getResultCode());
+                  appendErrorMessage(result.getErrorMessage());
+                  setMatchedDN(result.getMatchedDN());
+                  setReferralURLs(result.getReferralURLs());
                   break deleteProcessing;
                 }
               }
@@ -484,57 +474,34 @@
           setResponseData(de);
           break deleteProcessing;
         }
-        catch (CancelledOperationException coe)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, coe);
-          }
-
-          CancelResult cancelResult = coe.getCancelResult();
-
-          setCancelResult(cancelResult);
-          setResultCode(cancelResult.getResultCode());
-
-          Message message = coe.getMessageObject();
-          if ((message != null) && (message.length() > 0))
-          {
-            appendErrorMessage(message);
-          }
-          break deleteProcessing;
-        }
       }
       finally
       {
         LockManager.unlock(entryDN, entryLock);
-
-        for (SynchronizationProvider provider :
-             DirectoryServer.getSynchronizationProviders())
-        {
-          try
-          {
-            provider.doPostOperation(this);
-          }
-          catch (DirectoryException de)
-          {
-            if (debugEnabled())
-            {
-              TRACER.debugCaught(DebugLogLevel.ERROR, de);
-            }
-
-            logError(ERR_DELETE_SYNCH_POSTOP_FAILED.get(getConnectionID(),
-                          getOperationID(), getExceptionMessage(de)));
-            setResponseData(de);
-            break;
-          }
-        }
       }
     }
 
 
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
+    for (SynchronizationProvider provider :
+        DirectoryServer.getSynchronizationProviders())
+    {
+      try
+      {
+        provider.doPostOperation(this);
+      }
+      catch (DirectoryException de)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, de);
+        }
 
+        logError(ERR_DELETE_SYNCH_POSTOP_FAILED.get(getConnectionID(),
+            getOperationID(), getExceptionMessage(de)));
+        setResponseData(de);
+        break;
+      }
+    }
 
     // Invoke the post-operation or post-synchronization delete plugins.
     if (isSynchronizationOperation())
@@ -544,15 +511,16 @@
         pluginConfigManager.invokePostSynchronizationDeletePlugins(this);
       }
     }
-    else if (! skipPostOperation)
+    else if (executePostOpPlugins)
     {
-      PostOperationPluginResult postOperationResult =
-           pluginConfigManager.invokePostOperationDeletePlugins(this);
-      if (postOperationResult.connectionTerminated())
+      PluginResult.PostOperation postOpResult =
+          pluginConfigManager.invokePostOperationDeletePlugins(this);
+      if (!postOpResult.continueProcessing())
       {
-        setResultCode(ResultCode.CANCELED);
-        appendErrorMessage(ERR_CANCELED_BY_POSTOP_DISCONNECT.get());
-        setProcessingStopTime();
+        setResultCode(postOpResult.getResultCode());
+        appendErrorMessage(postOpResult.getErrorMessage());
+        setMatchedDN(postOpResult.getMatchedDN());
+        setReferralURLs(postOpResult.getReferralURLs());
         return;
       }
     }
@@ -582,30 +550,6 @@
         }
       }
     }
-
-    // Stop the processing timer.
-    setProcessingStopTime();
-  }
-
-
-
-  /**
-   * Checks to determine whether there has been a request to cancel this
-   * operation.  If so, then set the cancel result and processing stop time.
-   *
-   * @return  {@code true} if there was a cancel request, or {@code false} if
-   *          not.
-   */
-  private boolean cancelIfRequested()
-  {
-    if (getCancelRequest() == null)
-    {
-      return false;
-    }
-
-    indicateCancelled(getCancelRequest());
-    setProcessingStopTime();
-    return true;
   }
 
 
@@ -630,7 +574,6 @@
         if (!AccessControlConfigManager.getInstance().
                  getAccessControlHandler().isAllowed(entryDN, this, c))
         {
-          skipPostOperation = true;
           throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
                          ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid));
         }
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 af9f9d4..85ce265 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
@@ -41,8 +41,7 @@
 import org.opends.server.api.ChangeNotificationListener;
 import org.opends.server.api.ClientConnection;
 import org.opends.server.api.SynchronizationProvider;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.controls.LDAPAssertionRequestControl;
 import org.opends.server.controls.LDAPPostReadRequestControl;
 import org.opends.server.controls.LDAPPostReadResponseControl;
@@ -61,8 +60,7 @@
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.AttributeValue;
 import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelledOperationException;
-import org.opends.server.types.CancelResult;
+import org.opends.server.types.CanceledOperationException;
 import org.opends.server.types.Control;
 import org.opends.server.types.DebugLogLevel;
 import org.opends.server.types.DirectoryException;
@@ -115,9 +113,6 @@
   // Indicates whether the no-op control was included in the request.
   private boolean noOp;
 
-  // Indicates whether to skip post-operation plugin processing.
-  private boolean skipPostOperation;
-
   // The client connection on which this operation was requested.
   private ClientConnection clientConnection;
 
@@ -190,9 +185,13 @@
    *
    * @param  backend  The backend in which the modify DN operation should be
    *                  processed.
+   *
+   * @throws CanceledOperationException if this operation should be
+   * cancelled
    */
-  void processLocalModifyDN(Backend backend)
-  {
+  void processLocalModifyDN(Backend backend) throws CanceledOperationException {
+    boolean executePostOpPlugins = false;
+
     this.backend = backend;
 
     clientConnection = getClientConnection();
@@ -200,13 +199,9 @@
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
          DirectoryServer.getPluginConfigManager();
-    skipPostOperation = false;
 
     // Check for a request to cancel this operation.
-    if (cancelIfRequested())
-    {
-      return;
-    }
+    checkIfCanceled(false);
 
     // Create a labeled block of code that we can break out of if a problem is
     // detected.
@@ -220,7 +215,6 @@
       newRDN = getNewRDN();
       if (newRDN == null)
       {
-        skipPostOperation = true;
         break modifyDNProcessing;
       }
 
@@ -228,7 +222,6 @@
       if ((newSuperior == null) &&
           (getRawNewSuperior() != null))
       {
-        skipPostOperation = true;
         break modifyDNProcessing;
       }
 
@@ -283,10 +276,7 @@
 
 
       // Check for a request to cancel this operation.
-      if (cancelIfRequested())
-      {
-        return;
-      }
+      checkIfCanceled(false);
 
 
       // Acquire write locks for the current and new DN.
@@ -305,7 +295,6 @@
         setResultCode(DirectoryServer.getServerErrorResultCode());
         appendErrorMessage(ERR_MODDN_CANNOT_LOCK_CURRENT_DN.get(
                                 String.valueOf(entryDN)));
-        skipPostOperation = true;
         break modifyDNProcessing;
       }
 
@@ -339,8 +328,6 @@
         appendErrorMessage(ERR_MODDN_EXCEPTION_LOCKING_NEW_DN.get(
                                 String.valueOf(entryDN), String.valueOf(newDN),
                                 getExceptionMessage(e)));
-
-        skipPostOperation = true;
         break modifyDNProcessing;
       }
 
@@ -352,17 +339,13 @@
         appendErrorMessage(ERR_MODDN_CANNOT_LOCK_NEW_DN.get(
                                 String.valueOf(entryDN),
                                 String.valueOf(newDN)));
-        skipPostOperation = true;
         break modifyDNProcessing;
       }
 
       try
       {
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
+        checkIfCanceled(false);
 
 
         // Get the current entry from the appropriate backend.  If it doesn't
@@ -424,8 +407,12 @@
           {
             SynchronizationProviderResult result =
                  provider.handleConflictResolution(this);
-            if (! result.continueOperationProcessing())
+            if (! result.continueProcessing())
             {
+              setResultCode(result.getResultCode());
+              appendErrorMessage(result.getErrorMessage());
+              setMatchedDN(result.getMatchedDN());
+              setReferralURLs(result.getReferralURLs());
               break modifyDNProcessing;
             }
           }
@@ -480,7 +467,6 @@
           setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
           appendErrorMessage(ERR_MODDN_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS.get(
                                   String.valueOf(entryDN)));
-          skipPostOperation = true;
           break modifyDNProcessing;
         }
 
@@ -514,11 +500,7 @@
 
 
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
-
+        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
@@ -530,24 +512,15 @@
         // Invoke the pre-operation modify DN plugins.
         if (! isSynchronizationOperation())
         {
-          PreOperationPluginResult preOpResult =
-            pluginConfigManager.invokePreOperationModifyDNPlugins(this);
-          if (preOpResult.connectionTerminated())
+          executePostOpPlugins = true;
+          PluginResult.PreOperation preOpResult =
+              pluginConfigManager.invokePreOperationModifyDNPlugins(this);
+          if (!preOpResult.continueProcessing())
           {
-            // There's no point in continuing with anything.  Log the request
-            // and result and return.
-            setResultCode(ResultCode.CANCELED);
-            appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-            return;
-          }
-          else if (preOpResult.sendResponseImmediately())
-          {
-            skipPostOperation = true;
-            break modifyDNProcessing;
-          }
-          else if (preOpResult.skipCoreProcessing())
-          {
-            skipPostOperation = false;
+            setResultCode(preOpResult.getResultCode());
+            appendErrorMessage(preOpResult.getErrorMessage());
+            setMatchedDN(preOpResult.getMatchedDN());
+            setReferralURLs(preOpResult.getReferralURLs());
             break modifyDNProcessing;
           }
         }
@@ -575,11 +548,7 @@
 
 
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
-
+        checkIfCanceled(true);
 
         // Actually perform the modify DN operation.
         // This should include taking
@@ -641,9 +610,13 @@
               try
               {
                 SynchronizationProviderResult result =
-                     provider.doPreOperation(this);
-                if (! result.continueOperationProcessing())
+                    provider.doPreOperation(this);
+                if (! result.continueProcessing())
                 {
+                  setResultCode(result.getResultCode());
+                  appendErrorMessage(result.getErrorMessage());
+                  setMatchedDN(result.getMatchedDN());
+                  setReferralURLs(result.getReferralURLs());
                   break modifyDNProcessing;
                 }
               }
@@ -685,59 +658,34 @@
           setResponseData(de);
           break modifyDNProcessing;
         }
-        catch (CancelledOperationException coe)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, coe);
-          }
-
-          CancelResult cancelResult = coe.getCancelResult();
-
-          setCancelResult(cancelResult);
-          setResultCode(cancelResult.getResultCode());
-
-          Message message = coe.getMessageObject();
-          if ((message != null) && (message.length() > 0))
-          {
-            appendErrorMessage(message);
-          }
-
-          break modifyDNProcessing;
-        }
       }
       finally
       {
         LockManager.unlock(entryDN, currentLock);
         LockManager.unlock(newDN, newLock);
-
-        for (SynchronizationProvider provider :
-             DirectoryServer.getSynchronizationProviders())
-        {
-          try
-          {
-            provider.doPostOperation(this);
-          }
-          catch (DirectoryException de)
-          {
-            if (debugEnabled())
-            {
-              TRACER.debugCaught(DebugLogLevel.ERROR, de);
-            }
-
-            logError(ERR_MODDN_SYNCH_POSTOP_FAILED.get(getConnectionID(),
-                          getOperationID(), getExceptionMessage(de)));
-            setResponseData(de);
-            break;
-          }
-        }
       }
     }
 
+    for (SynchronizationProvider provider :
+        DirectoryServer.getSynchronizationProviders())
+    {
+      try
+      {
+        provider.doPostOperation(this);
+      }
+      catch (DirectoryException de)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, de);
+        }
 
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
-
+        logError(ERR_MODDN_SYNCH_POSTOP_FAILED.get(getConnectionID(),
+            getOperationID(), getExceptionMessage(de)));
+        setResponseData(de);
+        break;
+      }
+    }
 
     // Invoke the post-operation or post-synchronization modify DN plugins.
     if (isSynchronizationOperation())
@@ -747,14 +695,16 @@
         pluginConfigManager.invokePostSynchronizationModifyDNPlugins(this);
       }
     }
-    else if (! skipPostOperation)
+    else if (executePostOpPlugins)
     {
-      PostOperationPluginResult postOperationResult =
+      PluginResult.PostOperation postOpResult =
            pluginConfigManager.invokePostOperationModifyDNPlugins(this);
-      if (postOperationResult.connectionTerminated())
+      if (!postOpResult.continueProcessing())
       {
-        setResultCode(ResultCode.CANCELED);
-        appendErrorMessage(ERR_CANCELED_BY_POSTOP_DISCONNECT.get());
+        setResultCode(postOpResult.getResultCode());
+        appendErrorMessage(postOpResult.getErrorMessage());
+        setMatchedDN(postOpResult.getMatchedDN());
+        setReferralURLs(postOpResult.getReferralURLs());
         return;
       }
     }
@@ -789,27 +739,6 @@
 
 
   /**
-   * Checks to determine whether there has been a request to cancel this
-   * operation.  If so, then set the cancel result and processing stop time.
-   *
-   * @return  {@code true} if there was a cancel request, or {@code false} if
-   *          not.
-   */
-  private boolean cancelIfRequested()
-  {
-    if (getCancelRequest() == null)
-    {
-      return false;
-    }
-
-    indicateCancelled(getCancelRequest());
-    setProcessingStopTime();
-    return true;
-  }
-
-
-
-  /**
    * Processes the set of controls included in the request.
    *
    * @throws  DirectoryException  If a problem occurs that should cause the
@@ -829,7 +758,6 @@
         if (! AccessControlConfigManager.getInstance().
                    getAccessControlHandler().isAllowed(entryDN,  this, c))
         {
-          skipPostOperation = true;
           throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
                          ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid));
         }
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
index e61f4e2..f172c3d 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -45,8 +45,7 @@
 import org.opends.server.api.ClientConnection;
 import org.opends.server.api.PasswordStorageScheme;
 import org.opends.server.api.SynchronizationProvider;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.controls.LDAPAssertionRequestControl;
 import org.opends.server.controls.LDAPPostReadRequestControl;
 import org.opends.server.controls.LDAPPostReadResponseControl;
@@ -75,8 +74,7 @@
 import org.opends.server.types.AttributeValue;
 import org.opends.server.types.AuthenticationInfo;
 import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelledOperationException;
-import org.opends.server.types.CancelResult;
+import org.opends.server.types.CanceledOperationException;
 import org.opends.server.types.Control;
 import org.opends.server.types.DebugLogLevel;
 import org.opends.server.types.DirectoryException;
@@ -149,9 +147,6 @@
   // Indicates whether the password change is a self-change.
   private boolean selfChange;
 
-  // Indicates whether to skip post-operation plugin processing.
-  private boolean skipPostOperation;
-
   // Indicates whether the user's account was locked before this change.
   private boolean wasLocked;
 
@@ -299,9 +294,13 @@
    *
    * @param  backend  The backend in which the modify operation should be
    *                  performed.
+   *
+   * @throws CanceledOperationException if this operation should be
+   * cancelled
    */
-  void processLocalModify(Backend backend)
-  {
+  void processLocalModify(Backend backend) throws CanceledOperationException {
+    boolean executePostOpPlugins = false;
+
     this.backend = backend;
 
     clientConnection = getClientConnection();
@@ -309,7 +308,9 @@
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
       DirectoryServer.getPluginConfigManager();
-    skipPostOperation = false;
+
+    // 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.
@@ -367,10 +368,7 @@
 
 
       // Check for a request to cancel this operation.
-      if (cancelIfRequested())
-      {
-        return;
-      }
+      checkIfCanceled(false);
 
       // Acquire a write lock on the target entry.
       Lock entryLock = null;
@@ -388,7 +386,6 @@
         setResultCode(DirectoryServer.getServerErrorResultCode());
         appendErrorMessage(ERR_MODIFY_CANNOT_LOCK_ENTRY.get(
                                 String.valueOf(entryDN)));
-        skipPostOperation = true;
         break modifyProcessing;
       }
 
@@ -396,10 +393,7 @@
       try
       {
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
+        checkIfCanceled(false);
 
 
         try
@@ -418,8 +412,7 @@
 
           // FIXME -- Need a way to enable debug mode.
           pwPolicyState = new PasswordPolicyState(currentEntry, false,
-                                                  TimeThread.getTime(), true,
-                                                  false);
+                                                  TimeThread.getTime(), true);
         }
         catch (DirectoryException de)
         {
@@ -446,9 +439,13 @@
             try
             {
               SynchronizationProviderResult result =
-                provider.handleConflictResolution(this);
-              if (! result.continueOperationProcessing())
+                  provider.handleConflictResolution(this);
+              if (! result.continueProcessing())
               {
+                setResultCode(result.getResultCode());
+                appendErrorMessage(result.getErrorMessage());
+                setMatchedDN(result.getMatchedDN());
+                setReferralURLs(result.getReferralURLs());
                 break modifyProcessing;
               }
             }
@@ -501,7 +498,6 @@
           setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
           appendErrorMessage(ERR_MODIFY_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS.get(
                                   String.valueOf(entryDN)));
-          skipPostOperation = true;
           break modifyProcessing;
         }
 
@@ -558,45 +554,28 @@
 
 
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
+        checkIfCanceled(false);
 
         // If the operation is not a synchronization operation,
         // Invoke the pre-operation modify plugins.
         if (! isSynchronizationOperation())
         {
-          PreOperationPluginResult preOpResult =
+          executePostOpPlugins = true;
+          PluginResult.PreOperation preOpResult =
             pluginConfigManager.invokePreOperationModifyPlugins(this);
-          if (preOpResult.connectionTerminated())
+          if (!preOpResult.continueProcessing())
           {
-            // There's no point in continuing with anything.  Log the result
-            // and return.
-            setResultCode(ResultCode.CANCELED);
-            appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-            setProcessingStopTime();
-            return;
-          }
-          else if (preOpResult.sendResponseImmediately())
-          {
-            skipPostOperation = true;
-            break modifyProcessing;
-          }
-          else if (preOpResult.skipCoreProcessing())
-          {
-            skipPostOperation = false;
+            setResultCode(preOpResult.getResultCode());
+            appendErrorMessage(preOpResult.getErrorMessage());
+            setMatchedDN(preOpResult.getMatchedDN());
+            setReferralURLs(preOpResult.getReferralURLs());
             break modifyProcessing;
           }
         }
 
 
         // Check for a request to cancel this operation.
-        if (cancelIfRequested())
-        {
-          return;
-        }
-
+        checkIfCanceled(true);
 
         // Actually perform the modify operation.  This should also include
         // taking care of any synchronization that might be needed.
@@ -639,9 +618,13 @@
               try
               {
                 SynchronizationProviderResult result =
-                     provider.doPreOperation(this);
-                if (! result.continueOperationProcessing())
+                    provider.doPreOperation(this);
+                if (! result.continueProcessing())
                 {
+                  setResultCode(result.getResultCode());
+                  appendErrorMessage(result.getErrorMessage());
+                  setMatchedDN(result.getMatchedDN());
+                  setReferralURLs(result.getReferralURLs());
                   break modifyProcessing;
                 }
               }
@@ -692,53 +675,33 @@
           setResponseData(de);
           break modifyProcessing;
         }
-        catch (CancelledOperationException coe)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, coe);
-          }
-
-          CancelResult cancelResult = coe.getCancelResult();
-
-          setCancelResult(cancelResult);
-          setResultCode(cancelResult.getResultCode());
-
-          Message message = coe.getMessageObject();
-          if (message != null)
-          {
-            appendErrorMessage(message);
-          }
-          break modifyProcessing;
-        }
       }
       finally
       {
         LockManager.unlock(entryDN, entryLock);
-
-        for (SynchronizationProvider provider :
-          DirectoryServer.getSynchronizationProviders())
-        {
-          try
-          {
-            provider.doPostOperation(this);
-          }
-          catch (DirectoryException de)
-          {
-            if (debugEnabled())
-            {
-              TRACER.debugCaught(DebugLogLevel.ERROR, de);
-            }
-
-            logError(ERR_MODIFY_SYNCH_POSTOP_FAILED.get(getConnectionID(),
-                          getOperationID(), getExceptionMessage(de)));
-            setResponseData(de);
-            break;
-          }
-        }
       }
     }
 
+    for (SynchronizationProvider provider :
+        DirectoryServer.getSynchronizationProviders())
+    {
+      try
+      {
+        provider.doPostOperation(this);
+      }
+      catch (DirectoryException de)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, de);
+        }
+
+        logError(ERR_MODIFY_SYNCH_POSTOP_FAILED.get(getConnectionID(),
+            getOperationID(), getExceptionMessage(de)));
+        setResponseData(de);
+        break;
+      }
+    }
 
     // If the password policy request control was included, then make sure we
     // send the corresponding response control.
@@ -748,10 +711,6 @@
                                                            pwpErrorType));
     }
 
-
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
-
     // Invoke the post-operation or post-synchronization modify plugins.
     if (isSynchronizationOperation())
     {
@@ -760,18 +719,17 @@
         pluginConfigManager.invokePostSynchronizationModifyPlugins(this);
       }
     }
-    else if (! skipPostOperation)
+    else if (executePostOpPlugins)
     {
       // FIXME -- Should this also be done while holding the locks?
-      PostOperationPluginResult postOpResult =
+      PluginResult.PostOperation postOpResult =
            pluginConfigManager.invokePostOperationModifyPlugins(this);
-      if (postOpResult.connectionTerminated())
+      if (!postOpResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the result and
-        // return.
-        setResultCode(ResultCode.CANCELED);
-        appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-        setProcessingStopTime();
+        setResultCode(postOpResult.getResultCode());
+        appendErrorMessage(postOpResult.getErrorMessage());
+        setMatchedDN(postOpResult.getMatchedDN());
+        setReferralURLs(postOpResult.getReferralURLs());
         return;
       }
     }
@@ -783,31 +741,6 @@
     {
       notifyChangeListeners();
     }
-
-
-    // Stop the processing timer.
-    setProcessingStopTime();
-  }
-
-
-
-  /**
-   * Checks to determine whether there has been a request to cancel this
-   * operation.  If so, then set the cancel result and processing stop time.
-   *
-   * @return  {@code true} if there was a cancel request, or {@code false} if
-   *          not.
-   */
-  private boolean cancelIfRequested()
-  {
-    if (getCancelRequest() == null)
-    {
-      return false;
-    }
-
-    indicateCancelled(getCancelRequest());
-    setProcessingStopTime();
-    return true;
   }
 
 
@@ -878,7 +811,6 @@
         if (! AccessControlConfigManager.getInstance().
                    getAccessControlHandler().isAllowed(entryDN, this, c))
         {
-          skipPostOperation = true;
           throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
                          ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid));
         }
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 515b6b7..96d3403 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
@@ -30,11 +30,9 @@
 
 import java.util.List;
 
-import org.opends.messages.Message;
 import org.opends.server.api.Backend;
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.controls.LDAPAssertionRequestControl;
 import org.opends.server.controls.MatchedValuesControl;
 import org.opends.server.controls.PersistentSearchControl;
@@ -47,8 +45,7 @@
 import org.opends.server.core.SearchOperationWrapper;
 import org.opends.server.core.SearchOperation;
 import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.CancelledOperationException;
+import org.opends.server.types.CanceledOperationException;
 import org.opends.server.types.Control;
 import org.opends.server.types.DebugLogLevel;
 import org.opends.server.types.DirectoryException;
@@ -93,9 +90,6 @@
   // only be false if it's a persistent search with changesOnly=true.
   private boolean processSearch;
 
-  // Indicates whether to skip post-operation plugin processing.
-  private boolean skipPostOperation;
-
   // The client connection for the search operation.
   private ClientConnection clientConnection;
 
@@ -129,9 +123,13 @@
    *
    * @param  backend  The backend in which the search operation should be
    *                  performed.
+   *
+   * @throws CanceledOperationException if this operation should be
+   * cancelled
    */
-  void processLocalSearch(Backend backend)
-  {
+  void processLocalSearch(Backend backend) throws CanceledOperationException {
+    boolean executePostOpPlugins = false;
+
     this.backend = backend;
 
     clientConnection = getClientConnection();
@@ -139,9 +137,11 @@
     // Get the plugin config manager that will be used for invoking plugins.
     PluginConfigManager pluginConfigManager =
       DirectoryServer.getPluginConfigManager();
-    skipPostOperation = false;
     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:
@@ -186,46 +186,29 @@
         setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
         appendErrorMessage(ERR_SEARCH_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS.get(
                                 String.valueOf(baseDN)));
-        skipPostOperation = true;
         break searchProcessing;
       }
 
       // Check for a request to cancel this operation.
-      if (cancelIfRequested())
-      {
-        return;
-      }
+      checkIfCanceled(false);
 
 
       // Invoke the pre-operation search plugins.
-      PreOperationPluginResult preOpResult =
-           pluginConfigManager.invokePreOperationSearchPlugins(this);
-      if (preOpResult.connectionTerminated())
+      executePostOpPlugins = true;
+      PluginResult.PreOperation preOpResult =
+          pluginConfigManager.invokePreOperationSearchPlugins(this);
+      if (!preOpResult.continueProcessing())
       {
-        // There's no point in continuing with anything.  Log the request and
-        // result and return.
-        setResultCode(ResultCode.CANCELED);
-        appendErrorMessage(ERR_CANCELED_BY_PREOP_DISCONNECT.get());
-        setProcessingStopTime();
-        return;
-      }
-      else if (preOpResult.sendResponseImmediately())
-      {
-        skipPostOperation = true;
-        break searchProcessing;
-      }
-      else if (preOpResult.skipCoreProcessing())
-      {
-        skipPostOperation = false;
+        setResultCode(preOpResult.getResultCode());
+        appendErrorMessage(preOpResult.getErrorMessage());
+        setMatchedDN(preOpResult.getMatchedDN());
+        setReferralURLs(preOpResult.getReferralURLs());
         break searchProcessing;
       }
 
 
       // Check for a request to cancel this operation.
-      if (cancelIfRequested())
-      {
-        return;
-      }
+      checkIfCanceled(false);
 
 
       // Get the backend that should hold the search base.  If there is none,
@@ -277,33 +260,6 @@
 
         break searchProcessing;
       }
-      catch (CancelledOperationException coe)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, coe);
-        }
-
-        CancelResult cancelResult = coe.getCancelResult();
-
-        setCancelResult(cancelResult);
-        setResultCode(cancelResult.getResultCode());
-
-        Message message = coe.getMessageObject();
-        if ((message != null) && (message.length() > 0))
-        {
-          appendErrorMessage(message);
-        }
-
-        if (persistentSearch != null)
-        {
-          DirectoryServer.deregisterPersistentSearch(persistentSearch);
-          setSendResponse(true);
-        }
-
-        skipPostOperation = true;
-        break searchProcessing;
-      }
       catch (Exception e)
       {
         if (debugEnabled())
@@ -321,57 +277,30 @@
           setSendResponse(true);
         }
 
-        skipPostOperation = true;
         break searchProcessing;
       }
     }
 
 
     // Check for a request to cancel this operation.
-    if (cancelIfRequested())
-    {
-      return;
-    }
-
+    checkIfCanceled(false);
 
     // Invoke the post-operation search plugins.
-    if (! skipPostOperation)
+    if (executePostOpPlugins)
     {
-      PostOperationPluginResult postOperationResult =
+      PluginResult.PostOperation postOpResult =
            pluginConfigManager.invokePostOperationSearchPlugins(this);
-      if (postOperationResult.connectionTerminated())
+      if (!postOpResult.continueProcessing())
       {
-        setResultCode(ResultCode.CANCELED);
-        appendErrorMessage(ERR_CANCELED_BY_POSTOP_DISCONNECT.get());
-        setProcessingStopTime();
-        return;
+        setResultCode(postOpResult.getResultCode());
+        appendErrorMessage(postOpResult.getErrorMessage());
+        setMatchedDN(postOpResult.getMatchedDN());
+        setReferralURLs(postOpResult.getReferralURLs());
       }
     }
   }
 
 
-
-  /**
-   * Checks to determine whether there has been a request to cancel this
-   * operation.  If so, then set the cancel result and processing stop time.
-   *
-   * @return  {@code true} if there was a cancel request, or {@code false} if
-   *          not.
-   */
-  private boolean cancelIfRequested()
-  {
-    if (getCancelRequest() == null)
-    {
-      return false;
-    }
-
-    indicateCancelled(getCancelRequest());
-    setProcessingStopTime();
-    return true;
-  }
-
-
-
   /**
    * Handles any controls contained in the request.
    *
@@ -391,7 +320,6 @@
         if (! AccessControlConfigManager.getInstance().
                    getAccessControlHandler().isAllowed(baseDN, this, c))
         {
-          skipPostOperation = true;
           throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
                          ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid));
         }
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
index c249023..c4fa635 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -45,14 +45,7 @@
 import org.opends.server.core.ModifyDNOperation;
 import org.opends.server.core.ModifyOperation;
 import org.opends.server.core.SearchOperation;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.Operation;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchResultReference;
+import org.opends.server.types.*;
 import org.opends.server.workflowelement.LeafWorkflowElement;
 
 
@@ -341,8 +334,7 @@
   /**
    * {@inheritDoc}
    */
-  public void execute(Operation operation)
-  {
+  public void execute(Operation operation) throws CanceledOperationException {
     switch (operation.getOperationType())
     {
       case BIND:
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/DirectoryServerPluginTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/DirectoryServerPluginTestCase.java
index b794363..f079a6f 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/DirectoryServerPluginTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/DirectoryServerPluginTestCase.java
@@ -44,6 +44,7 @@
 import org.opends.server.types.DisconnectReason;
 import org.opends.server.types.DN;
 import org.opends.server.types.Entry;
+import org.opends.server.types.CanceledOperationException;
 import org.opends.server.types.operation.*;
 import org.opends.server.TestCaseUtils;
 import org.opends.messages.Message;
@@ -193,7 +194,7 @@
 
     sigList = new LinkedList<String>();
     sigList.add("doStartup");
-    sigList.add("org.opends.server.api.plugin.StartupPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$Startup");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
@@ -204,13 +205,13 @@
 
     sigList = new LinkedList<String>();
     sigList.add("doPostConnect");
-    sigList.add("org.opends.server.api.plugin.PostConnectPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostConnect");
     sigList.add("org.opends.server.api.ClientConnection");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostDisconnect");
-    sigList.add("org.opends.server.api.plugin.PostDisconnectPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostDisconnect");
     sigList.add("org.opends.server.api.ClientConnection");
     sigList.add("org.opends.server.types.DisconnectReason");
     sigList.add("org.opends.messages.Message");
@@ -218,252 +219,266 @@
 
     sigList = new LinkedList<String>();
     sigList.add("doLDIFImport");
-    sigList.add("org.opends.server.api.plugin.LDIFPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$ImportLDIF");
     sigList.add("org.opends.server.types.LDIFImportConfig");
     sigList.add("org.opends.server.types.Entry");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doLDIFExport");
-    sigList.add("org.opends.server.api.plugin.LDIFPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$ImportLDIF");
     sigList.add("org.opends.server.types.LDIFExportConfig");
     sigList.add("org.opends.server.types.Entry");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreParse");
-    sigList.add("org.opends.server.api.plugin.PreParsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreParse");
     sigList.add("org.opends.server.types.operation.PreParseAbandonOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreParse");
-    sigList.add("org.opends.server.api.plugin.PreParsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreParse");
     sigList.add("org.opends.server.types.operation.PreParseModifyOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreParse");
-    sigList.add("org.opends.server.api.plugin.PreParsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreParse");
     sigList.add("org.opends.server.types.operation.PreParseAddOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreParse");
-    sigList.add("org.opends.server.api.plugin.PreParsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreParse");
     sigList.add("org.opends.server.types.operation.PreParseBindOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreParse");
-    sigList.add("org.opends.server.api.plugin.PreParsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreParse");
     sigList.add("org.opends.server.types.operation.PreParseCompareOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreParse");
-    sigList.add("org.opends.server.api.plugin.PreParsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreParse");
     sigList.add("org.opends.server.types.operation.PreParseDeleteOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreParse");
-    sigList.add("org.opends.server.api.plugin.PreParsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreParse");
     sigList.add("org.opends.server.types.operation.PreParseExtendedOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreParse");
-    sigList.add("org.opends.server.api.plugin.PreParsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreParse");
     sigList.add("org.opends.server.types.operation.PreParseUnbindOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreParse");
-    sigList.add("org.opends.server.api.plugin.PreParsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreParse");
     sigList.add("org.opends.server.types.operation.PreParseModifyDNOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreParse");
-    sigList.add("org.opends.server.api.plugin.PreParsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreParse");
     sigList.add("org.opends.server.types.operation.PreParseSearchOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreOperation");
-    sigList.add("org.opends.server.api.plugin.PreOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PreOperationExtendedOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreOperation");
-    sigList.add("org.opends.server.api.plugin.PreOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PreOperationDeleteOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreOperation");
-    sigList.add("org.opends.server.api.plugin.PreOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreOperation");
     sigList.add("org.opends.server.types.operation.PreOperationBindOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreOperation");
-    sigList.add("org.opends.server.api.plugin.PreOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PreOperationSearchOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreOperation");
-    sigList.add("org.opends.server.api.plugin.PreOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreOperation");
     sigList.add("org.opends.server.types.operation.PreOperationAddOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreOperation");
-    sigList.add("org.opends.server.api.plugin.PreOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreOperation");
     sigList.add("org.opends.server.types.operation."+
                 "PreOperationCompareOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreOperation");
-    sigList.add("org.opends.server.api.plugin.PreOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PreOperationModifyOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPreOperation");
-    sigList.add("org.opends.server.api.plugin.PreOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PreOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PreOperationModifyDNOperation");
+    sigList.add("org.opends.server.types.CanceledOperationException");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostOperation");
-    sigList.add("org.opends.server.api.plugin.PostOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PostOperationCompareOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostOperation");
-    sigList.add("org.opends.server.api.plugin.PostOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PostOperationModifyDNOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostOperation");
-    sigList.add("org.opends.server.api.plugin.PostOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PostOperationExtendedOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostOperation");
-    sigList.add("org.opends.server.api.plugin.PostOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PostOperationBindOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostOperation");
-    sigList.add("org.opends.server.api.plugin.PostOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PostOperationAbandonOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostOperation");
-    sigList.add("org.opends.server.api.plugin.PostOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PostOperationUnbindOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostOperation");
-    sigList.add("org.opends.server.api.plugin.PostOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PostOperationModifyOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostOperation");
-    sigList.add("org.opends.server.api.plugin.PostOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostOperation");
     sigList.add("org.opends.server.types.operation.PostOperationAddOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostOperation");
-    sigList.add("org.opends.server.api.plugin.PostOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PostOperationDeleteOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostOperation");
-    sigList.add("org.opends.server.api.plugin.PostOperationPluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostOperation");
     sigList.add("org.opends.server.types.operation." +
                 "PostOperationSearchOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostResponse");
-    sigList.add("org.opends.server.api.plugin.PostResponsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostResponse");
     sigList.add("org.opends.server.types.operation." +
                 "PostResponseCompareOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostResponse");
-    sigList.add("org.opends.server.api.plugin.PostResponsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostResponse");
     sigList.add("org.opends.server.types.operation." +
                 "PostResponseDeleteOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostResponse");
-    sigList.add("org.opends.server.api.plugin.PostResponsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostResponse");
     sigList.add("org.opends.server.types.operation." +
                 "PostResponseSearchOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostResponse");
-    sigList.add("org.opends.server.api.plugin.PostResponsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostResponse");
     sigList.add("org.opends.server.types.operation." +
                 "PostResponseExtendedOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostResponse");
-    sigList.add("org.opends.server.api.plugin.PostResponsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostResponse");
     sigList.add("org.opends.server.types.operation." +
                 "PostResponseModifyOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostResponse");
-    sigList.add("org.opends.server.api.plugin.PostResponsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostResponse");
     sigList.add("org.opends.server.types.operation." +
                 "PostResponseModifyDNOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostResponse");
-    sigList.add("org.opends.server.api.plugin.PostResponsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostResponse");
     sigList.add("org.opends.server.types.operation.PostResponseAddOperation");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("doPostResponse");
-    sigList.add("org.opends.server.api.plugin.PostResponsePluginResult");
+    sigList.add("org.opends.server.api.plugin.PluginResult$PostResponse");
     sigList.add("org.opends.server.types.operation.PostResponseBindOperation");
     expectedPublicMethods.add(sigList);
 
@@ -497,14 +512,16 @@
 
     sigList = new LinkedList<String>();
     sigList.add("processSearchEntry");
-    sigList.add("org.opends.server.api.plugin.SearchEntryPluginResult");
+    sigList.add("org.opends.server.api.plugin." +
+        "PluginResult$IntermediateResponse");
     sigList.add("org.opends.server.types.operation.SearchEntrySearchOperation");
     sigList.add("org.opends.server.types.SearchResultEntry");
     expectedPublicMethods.add(sigList);
 
     sigList = new LinkedList<String>();
     sigList.add("processSearchReference");
-    sigList.add("org.opends.server.api.plugin.SearchReferencePluginResult");
+    sigList.add("org.opends.server.api.plugin." +
+        "PluginResult$IntermediateResponse");
     sigList.add("org.opends.server.types.operation." +
                 "SearchReferenceSearchOperation");
     sigList.add("org.opends.server.types.SearchResultReference");
@@ -512,7 +529,8 @@
 
     sigList = new LinkedList<String>();
     sigList.add("processSubordinateModifyDN");
-    sigList.add("org.opends.server.api.plugin.SubordinateModifyDNPluginResult");
+    sigList.add("org.opends.server.api.plugin." +
+        "PluginResult$SubordinateModifyDN");
     sigList.add("org.opends.server.types.operation." +
                 "SubordinateModifyDNOperation");
     sigList.add("org.opends.server.types.Entry");
@@ -523,7 +541,7 @@
     sigList = new LinkedList<String>();
     sigList.add("processIntermediateResponse");
     sigList.add("org.opends.server.api.plugin." +
-                "IntermediateResponsePluginResult");
+        "PluginResult$IntermediateResponse");
     sigList.add("org.opends.server.types.IntermediateResponse");
     expectedPublicMethods.add(sigList);
 
@@ -984,8 +1002,7 @@
    * exception for add operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreParseAdd()
-  {
+  public void testDoPreParseAdd() throws CanceledOperationException {
     new NullPlugin().doPreParse((PreParseAddOperation) null);
   }
 
@@ -1008,8 +1025,7 @@
    * exception for compare operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreParseCompare()
-  {
+  public void testDoPreParseCompare() throws CanceledOperationException {
     new NullPlugin().doPreParse((PreParseCompareOperation) null);
   }
 
@@ -1020,8 +1036,7 @@
    * exception for delete operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreParseDelete()
-  {
+  public void testDoPreParseDelete() throws CanceledOperationException {
     new NullPlugin().doPreParse((PreParseDeleteOperation) null);
   }
 
@@ -1032,8 +1047,7 @@
    * exception for extended operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreParseExtended()
-  {
+  public void testDoPreParseExtended() throws CanceledOperationException {
     new NullPlugin().doPreParse((PreParseExtendedOperation) null);
   }
 
@@ -1044,8 +1058,7 @@
    * exception for modify operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreParseModify()
-  {
+  public void testDoPreParseModify() throws CanceledOperationException {
     new NullPlugin().doPreParse((PreParseModifyOperation) null);
   }
 
@@ -1056,8 +1069,7 @@
    * exception for modify DN operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreParseModifyDN()
-  {
+  public void testDoPreParseModifyDN() throws CanceledOperationException {
     new NullPlugin().doPreParse((PreParseModifyDNOperation) null);
   }
 
@@ -1068,8 +1080,7 @@
    * exception for search operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreParseSearch()
-  {
+  public void testDoPreParseSearch() throws CanceledOperationException {
     new NullPlugin().doPreParse((PreParseSearchOperation) null);
   }
 
@@ -1092,8 +1103,7 @@
    * exception for add operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreOperationAdd()
-  {
+  public void testDoPreOperationAdd() throws CanceledOperationException {
     new NullPlugin().doPreOperation((PreOperationAddOperation) null);
   }
 
@@ -1116,8 +1126,7 @@
    * exception for compare operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreOperationCompare()
-  {
+  public void testDoPreOperationCompare() throws CanceledOperationException {
     new NullPlugin().doPreOperation((PreOperationCompareOperation) null);
   }
 
@@ -1128,8 +1137,7 @@
    * exception for delete operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreOperationDelete()
-  {
+  public void testDoPreOperationDelete() throws CanceledOperationException {
     new NullPlugin().doPreOperation((PreOperationDeleteOperation) null);
   }
 
@@ -1140,8 +1148,7 @@
    * exception for extended operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreOperationExtended()
-  {
+  public void testDoPreOperationExtended() throws CanceledOperationException {
     new NullPlugin().doPreOperation((PreOperationExtendedOperation) null);
   }
 
@@ -1152,8 +1159,7 @@
    * exception for modify operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreOperationModify()
-  {
+  public void testDoPreOperationModify() throws CanceledOperationException {
     new NullPlugin().doPreOperation((PreOperationModifyOperation) null);
   }
 
@@ -1164,8 +1170,7 @@
    * exception for modify DN operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreOperationModifyDN()
-  {
+  public void testDoPreOperationModifyDN() throws CanceledOperationException {
     new NullPlugin().doPreOperation((PreOperationModifyDNOperation) null);
   }
 
@@ -1176,8 +1181,7 @@
    * exception for search operations.
    */
   @Test(expectedExceptions = { UnsupportedOperationException.class })
-  public void testDoPreOperationSearch()
-  {
+  public void testDoPreOperationSearch() throws CanceledOperationException {
     new NullPlugin().doPreOperation((PreOperationSearchOperation) null);
   }
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/IntermediateResponsePluginResultTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/IntermediateResponsePluginResultTestCase.java
deleted file mode 100644
index 9f1c7cc..0000000
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/IntermediateResponsePluginResultTestCase.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases for the intermediate response plugin result type.
- */
-public class IntermediateResponsePluginResultTestCase
-       extends PluginAPITestCase
-{
-  /**
-   * Retrieves a set of intermediate response plugin result instances.
-   *
-   * @return  A set of intermediate response plugin result instances.
-   */
-  @DataProvider(name = "instances")
-  public Object[][] getInstances()
-  {
-    return new Object[][]
-    {
-      new Object[] { IntermediateResponsePluginResult.SUCCESS },
-      new Object[] { new IntermediateResponsePluginResult(false, false, false,
-                                                          false) },
-      new Object[] { new IntermediateResponsePluginResult(true, false, false,
-                                                          false) },
-      new Object[] { new IntermediateResponsePluginResult(false, true, false,
-                                                          false) },
-      new Object[] { new IntermediateResponsePluginResult(false, false, true,
-                                                          false) },
-      new Object[] { new IntermediateResponsePluginResult(false, false, false,
-                                                          true) },
-      new Object[] { new IntermediateResponsePluginResult(true, true, false,
-                                                          false) },
-      new Object[] { new IntermediateResponsePluginResult(true, false, true,
-                                                          false) },
-      new Object[] { new IntermediateResponsePluginResult(true, false, false,
-                                                          true) },
-      new Object[] { new IntermediateResponsePluginResult(false, true, true,
-                                                          false) },
-      new Object[] { new IntermediateResponsePluginResult(false, true, false,
-                                                          true) },
-      new Object[] { new IntermediateResponsePluginResult(false, false, true,
-                                                          true) },
-      new Object[] { new IntermediateResponsePluginResult(true, true, true,
-                                                          false) },
-      new Object[] { new IntermediateResponsePluginResult(true, true, false,
-                                                          true) },
-      new Object[] { new IntermediateResponsePluginResult(true, false, true,
-                                                          true) },
-      new Object[] { new IntermediateResponsePluginResult(false, true, true,
-                                                          true) },
-      new Object[] { new IntermediateResponsePluginResult(true, true, true,
-                                                          true) }
-    };
-  }
-
-
-
-  /**
-   * Tests the <CODE>connectionTerminated</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testConnectionTerminated(IntermediateResponsePluginResult result)
-  {
-    result.connectionTerminated();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continuePluginProcessing</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinuePluginProcessing(IntermediateResponsePluginResult
-                                                result)
-  {
-    result.continuePluginProcessing();
-  }
-
-
-
-  /**
-   * Tests the <CODE>sendIntermediateResponse</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testSendIntermediateResponse(IntermediateResponsePluginResult
-                                           result)
-  {
-    result.sendIntermediateResponse();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continueOperation</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinueOperation(IntermediateResponsePluginResult result)
-  {
-    result.continueOperation();
-  }
-
-
-
-
-  /**
-   * Tests the <CODE>toString</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testToString(IntermediateResponsePluginResult result)
-  {
-    assertNotNull(result.toString());
-  }
-}
-
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/LDIFPluginResultTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/LDIFPluginResultTestCase.java
deleted file mode 100644
index cde67b0..0000000
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/LDIFPluginResultTestCase.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import java.util.HashSet;
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-
-import org.opends.server.plugins.NullPlugin;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.DN;
-import org.opends.server.types.operation.*;
-
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases for the LDIF plugin result type.
- */
-public class LDIFPluginResultTestCase
-       extends PluginAPITestCase
-{
-  /**
-   * Retrieves a set of LDIF plugin result instances.
-   *
-   * @return  A set of LDIF plugin result instances.
-   */
-  @DataProvider(name = "instances")
-  public Object[][] getInstances()
-  {
-    return new Object[][]
-    {
-      new Object[] { LDIFPluginResult.SUCCESS },
-      new Object[] { new LDIFPluginResult(false, false) },
-      new Object[] { new LDIFPluginResult(true, false) },
-      new Object[] { new LDIFPluginResult(false, true) },
-      new Object[] { new LDIFPluginResult(true, true) }
-    };
-  }
-
-
-
-  /**
-   * Tests the <CODE>continuePluginProcessing</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinuePluginProcessing(LDIFPluginResult result)
-  {
-    result.continuePluginProcessing();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continueEntryProcessing</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinueEntryProcessing(LDIFPluginResult result)
-  {
-    result.continueEntryProcessing();
-  }
-
-
-
-  /**
-   * Tests the <CODE>toString</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testToString(LDIFPluginResult result)
-  {
-    assertNotNull(result.toString());
-  }
-}
-
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostConnectPluginResultTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostConnectPluginResultTestCase.java
deleted file mode 100644
index ac65362..0000000
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostConnectPluginResultTestCase.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases for the post-connect plugin result type.
- */
-public class PostConnectPluginResultTestCase
-       extends PluginAPITestCase
-{
-  /**
-   * Retrieves a set of post-connect plugin result instances.
-   *
-   * @return  A set of post-connect plugin result instances.
-   */
-  @DataProvider(name = "instances")
-  public Object[][] getInstances()
-  {
-    return new Object[][]
-    {
-      new Object[] { PostConnectPluginResult.SUCCESS },
-      new Object[] { new PostConnectPluginResult(false, false) },
-      new Object[] { new PostConnectPluginResult(true, false) },
-      new Object[] { new PostConnectPluginResult(false, true) },
-      new Object[] { new PostConnectPluginResult(true, true) }
-    };
-  }
-
-
-
-  /**
-   * Tests the <CODE>connectionTerminated</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testConnectionTerminated(PostConnectPluginResult result)
-  {
-    result.connectionTerminated();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continuePluginProcessing</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinuePluginProcessing(PostConnectPluginResult result)
-  {
-    result.continuePluginProcessing();
-  }
-
-
-
-
-  /**
-   * Tests the <CODE>toString</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testToString(PostConnectPluginResult result)
-  {
-    assertNotNull(result.toString());
-  }
-}
-
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostDisconnectPluginResultTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostDisconnectPluginResultTestCase.java
deleted file mode 100644
index 25ec2fc..0000000
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostDisconnectPluginResultTestCase.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases for the post-disconnect plugin result type.
- */
-public class PostDisconnectPluginResultTestCase
-       extends PluginAPITestCase
-{
-  /**
-   * Retrieves a set of post-disconnect plugin result instances.
-   *
-   * @return  A set of post-disconnect plugin result instances.
-   */
-  @DataProvider(name = "instances")
-  public Object[][] getInstances()
-  {
-    return new Object[][]
-    {
-      new Object[] { PostDisconnectPluginResult.SUCCESS },
-      new Object[] { new PostDisconnectPluginResult(false) },
-      new Object[] { new PostDisconnectPluginResult(true) }
-    };
-  }
-
-
-
-  /**
-   * Tests the <CODE>continuePluginProcessing</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinuePluginProcessing(PostDisconnectPluginResult result)
-  {
-    result.continuePluginProcessing();
-  }
-
-
-
-
-  /**
-   * Tests the <CODE>toString</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testToString(PostDisconnectPluginResult result)
-  {
-    assertNotNull(result.toString());
-  }
-}
-
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostOperationPluginResultTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostOperationPluginResultTestCase.java
deleted file mode 100644
index cf4883d..0000000
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostOperationPluginResultTestCase.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases for the post-operation plugin result type.
- */
-public class PostOperationPluginResultTestCase
-       extends PluginAPITestCase
-{
-  /**
-   * Retrieves a set of post-operation plugin result instances.
-   *
-   * @return  A set of post-operation plugin result instances.
-   */
-  @DataProvider(name = "instances")
-  public Object[][] getInstances()
-  {
-    return new Object[][]
-    {
-      new Object[] { PostOperationPluginResult.SUCCESS },
-      new Object[] { new PostOperationPluginResult(false, false) },
-      new Object[] { new PostOperationPluginResult(true, false) },
-      new Object[] { new PostOperationPluginResult(false, true) },
-      new Object[] { new PostOperationPluginResult(true, true) },
-    };
-  }
-
-
-
-  /**
-   * Tests the <CODE>connectionTerminated</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testConnectionTerminated(PostOperationPluginResult result)
-  {
-    result.connectionTerminated();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continuePluginProcessing</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinuePluginProcessing(PostOperationPluginResult result)
-  {
-    result.continuePluginProcessing();
-  }
-
-
-
-  /**
-   * Tests the <CODE>toString</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testToString(PostOperationPluginResult result)
-  {
-    assertNotNull(result.toString());
-  }
-}
-
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostResponsePluginResultTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostResponsePluginResultTestCase.java
deleted file mode 100644
index 125e4d3..0000000
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PostResponsePluginResultTestCase.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases for the post-response plugin result type.
- */
-public class PostResponsePluginResultTestCase
-       extends PluginAPITestCase
-{
-  /**
-   * Retrieves a set of post-resposne plugin result instances.
-   *
-   * @return  A set of post-response plugin result instances.
-   */
-  @DataProvider(name = "instances")
-  public Object[][] getInstances()
-  {
-    return new Object[][]
-    {
-      new Object[] { PostResponsePluginResult.SUCCESS },
-      new Object[] { new PostResponsePluginResult(false, false) },
-      new Object[] { new PostResponsePluginResult(true, false) },
-      new Object[] { new PostResponsePluginResult(false, true) },
-      new Object[] { new PostResponsePluginResult(true, true) },
-    };
-  }
-
-
-
-  /**
-   * Tests the <CODE>connectionTerminated</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testConnectionTerminated(PostResponsePluginResult result)
-  {
-    result.connectionTerminated();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continuePluginProcessing</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinuePluginProcessing(PostResponsePluginResult result)
-  {
-    result.continuePluginProcessing();
-  }
-
-
-
-  /**
-   * Tests the <CODE>toString</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testToString(PostResponsePluginResult result)
-  {
-    assertNotNull(result.toString());
-  }
-}
-
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PreOperationPluginResultTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PreOperationPluginResultTestCase.java
deleted file mode 100644
index f22b415..0000000
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PreOperationPluginResultTestCase.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases for the pre-operation plugin result type.
- */
-public class PreOperationPluginResultTestCase
-       extends PluginAPITestCase
-{
-  /**
-   * Retrieves a set of pre-operation plugin result instances.
-   *
-   * @return  A set of pre-operation plugin result instances.
-   */
-  @DataProvider(name = "instances")
-  public Object[][] getInstances()
-  {
-    return new Object[][]
-    {
-      new Object[] { PreOperationPluginResult.SUCCESS },
-      new Object[] { new PreOperationPluginResult(false, false, false) },
-      new Object[] { new PreOperationPluginResult(true, false, false) },
-      new Object[] { new PreOperationPluginResult(false, true, false) },
-      new Object[] { new PreOperationPluginResult(false, false, true) },
-      new Object[] { new PreOperationPluginResult(true, true, false) },
-      new Object[] { new PreOperationPluginResult(true, false, true) },
-      new Object[] { new PreOperationPluginResult(false, true, true) },
-      new Object[] { new PreOperationPluginResult(true, true, true) },
-    };
-  }
-
-
-
-  /**
-   * Tests the <CODE>connectionTerminated</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testConnectionTerminated(PreOperationPluginResult result)
-  {
-    result.connectionTerminated();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continuePluginProcessing</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinuePluginProcessing(PreOperationPluginResult result)
-  {
-    result.continuePluginProcessing();
-  }
-
-
-
-  /**
-   * Tests the <CODE>sendResponseImmediately</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testSendResponseImmediately(PreOperationPluginResult result)
-  {
-    result.sendResponseImmediately();
-  }
-
-
-
-  /**
-   * Tests the <CODE>toString</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testToString(PreOperationPluginResult result)
-  {
-    assertNotNull(result.toString());
-  }
-}
-
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PreParsePluginResultTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PreParsePluginResultTestCase.java
deleted file mode 100644
index b52e9dd..0000000
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/PreParsePluginResultTestCase.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases for the pre-parse plugin result type.
- */
-public class PreParsePluginResultTestCase
-       extends PluginAPITestCase
-{
-  /**
-   * Retrieves a set of pre-parse plugin result instances.
-   *
-   * @return  A set of pre-parse plugin result instances.
-   */
-  @DataProvider(name = "instances")
-  public Object[][] getInstances()
-  {
-    return new Object[][]
-    {
-      new Object[] { PreParsePluginResult.SUCCESS },
-      new Object[] { new PreParsePluginResult(false, false, false) },
-      new Object[] { new PreParsePluginResult(true, false, false) },
-      new Object[] { new PreParsePluginResult(false, true, false) },
-      new Object[] { new PreParsePluginResult(false, false, true) },
-      new Object[] { new PreParsePluginResult(true, true, false) },
-      new Object[] { new PreParsePluginResult(true, false, true) },
-      new Object[] { new PreParsePluginResult(false, true, true) },
-      new Object[] { new PreParsePluginResult(true, true, true) },
-    };
-  }
-
-
-
-  /**
-   * Tests the <CODE>connectionTerminated</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testConnectionTerminated(PreParsePluginResult result)
-  {
-    result.connectionTerminated();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continuePluginProcessing</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinuePluginProcessing(PreParsePluginResult result)
-  {
-    result.continuePluginProcessing();
-  }
-
-
-
-  /**
-   * Tests the <CODE>sendResponseImmediately</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testSendResponseImmediately(PreParsePluginResult result)
-  {
-    result.sendResponseImmediately();
-  }
-
-
-
-  /**
-   * Tests the <CODE>toString</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testToString(PreParsePluginResult result)
-  {
-    assertNotNull(result.toString());
-  }
-}
-
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/SearchEntryPluginResultTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/SearchEntryPluginResultTestCase.java
deleted file mode 100644
index a3a8778..0000000
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/SearchEntryPluginResultTestCase.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases for the search entry plugin result type.
- */
-public class SearchEntryPluginResultTestCase
-       extends PluginAPITestCase
-{
-  /**
-   * Retrieves a set of search entry plugin result instances.
-   *
-   * @return  A set of search entry plugin result instances.
-   */
-  @DataProvider(name = "instances")
-  public Object[][] getInstances()
-  {
-    return new Object[][]
-    {
-      new Object[] { SearchEntryPluginResult.SUCCESS },
-      new Object[] { new SearchEntryPluginResult(false, false, false, false) },
-      new Object[] { new SearchEntryPluginResult(true, false, false, false) },
-      new Object[] { new SearchEntryPluginResult(false, true, false, false) },
-      new Object[] { new SearchEntryPluginResult(false, false, true, false) },
-      new Object[] { new SearchEntryPluginResult(false, false, false, true) },
-      new Object[] { new SearchEntryPluginResult(true, true, false, false) },
-      new Object[] { new SearchEntryPluginResult(true, false, true, false) },
-      new Object[] { new SearchEntryPluginResult(true, false, false, true) },
-      new Object[] { new SearchEntryPluginResult(false, true, true, false) },
-      new Object[] { new SearchEntryPluginResult(false, true, false, true) },
-      new Object[] { new SearchEntryPluginResult(false, false, true, true) },
-      new Object[] { new SearchEntryPluginResult(true, true, true, false) },
-      new Object[] { new SearchEntryPluginResult(true, true, false, true) },
-      new Object[] { new SearchEntryPluginResult(true, false, true, true) },
-      new Object[] { new SearchEntryPluginResult(false, true, true, true) },
-      new Object[] { new SearchEntryPluginResult(true, true, true, true) }
-    };
-  }
-
-
-
-  /**
-   * Tests the <CODE>connectionTerminated</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testConnectionTerminated(SearchEntryPluginResult result)
-  {
-    result.connectionTerminated();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continuePluginProcessing</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinuePluginProcessing(SearchEntryPluginResult result)
-  {
-    result.continuePluginProcessing();
-  }
-
-
-
-  /**
-   * Tests the <CODE>sendEntry</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testSendEntry(SearchEntryPluginResult result)
-  {
-    result.sendEntry();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continueSearch</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinueSearch(SearchEntryPluginResult result)
-  {
-    result.continueSearch();
-  }
-
-
-
-
-  /**
-   * Tests the <CODE>toString</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testToString(SearchEntryPluginResult result)
-  {
-    assertNotNull(result.toString());
-  }
-}
-
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/SearchReferencePluginResultTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/SearchReferencePluginResultTestCase.java
deleted file mode 100644
index 05169d4..0000000
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/SearchReferencePluginResultTestCase.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases for the search reference plugin result type.
- */
-public class SearchReferencePluginResultTestCase
-       extends PluginAPITestCase
-{
-  /**
-   * Retrieves a set of search reference plugin result instances.
-   *
-   * @return  A set of search reference plugin result instances.
-   */
-  @DataProvider(name = "instances")
-  public Object[][] getInstances()
-  {
-    return new Object[][]
-    {
-      new Object[] { SearchReferencePluginResult.SUCCESS },
-      new Object[] { new SearchReferencePluginResult(false, false, false,
-                                                     false) },
-      new Object[] { new SearchReferencePluginResult(true, false, false,
-                                                     false) },
-      new Object[] { new SearchReferencePluginResult(false, true, false,
-                                                     false) },
-      new Object[] { new SearchReferencePluginResult(false, false, true,
-                                                     false) },
-      new Object[] { new SearchReferencePluginResult(false, false, false,
-                                                     true) },
-      new Object[] { new SearchReferencePluginResult(true, true, false,
-                                                     false) },
-      new Object[] { new SearchReferencePluginResult(true, false, true,
-                                                     false) },
-      new Object[] { new SearchReferencePluginResult(true, false, false,
-                                                     true) },
-      new Object[] { new SearchReferencePluginResult(false, true, true,
-                                                     false) },
-      new Object[] { new SearchReferencePluginResult(false, true, false,
-                                                     true) },
-      new Object[] { new SearchReferencePluginResult(false, false, true,
-                                                     true) },
-      new Object[] { new SearchReferencePluginResult(true, true, true,
-                                                     false) },
-      new Object[] { new SearchReferencePluginResult(true, true, false,
-                                                     true) },
-      new Object[] { new SearchReferencePluginResult(true, false, true,
-                                                     true) },
-      new Object[] { new SearchReferencePluginResult(false, true, true,
-                                                     true) },
-      new Object[] { new SearchReferencePluginResult(true, true, true,
-                                                     true) }
-    };
-  }
-
-
-
-  /**
-   * Tests the <CODE>connectionTerminated</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testConnectionTerminated(SearchReferencePluginResult result)
-  {
-    result.connectionTerminated();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continuePluginProcessing</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinuePluginProcessing(SearchReferencePluginResult result)
-  {
-    result.continuePluginProcessing();
-  }
-
-
-
-  /**
-   * Tests the <CODE>sendReference</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testSendReference(SearchReferencePluginResult result)
-  {
-    result.sendReference();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continueSearch</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinueSearch(SearchReferencePluginResult result)
-  {
-    result.continueSearch();
-  }
-
-
-
-
-  /**
-   * Tests the <CODE>toString</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testToString(SearchReferencePluginResult result)
-  {
-    assertNotNull(result.toString());
-  }
-}
-
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/StartupPluginResultTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/StartupPluginResultTestCase.java
deleted file mode 100644
index d4d1a38..0000000
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/StartupPluginResultTestCase.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
- */
-package org.opends.server.api.plugin;
-
-
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-
-import static org.testng.Assert.*;
-import org.opends.messages.Message;
-
-
-/**
- * A set of test cases for the startup plugin result type.
- */
-public class StartupPluginResultTestCase
-       extends PluginAPITestCase
-{
-  /**
-   * Retrieves a set of startup plugin result instances.
-   *
-   * @return  A set of startup plugin result instances.
-   */
-  @DataProvider(name = "instances")
-  public Object[][] getInstances()
-  {
-    return new Object[][]
-    {
-      new Object[] { StartupPluginResult.SUCCESS },
-      new Object[] { new StartupPluginResult(false, false, null) },
-      new Object[] { new StartupPluginResult(true, false, null) },
-      new Object[] { new StartupPluginResult(false, true, null) },
-      new Object[] { new StartupPluginResult(true, true, null) },
-      new Object[] { new StartupPluginResult(false, false, null) },
-      new Object[] { new StartupPluginResult(true, false, null) },
-      new Object[] { new StartupPluginResult(false, true, null) },
-      new Object[] { new StartupPluginResult(true, true, null) },
-      new Object[] { new StartupPluginResult(false, false, Message.raw("foo")) },
-      new Object[] { new StartupPluginResult(true, false, Message.raw("foo")) },
-      new Object[] { new StartupPluginResult(false, true, Message.raw("foo")) },
-      new Object[] { new StartupPluginResult(true, true, Message.raw("foo")) },
-      new Object[] { new StartupPluginResult(false, false, Message.raw("foo")) },
-      new Object[] { new StartupPluginResult(true, false, Message.raw("foo")) },
-      new Object[] { new StartupPluginResult(false, true, Message.raw("foo")) },
-      new Object[] { new StartupPluginResult(true, true, Message.raw("foo")) },
-    };
-  }
-
-
-
-  /**
-   * Tests the <CODE>completedSuccessfully</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testCompletedSuccessfully(StartupPluginResult result)
-  {
-    result.completedSuccessfully();
-  }
-
-
-
-  /**
-   * Tests the <CODE>continueStartup</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testContinueStartup(StartupPluginResult result)
-  {
-    result.continueStartup();
-  }
-
-
-
-  /**
-   * Tests the <CODE>getErrorID</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testGetErrorID(StartupPluginResult result)
-  {
-    result.getErrorMessage();
-  }
-
-
-
-  /**
-   * Tests the <CODE>getErrorMessage</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testGetErrorMessage(StartupPluginResult result)
-  {
-    result.getErrorMessage();
-  }
-
-
-
-  /**
-   * Tests the <CODE>toString</CODE> method.
-   *
-   * @param  result  The result instance to test.
-   */
-  @Test(dataProvider = "instances")
-  public void testToString(StartupPluginResult result)
-  {
-    assertNotNull(result.toString());
-  }
-}
-
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AbandonOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AbandonOperationTestCase.java
index d6c1e36..0d9dad0 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AbandonOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AbandonOperationTestCase.java
@@ -148,8 +148,9 @@
 
     CancelRequest cancelRequest = new CancelRequest(true,
             Message.raw("Test Cancel"));
-    assertEquals(abandonOperation.cancel(cancelRequest),
-                 CancelResult.CANNOT_CANCEL);
+
+    assertEquals(abandonOperation.cancel(cancelRequest).getResultCode(),
+                 ResultCode.CANNOT_CANCEL);
   }
 
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
index e494146..5d08929 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
@@ -44,34 +44,12 @@
 import org.opends.server.plugins.DisconnectClientPlugin;
 import org.opends.server.plugins.ShortCircuitPlugin;
 import org.opends.server.plugins.UpdatePreOpPlugin;
-import org.opends.server.protocols.asn1.ASN1Element;
-import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.protocols.asn1.ASN1Reader;
-import org.opends.server.protocols.asn1.ASN1Sequence;
-import org.opends.server.protocols.asn1.ASN1Writer;
+import org.opends.server.plugins.DelayPreOpPlugin;
+import org.opends.server.protocols.asn1.*;
 import org.opends.server.protocols.internal.InternalClientConnection;
-import org.opends.server.protocols.ldap.AddRequestProtocolOp;
-import org.opends.server.protocols.ldap.AddResponseProtocolOp;
-import org.opends.server.protocols.ldap.BindRequestProtocolOp;
-import org.opends.server.protocols.ldap.BindResponseProtocolOp;
-import org.opends.server.protocols.ldap.LDAPAttribute;
-import org.opends.server.protocols.ldap.LDAPMessage;
+import org.opends.server.protocols.ldap.*;
 import org.opends.server.tools.LDAPModify;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.AttributeValue;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.LockManager;
-import org.opends.server.types.ObjectClass;
-import org.opends.server.types.Operation;
-import org.opends.server.types.RawAttribute;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.WritabilityMode;
-import org.opends.server.types.DirectoryException;
+import org.opends.server.types.*;
 
 import static org.testng.Assert.*;
 
@@ -1992,11 +1970,47 @@
 
     CancelRequest cancelRequest = new CancelRequest(false,
                                                     Message.raw("testCancelBeforeStartup"));
-    addOperation.setCancelRequest(cancelRequest);
+    addOperation.abort(cancelRequest);
     addOperation.run();
     assertEquals(addOperation.getResultCode(), ResultCode.CANCELED);
   }
 
+  /**
+   * Tests an add operation that gets canceled before startup.
+   *
+   * @throws  Exception  If an unexpected probem occurs.
+   */
+  @Test()
+  public void testCancelAfterOperation()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    Entry entry = TestCaseUtils.makeEntry(
+         "dn: ou=People,o=test",
+         "objectClass: top",
+         "objectClass: organizationalUnit",
+         "ou: People");
+
+    InternalClientConnection conn =
+         InternalClientConnection.getRootConnection();
+
+    AddOperationBasis addOperation =
+         new AddOperationBasis(conn, conn.nextOperationID(), conn.nextMessageID(),
+                          null, entry.getDN(), entry.getObjectClasses(),
+                          entry.getUserAttributes(),
+                          entry.getOperationalAttributes());
+
+    addOperation.run();
+
+    CancelRequest cancelRequest = new CancelRequest(false,
+                                                    Message.raw("testCancelAfterOperation"));
+    CancelResult cancelResult = addOperation.cancel(cancelRequest);
+
+    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+    assertEquals(cancelResult.getResultCode(), ResultCode.TOO_LATE);
+  }
+
 
 
   /**
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/BindOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/BindOperationTestCase.java
index b76b277..8e825d8 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/BindOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/BindOperationTestCase.java
@@ -53,23 +53,12 @@
 import org.opends.server.protocols.ldap.LDAPResultCode;
 import org.opends.server.tools.LDAPSearch;
 import org.opends.server.tools.dsconfig.DSConfig;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.AuthenticationInfo;
-import org.opends.server.types.AuthenticationType;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.Modification;
-import org.opends.server.types.ModificationType;
-import org.opends.server.types.Operation;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 
 import static org.testng.Assert.*;
 
 import static org.opends.server.protocols.ldap.LDAPConstants.*;
-
+import org.opends.messages.Message;
 
 
 /**
@@ -2297,5 +2286,37 @@
       );
     }
   }
+
+  /**
+   * Tests the <CODE>cancel</CODE> method to ensure that it indicates that the
+   * operation cannot be cancelled.
+   */
+  @Test(dataProvider = "simpleBinds")
+  public void testCancel(BindOperation bindOperation)
+  {
+    CancelRequest cancelRequest =
+         new CancelRequest(false, Message.raw("Test Unbind Cancel"));
+
+    assertEquals(bindOperation.cancel(cancelRequest).getResultCode(),
+                 ResultCode.CANNOT_CANCEL);
+  }
+
+  /**
+   * Tests the <CODE>getCancelRequest</CODE> method to ensure that it always
+   * returns <CODE>null</CODE>.
+   */
+  @Test(dataProvider = "simpleBinds")
+  public void testGetCancelRequest(BindOperation bindOperation)
+  {
+    CancelRequest cancelRequest =
+         new CancelRequest(false, Message.raw("Test Unbind Cancel"));
+
+    assertNull(bindOperation.getCancelRequest());
+
+    assertEquals(bindOperation.cancel(cancelRequest).getResultCode(),
+                 ResultCode.CANNOT_CANCEL);
+
+    assertNull(bindOperation.getCancelRequest());
+  }
 }
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java
index 7b306e8..2f5c32c 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java
@@ -51,19 +51,11 @@
 import org.opends.server.protocols.ldap.DeleteRequestProtocolOp;
 import org.opends.server.protocols.ldap.LDAPMessage;
 import org.opends.server.tools.LDAPDelete;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.LockManager;
-import org.opends.server.types.Operation;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.WritabilityMode;
-import org.opends.server.types.DirectoryException;
+import org.opends.server.types.*;
 import org.opends.server.workflowelement.localbackend.LocalBackendDeleteOperation;
 
 import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
 
 import static org.opends.server.protocols.ldap.LDAPConstants.*;
 
@@ -181,7 +173,7 @@
    * non-null, then was changed to null; because of the call to the
    * <CODE>setRawEntry<CODE> method, and becomes non-null again because
    * of the call to the <CODE>getEntryDN</CODE> again.
-   * 
+   *
    *
    * @throws  Exception  If an unexpected problem occurs.
    */
@@ -814,11 +806,39 @@
 
     CancelRequest cancelRequest = new CancelRequest(false,
                                                     Message.raw("testCancelBeforeStartup"));
-    deleteOperation.setCancelRequest(cancelRequest);
+    deleteOperation.abort(cancelRequest);
     deleteOperation.run();
     assertEquals(deleteOperation.getResultCode(), ResultCode.CANCELED);
   }
 
+  /**
+   * Tests a delete operation that gets canceled before startup.
+   *
+   * @throws  Exception  If an unexpected probem occurs.
+   */
+  @Test()
+  public void testCancelAfterOperation()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    InternalClientConnection conn =
+         InternalClientConnection.getRootConnection();
+
+    DeleteOperationBasis deleteOperation =
+         new DeleteOperationBasis(conn, conn.nextOperationID(), conn.nextMessageID(),
+                             null, new ASN1OctetString("o=test"));
+
+    deleteOperation.run();
+
+    CancelRequest cancelRequest = new CancelRequest(false,
+                                                    Message.raw("testCancelAfterOperation"));
+    CancelResult cancelResult = deleteOperation.cancel(cancelRequest);
+
+    assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS);
+    assertEquals(cancelResult.getResultCode(), ResultCode.TOO_LATE);
+  }
+
 
 
   /**
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
index c0088a8..94b8f40 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
@@ -630,7 +630,7 @@
 
     ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
     values.add(new ASN1OctetString("foo"));
-    LDAPAttribute attr = new LDAPAttribute("mail", values);
+    LDAPAttribute attr = new LDAPAttribute("description", values);
 
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.REPLACE, attr));
@@ -661,7 +661,7 @@
 
     ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
     values.add(new ASN1OctetString("foo"));
-    LDAPAttribute attr = new LDAPAttribute("mail", values);
+    LDAPAttribute attr = new LDAPAttribute("description", values);
 
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.REPLACE, attr));
@@ -1135,7 +1135,7 @@
     ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
     values.add(new ASN1OctetString("Foo"));
     values.add(new ASN1OctetString("Foo"));
-    LDAPAttribute attr = new LDAPAttribute("mail", values);
+    LDAPAttribute attr = new LDAPAttribute("description", values);
 
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.REPLACE, attr));
@@ -1954,7 +1954,7 @@
 
     ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
     values.add(new ASN1OctetString("bar"));
-    LDAPAttribute attr = new LDAPAttribute("mail", values);
+    LDAPAttribute attr = new LDAPAttribute("description", values);
 
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.REPLACE, attr));
@@ -2224,7 +2224,7 @@
     assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
 
 
-    LDAPAttribute attr = new LDAPAttribute("mail");
+    LDAPAttribute attr = new LDAPAttribute("description");
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.REPLACE, attr));
 
@@ -2272,7 +2272,7 @@
     assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
 
 
-    LDAPAttribute attr = new LDAPAttribute("mail");
+    LDAPAttribute attr = new LDAPAttribute("description");
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.REPLACE, attr));
 
@@ -2322,7 +2322,7 @@
 
     ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
     values.add(new ASN1OctetString("foo"));
-    LDAPAttribute attr = new LDAPAttribute("mail", values);
+    LDAPAttribute attr = new LDAPAttribute("description", values);
 
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.REPLACE, attr));
@@ -3083,7 +3083,7 @@
 
     ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
     values.add(new ASN1OctetString("notnumeric"));
-    LDAPAttribute attr = new LDAPAttribute("mail", values);
+    LDAPAttribute attr = new LDAPAttribute("description", values);
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.INCREMENT, attr));
 
@@ -4079,7 +4079,7 @@
 
     ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
     values.add(new ASN1OctetString("foo"));
-    LDAPAttribute attr = new LDAPAttribute("mail", values);
+    LDAPAttribute attr = new LDAPAttribute("description", values);
 
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.REPLACE, attr));
@@ -4090,7 +4090,7 @@
 
     CancelRequest cancelRequest = new CancelRequest(false,
                                                     Message.raw("testCancelBeforeStartup"));
-    modifyOperation.setCancelRequest(cancelRequest);
+    modifyOperation.abort(cancelRequest);
     modifyOperation.run();
     assertEquals(modifyOperation.getResultCode(), ResultCode.CANCELED);
   }
@@ -4098,6 +4098,42 @@
 
 
   /**
+   * Tests a modify operation that gets canceled before startup.
+   *
+   * @throws  Exception  If an unexpected probem occurs.
+   */
+  @Test(dataProvider = "baseDNs")
+  public void testCancelAfterOperation(String baseDN)
+         throws Exception
+  {
+    TestCaseUtils.clearJEBackend(true,"userRoot",baseDN);
+
+    InternalClientConnection conn =
+         InternalClientConnection.getRootConnection();
+
+    ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+    values.add(new ASN1OctetString("foo"));
+    LDAPAttribute attr = new LDAPAttribute("description", values);
+
+    ArrayList<RawModification> mods = new ArrayList<RawModification>();
+    mods.add(new LDAPModification(ModificationType.REPLACE, attr));
+
+    ModifyOperationBasis modifyOperation =
+         new ModifyOperationBasis(conn, conn.nextOperationID(), conn.nextMessageID(),
+                             null, new ASN1OctetString(baseDN), mods);
+
+    modifyOperation.run();
+
+    CancelRequest cancelRequest = new CancelRequest(false,
+                                                    Message.raw("testCancelBeforeStartup"));
+    CancelResult cancelResponse = modifyOperation.cancel(cancelRequest);
+    assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
+    assertEquals(cancelResponse.getResultCode(), ResultCode.TOO_LATE);
+  }
+
+
+
+  /**
    * Tests a modify operation in which the server cannot obtain a lock on the
    * target entry because there is already a read lock held on it.
    *
@@ -4118,7 +4154,7 @@
 
       ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
       values.add(new ASN1OctetString("foo"));
-      LDAPAttribute attr = new LDAPAttribute("mail", values);
+      LDAPAttribute attr = new LDAPAttribute("description", values);
 
       ArrayList<RawModification> mods = new ArrayList<RawModification>();
       mods.add(new LDAPModification(ModificationType.REPLACE, attr));
@@ -4165,7 +4201,7 @@
 
     ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
     values.add(new ASN1OctetString("foo"));
-    LDAPAttribute attr = new LDAPAttribute("mail", values);
+    LDAPAttribute attr = new LDAPAttribute("description", values);
 
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.REPLACE, attr));
@@ -4284,7 +4320,7 @@
 
     ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
     values.add(new ASN1OctetString("foo"));
-    LDAPAttribute attr = new LDAPAttribute("mail", values);
+    LDAPAttribute attr = new LDAPAttribute("description", values);
 
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.REPLACE, attr));
@@ -4296,13 +4332,41 @@
               "PostOperation"));
     w.writeElement(message.encode());
 
-    ASN1Element element = r.readElement();
-    if (element != null)
+    // The operation should NOT be aborted at the post operation stage. While
+    // the plugin can disconnect the client, the modify should have already
+    // been committed to the backend and a SUCCESS COULD get back to the
+    // client.
+responseLoop:
+    while (true)
     {
-      // If we got an element back, then it must be a notice of disconnect
-      // unsolicited notification.
+      ASN1Element element = r.readElement();
+      if (element == null)
+      {
+        // The connection has been closed.
+        break responseLoop;
+      }
+
       message = LDAPMessage.decode(element.decodeAsSequence());
-      assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+      switch (message.getProtocolOpType())
+      {
+        case OP_TYPE_MODIFY_RESPONSE:
+          // This was expected.  The disconnect didn't happen until after the
+          // response was sent.
+          break;
+        case OP_TYPE_EXTENDED_RESPONSE:
+          // The server is notifying us that it will be closing the connection.
+          break responseLoop;
+        default:
+          // This is a problem.  It's an unexpected response.
+          try
+          {
+            s.close();
+          } catch (Exception e) {}
+
+          throw new Exception("Unexpected response message " + message +
+                              " encountered in " +
+                              "testDisconnectInPostOperationModify");
+      }
     }
 
     try
@@ -4344,7 +4408,7 @@
 
     ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
     values.add(new ASN1OctetString("foo"));
-    LDAPAttribute attr = new LDAPAttribute("mail", values);
+    LDAPAttribute attr = new LDAPAttribute("description", values);
 
     ArrayList<RawModification> mods = new ArrayList<RawModification>();
     mods.add(new LDAPModification(ModificationType.REPLACE, attr));
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java
index c799a45..26a9c92 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java
@@ -47,6 +47,7 @@
 import org.opends.server.plugins.InvocationCounterPlugin;
 import org.opends.server.plugins.ShortCircuitPlugin;
 import org.opends.server.tools.LDAPModify;
+import org.opends.messages.Message;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -466,6 +467,12 @@
                                null);
 
     modifyDNOperation.run();
+
+    CancelRequest cancelRequest = new CancelRequest(false,
+                                                    Message.raw("testCancelBeforeStartup"));
+    CancelResult cancelResult = modifyDNOperation.cancel(cancelRequest);
+
+    assertEquals(cancelResult.getResultCode(), ResultCode.TOO_LATE);
     assertEquals(modifyDNOperation.getResultCode(),
                  ResultCode.SUCCESS);
     assertEquals(modifyDNOperation.getErrorMessage().length(), 0);
@@ -1483,5 +1490,28 @@
       InvocationCounterPlugin.resetAllCounters();
     }
   }
+
+  @Test
+  public void testCancelBeforeStartup() throws Exception
+  {
+    ArrayList<Control> noControls = new ArrayList<Control>(0);
+    InvocationCounterPlugin.resetAllCounters();
+
+    InternalClientConnection conn =
+         InternalClientConnection.getRootConnection();
+
+    ModifyDNOperationBasis modifyDNOperation =
+         new ModifyDNOperationBasis(conn, conn.nextOperationID(), conn.nextMessageID(),
+                               noControls,
+                               DN.decode("uid=user.invalid,ou=People,dc=example,dc=com"),
+                               RDN.decode("uid=user.test0"), true,
+                               DN.decode("dc=example,dc=com"));
+
+    CancelRequest cancelRequest = new CancelRequest(false,
+                                                    Message.raw("testCancelBeforeStartup"));
+    modifyDNOperation.abort(cancelRequest);
+    modifyDNOperation.run();
+    assertEquals(modifyDNOperation.getResultCode(), ResultCode.CANCELED);
+  }
 }
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/UnbindOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/UnbindOperationTestCase.java
index f0d5fa7..b56a200 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/UnbindOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/UnbindOperationTestCase.java
@@ -36,10 +36,7 @@
 import org.opends.messages.Message;
 import org.opends.server.plugins.InvocationCounterPlugin;
 import org.opends.server.protocols.internal.InternalClientConnection;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.Operation;
+import org.opends.server.types.*;
 
 import static org.testng.Assert.*;
 
@@ -131,8 +128,8 @@
     UnbindOperationBasis unbindOperation =
          new UnbindOperationBasis(conn, conn.nextOperationID(),
                              conn.nextMessageID(), new ArrayList<Control>());
-    assertEquals(unbindOperation.cancel(cancelRequest),
-                 CancelResult.CANNOT_CANCEL);
+    assertEquals(unbindOperation.cancel(cancelRequest).getResultCode(),
+                 ResultCode.CANNOT_CANCEL);
   }
 
 
@@ -155,8 +152,8 @@
                              conn.nextMessageID(), new ArrayList<Control>());
     assertNull(unbindOperation.getCancelRequest());
 
-    assertEquals(unbindOperation.cancel(cancelRequest),
-                 CancelResult.CANNOT_CANCEL);
+    assertEquals(unbindOperation.cancel(cancelRequest).getResultCode(),
+                 ResultCode.CANNOT_CANCEL);
 
     assertNull(unbindOperation.getCancelRequest());
   }
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CancelExtendedOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CancelExtendedOperationTestCase.java
index 8a7fb6e..c614ca8 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CancelExtendedOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CancelExtendedOperationTestCase.java
@@ -38,6 +38,7 @@
 
 import org.opends.server.TestCaseUtils;
 import org.opends.server.core.AddOperation;
+import org.opends.server.core.AbandonOperationBasis;
 import org.opends.server.plugins.DelayPreOpPlugin;
 import org.opends.server.protocols.asn1.ASN1Element;
 import org.opends.server.protocols.asn1.ASN1Integer;
@@ -67,23 +68,14 @@
 import org.opends.server.protocols.ldap.ModifyDNResponseProtocolOp;
 import org.opends.server.protocols.ldap.SearchRequestProtocolOp;
 import org.opends.server.protocols.ldap.SearchResultDoneProtocolOp;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.Control;
-import org.opends.server.types.DereferencePolicy;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.Modification;
-import org.opends.server.types.ModificationType;
-import org.opends.server.types.RawAttribute;
-import org.opends.server.types.RawModification;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchScope;
+import org.opends.server.types.*;
 
 import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
 
 import static org.opends.server.protocols.ldap.LDAPConstants.*;
 import static org.opends.server.util.ServerConstants.*;
-
+import org.opends.messages.Message;
 
 
 /**
@@ -848,5 +840,56 @@
 
     socket.close();
   }
+
+  /**
+   * Tests the ability to cancel an extended operation.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCancelCancelExtendedOperation()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+
+    // Create a new connection to the Directory Server and authenticate as
+    // the Directory Manager.
+    Socket socket = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
+    ASN1Reader reader = new ASN1Reader(socket);
+    ASN1Writer writer = new ASN1Writer(socket);
+
+    BindRequestProtocolOp bindRequest =
+         new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+                                   3, new ASN1OctetString("password"));
+    LDAPMessage message = new LDAPMessage(1, bindRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
+    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+
+
+    // Create a self cancelling request and send it to the server. Make sure
+    // to include the delay request control so it won't complete before we
+    // can send the cancel request.
+    ArrayList<ASN1Element> sequenceElements = new ArrayList<ASN1Element>(1);
+    sequenceElements.add(new ASN1Integer(2));
+    ASN1Sequence valueSequence = new ASN1Sequence(sequenceElements);
+    ASN1OctetString extendedValue = new ASN1OctetString(valueSequence.encode());
+    ExtendedRequestProtocolOp extendedRequest =
+        new ExtendedRequestProtocolOp(OID_CANCEL_REQUEST, extendedValue);
+    message = new LDAPMessage(2, extendedRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    ExtendedResponseProtocolOp extendedResponse =
+        message.getExtendedResponseProtocolOp();
+    assertEquals(extendedResponse.getResultCode(),
+        LDAPResultCode.CANNOT_CANCEL);
+
+    socket.close();
+  }
+
 }
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java
index 9613e41..eee7db2 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java
@@ -257,7 +257,7 @@
                DirectoryServer.getEntry(DN.decode("uid=test.user,o=test"));
 
     PasswordPolicyState pwPolicyState =
-         new PasswordPolicyState(userEntry, false, false);
+         new PasswordPolicyState(userEntry, false);
     PasswordPolicy policy = pwPolicyState.getPolicy();
 
     HashMap<AccountStatusNotificationProperty,List<String>>
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DelayPreOpPlugin.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DelayPreOpPlugin.java
index f5093d1..20eea6f 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DelayPreOpPlugin.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DelayPreOpPlugin.java
@@ -35,13 +35,14 @@
 import org.opends.server.admin.std.server.PluginCfg;
 import org.opends.server.api.plugin.DirectoryServerPlugin;
 import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.config.ConfigException;
 import org.opends.server.protocols.asn1.ASN1Long;
 import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.protocols.ldap.LDAPControl;
 import org.opends.server.types.Control;
 import org.opends.server.types.ResultCode;
+import org.opends.server.types.CanceledOperationException;
 import org.opends.server.types.operation.*;
 import org.opends.messages.Message;
 
@@ -115,9 +116,9 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationAddOperation addOperation)
-  {
+      throws CanceledOperationException {
     return doPreOperationInternal(addOperation);
   }
 
@@ -127,10 +128,18 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
-       doPreOperation(PreOperationBindOperation bindOperation)
+  public PluginResult.PreOperation
+         doPreOperation(PreOperationBindOperation bindOperation)
   {
-    return doPreOperationInternal(bindOperation);
+    try
+    {
+      return doPreOperationInternal(bindOperation);
+    }
+    catch(CanceledOperationException coe)
+    {
+      // Bind ops can't be canceled. Just ignore.
+      return PluginResult.PreOperation.continueOperationProcessing();
+    }
   }
 
 
@@ -139,9 +148,9 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
-       doPreOperation(PreOperationCompareOperation compareOperation)
-  {
+  public PluginResult.PreOperation
+         doPreOperation(PreOperationCompareOperation compareOperation)
+      throws CanceledOperationException {
     return doPreOperationInternal(compareOperation);
   }
 
@@ -151,9 +160,9 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationDeleteOperation deleteOperation)
-  {
+      throws CanceledOperationException {
     return doPreOperationInternal(deleteOperation);
   }
 
@@ -163,9 +172,9 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationExtendedOperation extendedOperation)
-  {
+      throws CanceledOperationException {
     return doPreOperationInternal(extendedOperation);
   }
 
@@ -175,9 +184,9 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationModifyOperation modifyOperation)
-  {
+      throws CanceledOperationException {
     return doPreOperationInternal(modifyOperation);
   }
 
@@ -187,9 +196,9 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationModifyDNOperation modifyDNOperation)
-  {
+      throws CanceledOperationException {
     return doPreOperationInternal(modifyDNOperation);
   }
 
@@ -199,9 +208,9 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationSearchOperation searchOperation)
-  {
+      throws CanceledOperationException {
     return doPreOperationInternal(searchOperation);
   }
 
@@ -217,9 +226,9 @@
    *
    * @return  The result of the plugin processing.
    */
-  private PreOperationPluginResult
+  private PluginResult.PreOperation
        doPreOperationInternal(PreOperationOperation operation)
-  {
+      throws CanceledOperationException {
     long delayDuration = 0L;
     List<Control> requestControls = operation.getRequestControls();
     if (requestControls != null)
@@ -235,10 +244,10 @@
           }
           catch (Exception e)
           {
-            operation.setResultCode(ResultCode.PROTOCOL_ERROR);
-            operation.appendErrorMessage(Message.raw("Unable to decode the delay request " +
-                                         "control:  " + e));
-            return new PreOperationPluginResult(false, false, true);
+            return PluginResult.PreOperation.stopProcessing(
+                ResultCode.PROTOCOL_ERROR,
+                Message.raw("Unable to decode the delay request control:  " +
+                    e));
           }
         }
       }
@@ -246,16 +255,13 @@
 
     if (delayDuration <= 0)
     {
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
 
     long stopSleepTime = System.currentTimeMillis() + delayDuration;
     while (System.currentTimeMillis() < stopSleepTime)
     {
-      if (operation.getCancelRequest() != null)
-      {
-        break;
-      }
+      operation.checkIfCanceled(false);
 
       try
       {
@@ -263,7 +269,7 @@
       } catch (Exception e) {}
     }
 
-    return new PreOperationPluginResult(false, false, false);
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DisconnectClientPlugin.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DisconnectClientPlugin.java
index 12f4160..d8e13e6 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DisconnectClientPlugin.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DisconnectClientPlugin.java
@@ -33,18 +33,13 @@
 import java.util.Set;
 
 import org.opends.server.admin.std.server.PluginCfg;
-import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.DirectoryServerPlugin;
-import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PostResponsePluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
-import org.opends.server.api.plugin.PreParsePluginResult;
+import org.opends.server.api.plugin.*;
 import org.opends.server.config.ConfigException;
 import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.protocols.ldap.LDAPControl;
 import org.opends.server.types.Control;
 import org.opends.server.types.DisconnectReason;
+import org.opends.server.types.CanceledOperationException;
 import org.opends.server.types.operation.*;
 import org.opends.messages.Message;
 
@@ -155,17 +150,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
-       doPreParse(PreParseAbandonOperation abandonOperation)
+  public PluginResult.PreParse doPreParse(
+      PreParseAbandonOperation abandonOperation)
   {
-    if (disconnectInternal(abandonOperation, "PreParse"))
-    {
-      return new PreParsePluginResult(true, false, false);
-    }
-    else
-    {
-      return PreParsePluginResult.SUCCESS;
-    }
+    disconnectInternal(abandonOperation, "PreParse");
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -174,16 +163,13 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult doPreParse(PreParseAddOperation addOperation)
-  {
+  public PluginResult.PreParse doPreParse(PreParseAddOperation addOperation)
+      throws CanceledOperationException {
     if (disconnectInternal(addOperation, "PreParse"))
     {
-      return new PreParsePluginResult(true, false, false);
+      addOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreParsePluginResult.SUCCESS;
-    }
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -192,16 +178,10 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult doPreParse(PreParseBindOperation bindOperation)
+  public PluginResult.PreParse doPreParse(PreParseBindOperation bindOperation)
   {
-    if (disconnectInternal(bindOperation, "PreParse"))
-    {
-      return new PreParsePluginResult(true, false, false);
-    }
-    else
-    {
-      return PreParsePluginResult.SUCCESS;
-    }
+    disconnectInternal(bindOperation, "PreParse");
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -210,17 +190,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseCompareOperation compareOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(compareOperation, "PreParse"))
     {
-      return new PreParsePluginResult(true, false, false);
+      compareOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreParsePluginResult.SUCCESS;
-    }
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -229,17 +206,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseDeleteOperation deleteOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(deleteOperation, "PreParse"))
     {
-      return new PreParsePluginResult(true, false, false);
+      deleteOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreParsePluginResult.SUCCESS;
-    }
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -248,17 +222,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseExtendedOperation extendedOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(extendedOperation, "PreParse"))
     {
-      return new PreParsePluginResult(true, false, false);
+      extendedOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreParsePluginResult.SUCCESS;
-    }
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -267,17 +238,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseModifyOperation modifyOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(modifyOperation, "PreParse"))
     {
-      return new PreParsePluginResult(true, false, false);
+      modifyOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreParsePluginResult.SUCCESS;
-    }
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -286,17 +254,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseModifyDNOperation modifyDNOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(modifyDNOperation, "PreParse"))
     {
-      return new PreParsePluginResult(true, false, false);
+      modifyDNOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreParsePluginResult.SUCCESS;
-    }
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -305,17 +270,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseSearchOperation searchOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(searchOperation, "PreParse"))
     {
-      return new PreParsePluginResult(true, false, false);
+      searchOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreParsePluginResult.SUCCESS;
-    }
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -324,17 +286,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseUnbindOperation unbindOperation)
   {
-    if (disconnectInternal(unbindOperation, "PreParse"))
-    {
-      return new PreParsePluginResult(true, false, false);
-    }
-    else
-    {
-      return PreParsePluginResult.SUCCESS;
-    }
+    disconnectInternal(unbindOperation, "PreParse");
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -343,17 +299,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationAddOperation addOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(addOperation, "PreOperation"))
     {
-      return new PreOperationPluginResult(true, false, false);
+      addOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreOperationPluginResult.SUCCESS;
-    }
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -362,17 +315,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationBindOperation bindOperation)
   {
-    if (disconnectInternal(bindOperation, "PreOperation"))
-    {
-      return new PreOperationPluginResult(true, false, false);
-    }
-    else
-    {
-      return PreOperationPluginResult.SUCCESS;
-    }
+    disconnectInternal(bindOperation, "PreOperation");
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -381,17 +328,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationCompareOperation compareOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(compareOperation, "PreOperation"))
     {
-      return new PreOperationPluginResult(true, false, false);
+      compareOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreOperationPluginResult.SUCCESS;
-    }
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -400,17 +344,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationDeleteOperation deleteOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(deleteOperation, "PreOperation"))
     {
-      return new PreOperationPluginResult(true, false, false);
+      deleteOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreOperationPluginResult.SUCCESS;
-    }
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -419,17 +360,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationExtendedOperation extendedOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(extendedOperation, "PreOperation"))
     {
-      return new PreOperationPluginResult(true, false, false);
+      extendedOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreOperationPluginResult.SUCCESS;
-    }
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -438,17 +376,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationModifyOperation modifyOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(modifyOperation, "PreOperation"))
     {
-      return new PreOperationPluginResult(true, false, false);
+      modifyOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreOperationPluginResult.SUCCESS;
-    }
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -457,17 +392,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationModifyDNOperation modifyDNOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(modifyDNOperation, "PreOperation"))
     {
-      return new PreOperationPluginResult(true, false, false);
+      modifyDNOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreOperationPluginResult.SUCCESS;
-    }
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -476,17 +408,14 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationSearchOperation searchOperation)
-  {
+       throws CanceledOperationException {
     if (disconnectInternal(searchOperation, "PreOperation"))
     {
-      return new PreOperationPluginResult(true, false, false);
+      searchOperation.checkIfCanceled(false);
     }
-    else
-    {
-      return PreOperationPluginResult.SUCCESS;
-    }
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -495,17 +424,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationAbandonOperation abandonOperation)
   {
-    if (disconnectInternal(abandonOperation, "PreOperation"))
-    {
-      return new PostOperationPluginResult(true, false);
-    }
-    else
-    {
-      return PostOperationPluginResult.SUCCESS;
-    }
+    disconnectInternal(abandonOperation, "PostOperation");
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -514,17 +437,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationAddOperation addOperation)
   {
-    if (disconnectInternal(addOperation, "PostOperation"))
-    {
-      return new PostOperationPluginResult(true, false);
-    }
-    else
-    {
-      return PostOperationPluginResult.SUCCESS;
-    }
+    disconnectInternal(addOperation, "PostOperation");
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -533,17 +450,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationBindOperation bindOperation)
   {
-    if (disconnectInternal(bindOperation, "PostOperation"))
-    {
-      return new PostOperationPluginResult(true, false);
-    }
-    else
-    {
-      return PostOperationPluginResult.SUCCESS;
-    }
+    disconnectInternal(bindOperation, "PostOperation");
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -552,17 +463,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationCompareOperation compareOperation)
   {
-    if (disconnectInternal(compareOperation, "PostOperation"))
-    {
-      return new PostOperationPluginResult(true, false);
-    }
-    else
-    {
-      return PostOperationPluginResult.SUCCESS;
-    }
+    disconnectInternal(compareOperation, "PostOperation");
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -571,17 +476,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationDeleteOperation deleteOperation)
   {
-    if (disconnectInternal(deleteOperation, "PostOperation"))
-    {
-      return new PostOperationPluginResult(true, false);
-    }
-    else
-    {
-      return PostOperationPluginResult.SUCCESS;
-    }
+    disconnectInternal(deleteOperation, "PostOperation");
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -590,17 +489,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationExtendedOperation extendedOperation)
   {
-    if (disconnectInternal(extendedOperation, "PostOperation"))
-    {
-      return new PostOperationPluginResult(true, false);
-    }
-    else
-    {
-      return PostOperationPluginResult.SUCCESS;
-    }
+    disconnectInternal(extendedOperation, "PostOperation");
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -609,17 +502,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationModifyOperation modifyOperation)
   {
-    if (disconnectInternal(modifyOperation, "PostOperation"))
-    {
-      return new PostOperationPluginResult(true, false);
-    }
-    else
-    {
-      return PostOperationPluginResult.SUCCESS;
-    }
+    disconnectInternal(modifyOperation, "PostOperation");
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -628,17 +515,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationModifyDNOperation modifyDNOperation)
   {
-    if (disconnectInternal(modifyDNOperation, "PostOperation"))
-    {
-      return new PostOperationPluginResult(true, false);
-    }
-    else
-    {
-      return PostOperationPluginResult.SUCCESS;
-    }
+    disconnectInternal(modifyDNOperation, "PostOperation");
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -647,17 +528,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationSearchOperation searchOperation)
   {
-    if (disconnectInternal(searchOperation, "PostOperation"))
-    {
-      return new PostOperationPluginResult(true, false);
-    }
-    else
-    {
-      return PostOperationPluginResult.SUCCESS;
-    }
+    disconnectInternal(searchOperation, "PostOperation");
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -666,17 +541,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationUnbindOperation unbindOperation)
   {
-    if (disconnectInternal(unbindOperation, "PostOperation"))
-    {
-      return new PostOperationPluginResult(true, false);
-    }
-    else
-    {
-      return PostOperationPluginResult.SUCCESS;
-    }
+    disconnectInternal(unbindOperation, "PostOperation");
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -685,17 +554,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseAddOperation addOperation)
   {
-    if (disconnectInternal(addOperation, "PostResponse"))
-    {
-      return new PostResponsePluginResult(true, false);
-    }
-    else
-    {
-      return PostResponsePluginResult.SUCCESS;
-    }
+    disconnectInternal(addOperation, "PostResponse");
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -704,17 +567,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseBindOperation bindOperation)
   {
-    if (disconnectInternal(bindOperation, "PostResponse"))
-    {
-      return new PostResponsePluginResult(true, false);
-    }
-    else
-    {
-      return PostResponsePluginResult.SUCCESS;
-    }
+    disconnectInternal(bindOperation, "PostResponse");
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -723,17 +580,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseCompareOperation compareOperation)
   {
-    if (disconnectInternal(compareOperation, "PostResponse"))
-    {
-      return new PostResponsePluginResult(true, false);
-    }
-    else
-    {
-      return PostResponsePluginResult.SUCCESS;
-    }
+    disconnectInternal(compareOperation, "PostResponse");
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -742,17 +593,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseDeleteOperation deleteOperation)
   {
-    if (disconnectInternal(deleteOperation, "PostResponse"))
-    {
-      return new PostResponsePluginResult(true, false);
-    }
-    else
-    {
-      return PostResponsePluginResult.SUCCESS;
-    }
+    disconnectInternal(deleteOperation, "PostResponse");
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -761,17 +606,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseExtendedOperation extendedOperation)
   {
-    if (disconnectInternal(extendedOperation, "PostResponse"))
-    {
-      return new PostResponsePluginResult(true, false);
-    }
-    else
-    {
-      return PostResponsePluginResult.SUCCESS;
-    }
+    disconnectInternal(extendedOperation, "PostResponse");
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -780,17 +619,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseModifyOperation modifyOperation)
   {
-    if (disconnectInternal(modifyOperation, "PostResponse"))
-    {
-      return new PostResponsePluginResult(true, false);
-    }
-    else
-    {
-      return PostResponsePluginResult.SUCCESS;
-    }
+    disconnectInternal(modifyOperation, "PostResponse");
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -799,17 +632,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseModifyDNOperation modifyDNOperation)
   {
-    if (disconnectInternal(modifyDNOperation, "PostResponse"))
-    {
-      return new PostResponsePluginResult(true, false);
-    }
-    else
-    {
-      return PostResponsePluginResult.SUCCESS;
-    }
+    disconnectInternal(modifyDNOperation, "PostResponse");
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -818,17 +645,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseSearchOperation searchOperation)
   {
-    if (disconnectInternal(searchOperation, "PostResponse"))
-    {
-      return new PostResponsePluginResult(true, false);
-    }
-    else
-    {
-      return PostResponsePluginResult.SUCCESS;
-    }
+    disconnectInternal(searchOperation, "PostResponse");
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/InvocationCounterPlugin.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/InvocationCounterPlugin.java
index 5c686ee..898c8e2 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/InvocationCounterPlugin.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/InvocationCounterPlugin.java
@@ -34,20 +34,7 @@
 
 import org.opends.server.admin.std.server.PluginCfg;
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.plugin.DirectoryServerPlugin;
-import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.IntermediateResponsePluginResult;
-import org.opends.server.api.plugin.LDIFPluginResult;
-import org.opends.server.api.plugin.PostConnectPluginResult;
-import org.opends.server.api.plugin.PostDisconnectPluginResult;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PostResponsePluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
-import org.opends.server.api.plugin.PreParsePluginResult;
-import org.opends.server.api.plugin.SearchEntryPluginResult;
-import org.opends.server.api.plugin.SearchReferencePluginResult;
-import org.opends.server.api.plugin.StartupPluginResult;
-import org.opends.server.api.plugin.SubordinateModifyDNPluginResult;
+import org.opends.server.api.plugin.*;
 import org.opends.server.types.DisconnectReason;
 import org.opends.server.types.Entry;
 import org.opends.server.types.IntermediateResponse;
@@ -136,11 +123,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseAbandonOperation abandonOperation)
   {
     preParseCounter.incrementAndGet();
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -149,10 +136,10 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult doPreParse(PreParseAddOperation addOperation)
+  public PluginResult.PreParse doPreParse(PreParseAddOperation addOperation)
   {
     preParseCounter.incrementAndGet();
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -161,10 +148,10 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult doPreParse(PreParseBindOperation bindOperation)
+  public PluginResult.PreParse doPreParse(PreParseBindOperation bindOperation)
   {
     preParseCounter.incrementAndGet();
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -173,11 +160,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseCompareOperation compareOperation)
   {
     preParseCounter.incrementAndGet();
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -186,11 +173,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseDeleteOperation deleteOperation)
   {
     preParseCounter.incrementAndGet();
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -199,11 +186,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseExtendedOperation extendedOperation)
   {
     preParseCounter.incrementAndGet();
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -212,11 +199,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseModifyOperation modifyOperation)
   {
     preParseCounter.incrementAndGet();
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -225,11 +212,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseModifyDNOperation modifyDNOperation)
   {
     preParseCounter.incrementAndGet();
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -238,11 +225,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseSearchOperation searchOperation)
   {
     preParseCounter.incrementAndGet();
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -251,11 +238,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseUnbindOperation unbindOperation)
   {
     preParseCounter.incrementAndGet();
-    return PreParsePluginResult.SUCCESS;
+    return PluginResult.PreParse.continueOperationProcessing();
   }
 
 
@@ -290,11 +277,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationAddOperation addOperation)
   {
     preOperationCounter.incrementAndGet();
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -303,11 +290,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationBindOperation bindOperation)
   {
     preOperationCounter.incrementAndGet();
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -316,11 +303,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationCompareOperation compareOperation)
   {
     preOperationCounter.incrementAndGet();
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -329,11 +316,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationDeleteOperation deleteOperation)
   {
     preOperationCounter.incrementAndGet();
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -342,11 +329,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationExtendedOperation extendedOperation)
   {
     preOperationCounter.incrementAndGet();
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -355,11 +342,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationModifyOperation modifyOperation)
   {
     preOperationCounter.incrementAndGet();
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -368,11 +355,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationModifyDNOperation modifyDNOperation)
   {
     preOperationCounter.incrementAndGet();
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -381,11 +368,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationSearchOperation searchOperation)
   {
     preOperationCounter.incrementAndGet();
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -420,11 +407,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationAbandonOperation abandonOperation)
   {
     postOperationCounter.incrementAndGet();
-    return PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -433,11 +420,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationAddOperation addOperation)
   {
     postOperationCounter.incrementAndGet();
-    return PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -446,11 +433,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationBindOperation bindOperation)
   {
     postOperationCounter.incrementAndGet();
-    return PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -459,11 +446,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationCompareOperation compareOperation)
   {
     postOperationCounter.incrementAndGet();
-    return PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -472,11 +459,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationDeleteOperation deleteOperation)
   {
     postOperationCounter.incrementAndGet();
-    return PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -485,11 +472,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationExtendedOperation extendedOperation)
   {
     postOperationCounter.incrementAndGet();
-    return PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -498,11 +485,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationModifyOperation modifyOperation)
   {
     postOperationCounter.incrementAndGet();
-    return PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -511,11 +498,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationModifyDNOperation modifyDNOperation)
   {
     postOperationCounter.incrementAndGet();
-    return PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -524,11 +511,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationSearchOperation searchOperation)
   {
     postOperationCounter.incrementAndGet();
-    return PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -537,11 +524,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostOperationPluginResult
+  public PluginResult.PostOperation
        doPostOperation(PostOperationUnbindOperation unbindOperation)
   {
     postOperationCounter.incrementAndGet();
-    return PostOperationPluginResult.SUCCESS;
+    return PluginResult.PostOperation.continueOperationProcessing();
   }
 
 
@@ -576,11 +563,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseAddOperation addOperation)
   {
     postResponseCounter.incrementAndGet();
-    return PostResponsePluginResult.SUCCESS;
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -589,11 +576,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseBindOperation bindOperation)
   {
     postResponseCounter.incrementAndGet();
-    return PostResponsePluginResult.SUCCESS;
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -602,11 +589,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseCompareOperation compareOperation)
   {
     postResponseCounter.incrementAndGet();
-    return PostResponsePluginResult.SUCCESS;
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -615,11 +602,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseDeleteOperation deleteOperation)
   {
     postResponseCounter.incrementAndGet();
-    return PostResponsePluginResult.SUCCESS;
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -628,11 +615,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseExtendedOperation extendedOperation)
   {
     postResponseCounter.incrementAndGet();
-    return PostResponsePluginResult.SUCCESS;
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -641,11 +628,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseModifyOperation modifyOperation)
   {
     postResponseCounter.incrementAndGet();
-    return PostResponsePluginResult.SUCCESS;
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -654,11 +641,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseModifyDNOperation modifyDNOperation)
   {
     postResponseCounter.incrementAndGet();
-    return PostResponsePluginResult.SUCCESS;
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -667,11 +654,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostResponsePluginResult
+  public PluginResult.PostResponse
        doPostResponse(PostResponseSearchOperation searchOperation)
   {
     postResponseCounter.incrementAndGet();
-    return PostResponsePluginResult.SUCCESS;
+    return PluginResult.PostResponse.continueOperationProcessing();
   }
 
 
@@ -769,12 +756,12 @@
    * {@inheritDoc}
    */
   @Override()
-  public SearchEntryPluginResult
+  public PluginResult.IntermediateResponse
        processSearchEntry(SearchEntrySearchOperation searchOperation,
                           SearchResultEntry searchEntry)
   {
     searchEntryCounter.incrementAndGet();
-    return SearchEntryPluginResult.SUCCESS;
+    return PluginResult.IntermediateResponse.continueOperationProcessing(true);
   }
 
 
@@ -810,12 +797,12 @@
    * {@inheritDoc}
    */
   @Override()
-  public SearchReferencePluginResult
+  public PluginResult.IntermediateResponse
        processSearchReference(SearchReferenceSearchOperation searchOperation,
                               SearchResultReference searchReference)
   {
     searchReferenceCounter.incrementAndGet();
-    return SearchReferencePluginResult.SUCCESS;
+    return PluginResult.IntermediateResponse.continueOperationProcessing(true);
   }
 
 
@@ -851,12 +838,12 @@
    * {@inheritDoc}
    */
   @Override()
-  public SubordinateModifyDNPluginResult processSubordinateModifyDN(
+  public PluginResult.SubordinateModifyDN processSubordinateModifyDN(
               SubordinateModifyDNOperation modifyDNOperation, Entry oldEntry,
               Entry newEntry, List<Modification> modifications)
   {
     subordinateModifyDNCounter.incrementAndGet();
-    return SubordinateModifyDNPluginResult.SUCCESS;
+    return PluginResult.SubordinateModifyDN.continueOperationProcessing();
   }
 
 
@@ -893,11 +880,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public IntermediateResponsePluginResult processIntermediateResponse(
+  public PluginResult.IntermediateResponse processIntermediateResponse(
               IntermediateResponse intermediateResponse)
   {
     intermediateResponseCounter.incrementAndGet();
-    return IntermediateResponsePluginResult.SUCCESS;
+    return PluginResult.IntermediateResponse.continueOperationProcessing(true);
   }
 
 
@@ -933,11 +920,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostConnectPluginResult doPostConnect(ClientConnection
+  public PluginResult.PostConnect doPostConnect(ClientConnection
                                                     clientConnection)
   {
     postConnectCounter.incrementAndGet();
-    return PostConnectPluginResult.SUCCESS;
+    return PluginResult.PostConnect.continueConnectProcessing();
   }
 
 
@@ -972,12 +959,12 @@
    * {@inheritDoc}
    */
   @Override()
-  public PostDisconnectPluginResult doPostDisconnect(
+  public PluginResult.PostDisconnect doPostDisconnect(
           ClientConnection clientConnection, DisconnectReason disconnectReason,
           Message message)
   {
     postDisconnectCounter.incrementAndGet();
-    return PostDisconnectPluginResult.SUCCESS;
+    return PluginResult.PostDisconnect.continueDisconnectProcessing();
   }
 
 
@@ -1012,11 +999,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public LDIFPluginResult doLDIFImport(LDIFImportConfig importConfig,
-                                       Entry entry)
+  public PluginResult.ImportLDIF doLDIFImport(LDIFImportConfig importConfig,
+                                        Entry entry)
   {
     ldifImportCounter.incrementAndGet();
-    return LDIFPluginResult.SUCCESS;
+    return PluginResult.ImportLDIF.continueEntryProcessing();
   }
 
 
@@ -1051,11 +1038,11 @@
    * {@inheritDoc}
    */
   @Override()
-  public LDIFPluginResult doLDIFExport(LDIFExportConfig exportConfig,
+  public PluginResult.ImportLDIF doLDIFExport(LDIFExportConfig exportConfig,
                                        Entry entry)
   {
     ldifExportCounter.incrementAndGet();
-    return LDIFPluginResult.SUCCESS;
+    return PluginResult.ImportLDIF.continueEntryProcessing();
   }
 
 
@@ -1113,10 +1100,10 @@
    * {@inheritDoc}
    */
   @Override()
-  public StartupPluginResult doStartup()
+  public PluginResult.Startup doStartup()
   {
     startupCalled = true;
-    return StartupPluginResult.SUCCESS;
+    return PluginResult.Startup.continueStartup();
   }
 
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/NullPlugin.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/NullPlugin.java
index c6d3e96..4a178a1 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/NullPlugin.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/NullPlugin.java
@@ -28,21 +28,11 @@
 
 
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Set;
 
 import org.opends.server.admin.std.server.PluginCfg;
 import org.opends.server.api.plugin.DirectoryServerPlugin;
 import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PreOperationPluginResult;
-import org.opends.server.config.ConfigException;
-import org.opends.server.protocols.asn1.ASN1Long;
-import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.protocols.ldap.LDAPControl;
-import org.opends.server.types.Control;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.operation.*;
 
 
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/SevenBitCleanPluginTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/SevenBitCleanPluginTestCase.java
index f319afe..54b9a10 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/SevenBitCleanPluginTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/SevenBitCleanPluginTestCase.java
@@ -32,6 +32,7 @@
 import org.testng.annotations.Test;
 
 import org.opends.server.TestCaseUtils;
+import org.opends.server.types.ResultCode;
 import org.opends.server.core.AddOperation;
 import org.opends.server.core.ModifyOperation;
 import org.opends.server.core.ModifyDNOperation;
@@ -248,8 +249,8 @@
         "-f", path
       };
 
-      assertFalse(LDAPModify.mainModify(args, false, System.out, System.err) ==
-                  0);
+      assertEquals(LDAPModify.mainModify(args, false, System.out, System.err),
+                  ResultCode.CONSTRAINT_VIOLATION.getIntValue());
     }
     finally
     {
@@ -413,8 +414,8 @@
         "-f", path
       };
 
-      assertFalse(LDAPModify.mainModify(args, false, System.out, System.err) ==
-                  0);
+      assertEquals(LDAPModify.mainModify(args, false, System.out, System.err),
+                  ResultCode.CONSTRAINT_VIOLATION.getIntValue());
     }
     finally
     {
@@ -641,8 +642,8 @@
         "-f", path
       };
 
-      assertFalse(LDAPModify.mainModify(args, false, System.out, System.err) ==
-                  0);
+      assertEquals(LDAPModify.mainModify(args, false, System.out, System.err),
+                  ResultCode.CONSTRAINT_VIOLATION.getIntValue());
     }
     finally
     {
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/ShortCircuitPlugin.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/ShortCircuitPlugin.java
index a859ce2..3e5da05 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/ShortCircuitPlugin.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/ShortCircuitPlugin.java
@@ -35,11 +35,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.opends.server.admin.std.server.PluginCfg;
-import org.opends.server.api.plugin.DirectoryServerPlugin;
-import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PreOperationPluginResult;
-import org.opends.server.api.plugin.PreParsePluginResult;
-import org.opends.server.config.ConfigEntry;
+import org.opends.server.api.plugin.*;
 import org.opends.server.config.ConfigException;
 import org.opends.server.protocols.asn1.ASN1Element;
 import org.opends.server.protocols.asn1.ASN1Enumerated;
@@ -132,20 +128,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
-       doPreParse(PreParseAbandonOperation abandonOperation)
+  public PluginResult.PreParse
+         doPreParse(PreParseAbandonOperation abandonOperation)
   {
     int resultCode = shortCircuitInternal(abandonOperation, "PreParse");
     if (resultCode >= 0)
     {
-      abandonOperation.setResultCode(ResultCode.valueOf(resultCode));
-      abandonOperation.appendErrorMessage(
-              Message.raw("Short-circuit in pre-parse"));
-      return new PreParsePluginResult(false, false, true);
+      return PluginResult.PreParse.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-parse"));
     }
     else
     {
-      return PreParsePluginResult.SUCCESS;
+      return PluginResult.PreParse.continueOperationProcessing();
     }
   }
 
@@ -155,18 +150,18 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult doPreParse(PreParseAddOperation addOperation)
+  public PluginResult.PreParse doPreParse(PreParseAddOperation addOperation)
   {
     int resultCode = shortCircuitInternal(addOperation, "PreParse");
     if (resultCode >= 0)
     {
-      addOperation.setResultCode(ResultCode.valueOf(resultCode));
-      addOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreParsePluginResult(false, false, true);
+      return PluginResult.PreParse.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-parse"));
     }
     else
     {
-      return PreParsePluginResult.SUCCESS;
+      return PluginResult.PreParse.continueOperationProcessing();
     }
   }
 
@@ -176,18 +171,18 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult doPreParse(PreParseBindOperation bindOperation)
+  public PluginResult.PreParse doPreParse(PreParseBindOperation bindOperation)
   {
     int resultCode = shortCircuitInternal(bindOperation, "PreParse");
     if (resultCode >= 0)
     {
-      bindOperation.setResultCode(ResultCode.valueOf(resultCode));
-      bindOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreParsePluginResult(false, false, true);
+      return PluginResult.PreParse.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-parse"));
     }
     else
     {
-      return PreParsePluginResult.SUCCESS;
+      return PluginResult.PreParse.continueOperationProcessing();
     }
   }
 
@@ -197,19 +192,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseCompareOperation compareOperation)
   {
     int resultCode = shortCircuitInternal(compareOperation, "PreParse");
     if (resultCode >= 0)
     {
-      compareOperation.setResultCode(ResultCode.valueOf(resultCode));
-      compareOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreParsePluginResult(false, false, true);
+      return PluginResult.PreParse.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-parse"));
     }
     else
     {
-      return PreParsePluginResult.SUCCESS;
+      return PluginResult.PreParse.continueOperationProcessing();
     }
   }
 
@@ -219,19 +214,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseDeleteOperation deleteOperation)
   {
     int resultCode = shortCircuitInternal(deleteOperation, "PreParse");
     if (resultCode >= 0)
     {
-      deleteOperation.setResultCode(ResultCode.valueOf(resultCode));
-      deleteOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreParsePluginResult(false, false, true);
+      return PluginResult.PreParse.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-parse"));
     }
     else
     {
-      return PreParsePluginResult.SUCCESS;
+      return PluginResult.PreParse.continueOperationProcessing();
     }
   }
 
@@ -241,19 +236,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseExtendedOperation extendedOperation)
   {
     int resultCode = shortCircuitInternal(extendedOperation, "PreParse");
     if (resultCode >= 0)
     {
-      extendedOperation.setResultCode(ResultCode.valueOf(resultCode));
-      extendedOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreParsePluginResult(false, false, true);
+      return PluginResult.PreParse.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-parse"));
     }
     else
     {
-      return PreParsePluginResult.SUCCESS;
+      return PluginResult.PreParse.continueOperationProcessing();
     }
   }
 
@@ -263,19 +258,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseModifyOperation modifyOperation)
   {
     int resultCode = shortCircuitInternal(modifyOperation, "PreParse");
     if (resultCode >= 0)
     {
-      modifyOperation.setResultCode(ResultCode.valueOf(resultCode));
-      modifyOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreParsePluginResult(false, false, true);
+      return PluginResult.PreParse.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-parse"));
     }
     else
     {
-      return PreParsePluginResult.SUCCESS;
+      return PluginResult.PreParse.continueOperationProcessing();
     }
   }
 
@@ -285,19 +280,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseModifyDNOperation modifyDNOperation)
   {
     int resultCode = shortCircuitInternal(modifyDNOperation, "PreParse");
     if (resultCode >= 0)
     {
-      modifyDNOperation.setResultCode(ResultCode.valueOf(resultCode));
-      modifyDNOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreParsePluginResult(false, false, true);
+      return PluginResult.PreParse.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-parse"));
     }
     else
     {
-      return PreParsePluginResult.SUCCESS;
+      return PluginResult.PreParse.continueOperationProcessing();
     }
   }
 
@@ -307,19 +302,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseSearchOperation searchOperation)
   {
     int resultCode = shortCircuitInternal(searchOperation, "PreParse");
     if (resultCode >= 0)
     {
-      searchOperation.setResultCode(ResultCode.valueOf(resultCode));
-      searchOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreParsePluginResult(false, false, true);
+      return PluginResult.PreParse.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-parse"));
     }
     else
     {
-      return PreParsePluginResult.SUCCESS;
+      return PluginResult.PreParse.continueOperationProcessing();
     }
   }
 
@@ -329,19 +324,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreParsePluginResult
+  public PluginResult.PreParse
        doPreParse(PreParseUnbindOperation unbindOperation)
   {
     int resultCode = shortCircuitInternal(unbindOperation, "PreParse");
     if (resultCode >= 0)
     {
-      unbindOperation.setResultCode(ResultCode.valueOf(resultCode));
-      unbindOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreParsePluginResult(false, false, true);
+      return PluginResult.PreParse.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-parse"));
     }
     else
     {
-      return PreParsePluginResult.SUCCESS;
+      return PluginResult.PreParse.continueOperationProcessing();
     }
   }
 
@@ -351,19 +346,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationAddOperation addOperation)
   {
     int resultCode = shortCircuitInternal(addOperation, "PreOperation");
     if (resultCode >= 0)
     {
-      addOperation.setResultCode(ResultCode.valueOf(resultCode));
-      addOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreOperationPluginResult(false, false, true);
+      return PluginResult.PreOperation.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-operation"));
     }
     else
     {
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
   }
 
@@ -373,19 +368,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationBindOperation bindOperation)
   {
     int resultCode = shortCircuitInternal(bindOperation, "PreOperation");
     if (resultCode >= 0)
     {
-      bindOperation.setResultCode(ResultCode.valueOf(resultCode));
-      bindOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreOperationPluginResult(false, false, true);
+      return PluginResult.PreOperation.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-operation"));
     }
     else
     {
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
   }
 
@@ -395,19 +390,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationCompareOperation compareOperation)
   {
     int resultCode = shortCircuitInternal(compareOperation, "PreOperation");
     if (resultCode >= 0)
     {
-      compareOperation.setResultCode(ResultCode.valueOf(resultCode));
-      compareOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreOperationPluginResult(false, false, true);
+      return PluginResult.PreOperation.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-operation"));
     }
     else
     {
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
   }
 
@@ -417,19 +412,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationDeleteOperation deleteOperation)
   {
     int resultCode = shortCircuitInternal(deleteOperation, "PreOperation");
     if (resultCode >= 0)
     {
-      deleteOperation.setResultCode(ResultCode.valueOf(resultCode));
-      deleteOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreOperationPluginResult(false, false, true);
+      return PluginResult.PreOperation.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-operation"));
     }
     else
     {
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
   }
 
@@ -439,19 +434,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationExtendedOperation extendedOperation)
   {
     int resultCode = shortCircuitInternal(extendedOperation, "PreOperation");
     if (resultCode >= 0)
     {
-      extendedOperation.setResultCode(ResultCode.valueOf(resultCode));
-      extendedOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreOperationPluginResult(false, false, true);
+      return PluginResult.PreOperation.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-operation"));
     }
     else
     {
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
   }
 
@@ -461,19 +456,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationModifyOperation modifyOperation)
   {
     int resultCode = shortCircuitInternal(modifyOperation, "PreOperation");
     if (resultCode >= 0)
     {
-      modifyOperation.setResultCode(ResultCode.valueOf(resultCode));
-      modifyOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreOperationPluginResult(false, false, true);
+      return PluginResult.PreOperation.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-operation"));
     }
     else
     {
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
   }
 
@@ -483,19 +478,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationModifyDNOperation modifyDNOperation)
   {
     int resultCode = shortCircuitInternal(modifyDNOperation, "PreOperation");
     if (resultCode >= 0)
     {
-      modifyDNOperation.setResultCode(ResultCode.valueOf(resultCode));
-      modifyDNOperation.appendErrorMessage(Message.raw("Short-circuit in pre-parse"));
-      return new PreOperationPluginResult(false, false, true);
+      return PluginResult.PreOperation.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-operation"));
     }
     else
     {
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
   }
 
@@ -505,20 +500,19 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationSearchOperation searchOperation)
   {
     int resultCode = shortCircuitInternal(searchOperation, "PreOperation");
     if (resultCode >= 0)
     {
-      searchOperation.setResultCode(ResultCode.valueOf(resultCode));
-      searchOperation.appendErrorMessage(
-              Message.raw("Short-circuit in pre-parse"));
-      return new PreOperationPluginResult(false, false, true);
+      return PluginResult.PreOperation.stopProcessing(
+          ResultCode.valueOf(resultCode),
+          Message.raw("Short-circuit in pre-operation"));
     }
     else
     {
-      return PreOperationPluginResult.SUCCESS;
+      return PluginResult.PreOperation.continueOperationProcessing();
     }
   }
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/UpdatePreOpPlugin.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/UpdatePreOpPlugin.java
index c5d22b1..c879c50 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/UpdatePreOpPlugin.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/UpdatePreOpPlugin.java
@@ -29,13 +29,12 @@
 
 
 import java.util.ArrayList;
-import java.util.List;
 import java.util.Set;
 
 import org.opends.server.admin.std.server.PluginCfg;
 import org.opends.server.api.plugin.DirectoryServerPlugin;
 import org.opends.server.api.plugin.PluginType;
-import org.opends.server.api.plugin.PreOperationPluginResult;
+import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.config.ConfigException;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.AttributeType;
@@ -135,7 +134,7 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationAddOperation addOperation)
   {
     for (AttributeType t : removeAttributes)
@@ -160,7 +159,7 @@
       addOperation.addObjectClass(oc, oc.getPrimaryName());
     }
 
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
@@ -169,7 +168,7 @@
    * {@inheritDoc}
    */
   @Override()
-  public PreOperationPluginResult
+  public PluginResult.PreOperation
        doPreOperation(PreOperationModifyOperation modifyOperation)
   {
     for (Modification m : modifications)
@@ -180,12 +179,12 @@
       }
       catch (DirectoryException de)
       {
-        modifyOperation.setResponseData(de);
-        return new PreOperationPluginResult(false, false, true);
+        return PluginResult.PreOperation.stopProcessing(de.getResultCode(),
+            de.getMessageObject(), de.getMatchedDN(), de.getReferralURLs());
       }
     }
 
-    return PreOperationPluginResult.SUCCESS;
+    return PluginResult.PreOperation.continueOperationProcessing();
   }
 
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
index 1c9dabc..fbb61e0 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
@@ -1118,7 +1118,7 @@
     CancelResult cancelResult =
          conn.cancelOperation(1,
               new CancelRequest(true, Message.raw("testCancelOperation")));
-    assertEquals(cancelResult, CancelResult.CANNOT_CANCEL);
+    assertEquals(cancelResult.getResultCode(), ResultCode.CANNOT_CANCEL);
   }
 
 

--
Gitblit v1.10.0