mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

matthew_swift
28.33.2009 d80f86a08f6955e0c623a80357c8481b38e92d61
Fix issue 4043 - intermittent failures in ACI unit tests

Introduce API for registering internal plugins which are not exposed in the user configuration. Update ACI cache to use a post-op plugin instead of a change listener.
1 files added
5 files modified
2016 ■■■■■ changed files
opends/src/server/org/opends/server/api/plugin/DirectoryServerPlugin.java 23 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/plugin/InternalDirectoryServerPlugin.java 96 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java 706 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/DirectoryServer.java 64 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/PluginConfigManager.java 1118 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/DirectoryServerPluginTestCase.java 9 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/plugin/DirectoryServerPlugin.java
@@ -111,26 +111,29 @@
  /**
   * Performs any initialization that should be done for all types of
   * plugins regardless of type.  This should only be called by the
   * plugins regardless of type. This should only be called by the
   * core Directory Server code during the course of loading a plugin.
   *
   * @param  configuration  The configuration for this plugin.
   * @param  pluginTypes    The set of plugin types for which this
   *                        plugin is registered.
   * @param pluginDN
   *          The configuration entry name of this plugin.
   * @param pluginTypes
   *          The set of plugin types for which this plugin is
   *          registered.
   * @param invokeForInternalOps
   *          Indicates whether this plugin should be invoked for
   *          internal operations.
   */
  @org.opends.server.types.PublicAPI(
       stability=org.opends.server.types.StabilityLevel.PRIVATE,
       mayInstantiate=false,
       mayExtend=false,
       mayInvoke=false)
  public final void initializeInternal(PluginCfg configuration,
                                       Set<PluginType> pluginTypes)
  public final void initializeInternal(DN pluginDN,
      Set<PluginType> pluginTypes, boolean invokeForInternalOps)
  {
    this.pluginDN = pluginDN;
    this.pluginTypes = pluginTypes;
    pluginDN = configuration.dn();
    invokeForInternalOps =
         configuration.isInvokeForInternalOperations();
    this.invokeForInternalOps = invokeForInternalOps;
  }
opends/src/server/org/opends/server/api/plugin/InternalDirectoryServerPlugin.java
New file
@@ -0,0 +1,96 @@
/*
 * 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 2009 Sun Microsystems, Inc.
 */
package org.opends.server.api.plugin;
import java.util.List;
import java.util.Set;
import org.opends.messages.Message;
import org.opends.server.admin.std.server.PluginCfg;
import org.opends.server.config.ConfigException;
import org.opends.server.types.DN;
import org.opends.server.types.InitializationException;
/**
 * An internal directory server plugin which can be registered with
 * the server without requiring any associated configuration.
 */
public abstract class InternalDirectoryServerPlugin extends
    DirectoryServerPlugin<PluginCfg>
{
  /**
   * Creates a new internal directory server plugin using the provided
   * component name and plugin types.
   *
   * @param componentDN
   *          The configuration entry name of the component associated
   *          with this internal plugin.
   * @param pluginTypes
   *          The set of plugin types for which this internal plugin
   *          is registered.
   * @param invokeForInternalOps
   *          Indicates whether this internal plugin should be invoked
   *          for internal operations.
   */
  protected InternalDirectoryServerPlugin(DN componentDN,
      Set<PluginType> pluginTypes, boolean invokeForInternalOps)
  {
    initializeInternal(componentDN, pluginTypes,
        invokeForInternalOps);
  }
  /**
   * {@inheritDoc}
   */
  public final void initializePlugin(Set<PluginType> pluginTypes,
      PluginCfg configuration) throws ConfigException,
      InitializationException
  {
    // Unused.
  }
  /**
   * {@inheritDoc}
   */
  public final boolean isConfigurationAcceptable(
      PluginCfg configuration, List<Message> unacceptableReasons)
  {
    // Unused.
    return true;
  }
}
opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java
@@ -22,21 +22,27 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 */
package org.opends.server.authorization.dseecompat;
import org.opends.messages.Message;
import org.opends.server.workflowelement.localbackend.*;
import org.opends.server.api.ChangeNotificationListener;
import org.opends.server.api.BackendInitializationListener;
import org.opends.server.api.Backend;
import org.opends.server.api.AlertGenerator;
import org.opends.server.types.operation.PostResponseAddOperation;
import org.opends.server.types.operation.PostResponseDeleteOperation;
import org.opends.server.types.operation.PostResponseModifyOperation;
import org.opends.server.types.operation.PostResponseModifyDNOperation;
import org.opends.server.api.plugin.InternalDirectoryServerPlugin;
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.api.plugin.PluginType;
import org.opends.server.api.plugin.PluginResult.PostOperation;
import org.opends.server.types.operation.PostOperationAddOperation;
import org.opends.server.types.operation.PostOperationDeleteOperation;
import org.opends.server.types.operation.PostOperationModifyDNOperation;
import org.opends.server.types.operation.PostOperationModifyOperation;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPControl;
@@ -44,341 +50,437 @@
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.*;
import static org.opends.messages.AccessControlMessages.*;
import org.opends.server.core.DirectoryServer;
import static org.opends.server.util.ServerConstants.*;
import java.util.*;
/**
 * The AciListenerManager updates an ACI list after each
 * modification operation. Also, updates ACI list when backends are initialized
 * and finalized.
 * The AciListenerManager updates an ACI list after each modification
 * operation. Also, updates ACI list when backends are initialized and
 * finalized.
 */
public class AciListenerManager
        implements ChangeNotificationListener, BackendInitializationListener,
                   AlertGenerator {
public class AciListenerManager implements
    BackendInitializationListener, AlertGenerator
{
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
    /**
     * The fully-qualified name of this class.
     */
    private static final String CLASS_NAME =
         "org.opends.server.authorization.dseecompat.AciListenerManager";
    /*
     *  The configuration DN.
     */
    private DN configurationDN;
  /**
   * The fully-qualified name of this class.
   */
  private static final String CLASS_NAME =
      "org.opends.server.authorization.dseecompat.AciListenerManager";
    /*
     *  True if the server is in lockdown mode.
     */
    private boolean inLockDownMode=false;
    /*
     * The AciList caches the ACIs.
     */
    private AciList aciList;
    /*
     * Search filter used in context search for "aci" attribute types.
     */
    private static SearchFilter aciFilter;
    /*
     * The aci attribute type is operational so we need to specify it to be
     * returned.
     */
    private static LinkedHashSet<String> attrs = new LinkedHashSet<String>();
    static {
        /*
         * Set up the filter used to search private and public contexts.
         */
        try {
            aciFilter=SearchFilter.createFilterFromString("(aci=*)");
        } catch (DirectoryException ex) {
            //TODO should never happen, error message?
        }
        attrs.add("aci");
    }
    /**
     * Save the list created by the AciHandler routine. Registers as an
     * Alert Generator that can send alerts when the server is being put
     * in lockdown  mode. Registers as backend initialization listener that is
     * used to manage the ACI list cache when backends are
     * initialized/finalized. Registers as a change notification listener that
     * is used to manage the ACI list cache after ACI modifications have been
     * performed.
     *
     * @param aciList The list object created and loaded by the handler.
     * @param cfgDN The DN of the access control configuration entry.
     */
    public AciListenerManager(AciList aciList, DN cfgDN) {
        this.aciList=aciList;
        this.configurationDN=cfgDN;
        DirectoryServer.registerChangeNotificationListener(this);
        DirectoryServer.registerBackendInitializationListener(this);
        DirectoryServer.registerAlertGenerator(this);
    }
   /**
    * Deregister from the change notification listener, the backend
    * initialization listener and the alert generator.
    */
    public void finalizeListenerManager() {
        DirectoryServer.deregisterChangeNotificationListener(this);
        DirectoryServer.deregisterBackendInitializationListener(this);
        DirectoryServer.deregisterAlertGenerator(this);
    }
    /**
     * A delete operation succeeded. Remove any ACIs associated with the
     * entry deleted.
     * @param deleteOperation The delete operation.
     * @param entry The entry being deleted.
     */
    public void handleDeleteOperation(PostResponseDeleteOperation
            deleteOperation, Entry entry) {
        boolean hasAci,  hasGlobalAci=false;
        //This entry might have both global and aci attribute types.
        if((hasAci=entry.hasOperationalAttribute(AciHandler.aciType)) ||
                (hasGlobalAci=entry.hasAttribute(AciHandler.globalAciType)))
            aciList.removeAci(entry, hasAci, hasGlobalAci);
    }
    /**
     * An Add operation succeeded. Add any ACIs associated with the
     * entry being added.
     * @param addOperation  The add operation.
     * @param entry   The entry being added.
     */
    public void handleAddOperation(PostResponseAddOperation addOperation,
                                   Entry entry) {
        boolean hasAci, hasGlobalAci=false;
        //Ignore this list, the ACI syntax has already passed and it should be
        //empty.
        LinkedList<Message>failedACIMsgs=new LinkedList<Message>();
        //This entry might have both global and aci attribute types.
        if((hasAci=entry.hasOperationalAttribute(AciHandler.aciType)) ||
                (hasGlobalAci=entry.hasAttribute(AciHandler.globalAciType)))
            aciList.addAci(entry, hasAci, hasGlobalAci, failedACIMsgs);
    }
    /**
     * A modify operation succeeded. Adjust the ACIs by removing
     * ACIs based on the oldEntry and then adding ACIs based on the new
     * entry.
     * @param modOperation  the modify operation.
     * @param oldEntry The old entry to examine.
     * @param newEntry  The new entry to examine.
     */
    public void handleModifyOperation(PostResponseModifyOperation modOperation,
                                      Entry oldEntry, Entry newEntry)
  /**
   * Internal plugin used for updating the cache before a response is
   * sent to the client.
   */
  private final class AciChangeListenerPlugin extends
      InternalDirectoryServerPlugin
  {
    private AciChangeListenerPlugin()
    {
        // A change to the ACI list is expensive so let's first make sure that
        // the modification included changes to the ACI. We'll check for
        //both "aci" attribute types and global "ds-cfg-global-aci" attribute
        //types.
        boolean hasAci = false, hasGlobalAci=false;
        List<Modification> mods = modOperation.getModifications();
        for (Modification mod : mods) {
            AttributeType attributeType=mod.getAttribute().getAttributeType();
            if (attributeType.equals(AciHandler.aciType))
                hasAci = true;
           else if(attributeType.equals(AciHandler.globalAciType))
                hasGlobalAci=true;
            if(hasAci && hasGlobalAci)
               break;
        }
        if (hasAci || hasGlobalAci)
            aciList.modAciOldNewEntry(oldEntry, newEntry, hasAci, hasGlobalAci);
      super(configurationDN, EnumSet.of(PluginType.POST_OPERATION_ADD,
          PluginType.POST_OPERATION_DELETE,
          PluginType.POST_OPERATION_MODIFY,
          PluginType.POST_OPERATION_MODIFY_DN), true);
    }
    /**
     * A modify DN operation has succeeded. Adjust the ACIs by moving ACIs
     * under the old entry DN to the new entry DN.
     * @param modifyDNOperation  The LDAP modify DN operation.
     * @param oldEntry  The old entry.
     * @param newEntry The new entry.
     * {@inheritDoc}
     */
    public void handleModifyDNOperation(
            PostResponseModifyDNOperation modifyDNOperation,
            Entry oldEntry, Entry newEntry)
    public PostOperation doPostOperation(
        PostOperationAddOperation addOperation)
    {
        aciList.renameAci(oldEntry.getDN(), newEntry.getDN());
    }
    /**
     * {@inheritDoc}  In this case, the server will search the backend to find
     * all aci attribute type values that it may contain and add them to the
     * ACI list.
     */
    public void performBackendInitializationProcessing(Backend backend) {
      // Check to make sure that the backend has a presence index defined for
      // the ACI attribute.  If it does not, then log a warning message because
      // this processing could be very expensive.
      AttributeType aciType = DirectoryServer.getAttributeType("aci", true);
      if (backend.getEntryCount() > 0 &&
          ! backend.isIndexed(aciType, IndexType.PRESENCE))
      // This entry might have both global and aci attribute types.
      Entry entry = addOperation.getEntryToAdd();
      boolean hasAci, hasGlobalAci = false;
      if ((hasAci = entry.hasOperationalAttribute(AciHandler.aciType))
          || (hasGlobalAci =
              entry.hasAttribute(AciHandler.globalAciType)))
      {
        logError(WARN_ACI_ATTRIBUTE_NOT_INDEXED.get(backend.getBackendID(),
                                                    "aci"));
        // Ignore this list, the ACI syntax has already passed and it
        // should be empty.
        LinkedList<Message> failedACIMsgs = new LinkedList<Message>();
        aciList.addAci(entry, hasAci, hasGlobalAci, failedACIMsgs);
      }
      // If we've gotten here, then everything is acceptable.
      return PluginResult.PostOperation.continueOperationProcessing();
    }
      InternalClientConnection conn =
           InternalClientConnection.getRootConnection();
      LinkedList<Message>failedACIMsgs=new LinkedList<Message>();
      //Add manageDsaIT control so any ACIs in referral entries will be
      //picked up.
      ArrayList<Control> controls = new ArrayList<Control>(1);
      controls.add(new LDAPControl(OID_MANAGE_DSAIT_CONTROL, true));
      //Add group membership control to let a backend look for it and
      //decide if it would abort searches.
      controls.add(new LDAPControl(
          OID_INTERNAL_GROUP_MEMBERSHIP_UPDATE ,false));
      for (DN baseDN : backend.getBaseDNs()) {
        try {
          if (! backend.entryExists(baseDN))  {
            continue;
          }
        } catch (Exception e) {
            if (debugEnabled())
            {
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
            }
            continue;
    /**
     * {@inheritDoc}
     */
    public PostOperation doPostOperation(
        PostOperationDeleteOperation deleteOperation)
    {
      // This entry might have both global and aci attribute types.
      boolean hasAci, hasGlobalAci = false;
      Entry entry = deleteOperation.getEntryToDelete();
      if ((hasAci = entry.hasOperationalAttribute(AciHandler.aciType))
          || (hasGlobalAci =
              entry.hasAttribute(AciHandler.globalAciType)))
      {
        aciList.removeAci(entry, hasAci, hasGlobalAci);
      }
      // If we've gotten here, then everything is acceptable.
      return PluginResult.PostOperation.continueOperationProcessing();
    }
    /**
     * {@inheritDoc}
     */
    public PostOperation doPostOperation(
        PostOperationModifyDNOperation modifyDNOperation)
    {
      aciList.renameAci(modifyDNOperation.getOriginalEntry().getDN(),
          modifyDNOperation.getUpdatedEntry().getDN());
      // If we've gotten here, then everything is acceptable.
      return PluginResult.PostOperation.continueOperationProcessing();
    }
    /**
     * {@inheritDoc}
     */
    public PostOperation doPostOperation(
        PostOperationModifyOperation modifyOperation)
    {
      // A change to the ACI list is expensive so let's first make sure
      // that the modification included changes to the ACI. We'll check
      // for both "aci" attribute types and global "ds-cfg-global-aci"
      // attribute types.
      boolean hasAci = false, hasGlobalAci = false;
      List<Modification> mods = modifyOperation.getModifications();
      for (Modification mod : mods)
      {
        AttributeType attributeType =
            mod.getAttribute().getAttributeType();
        if (attributeType.equals(AciHandler.aciType))
        {
          hasAci = true;
        }
        InternalSearchOperation internalSearch =
             new InternalSearchOperation(
                  conn,
                  InternalClientConnection.nextOperationID(),
                  InternalClientConnection.nextMessageID(),
                  controls, baseDN, SearchScope.WHOLE_SUBTREE,
                  DereferencePolicy.NEVER_DEREF_ALIASES,
                  0, 0, false, aciFilter, attrs, null);
        LocalBackendSearchOperation localInternalSearch =
        else if (attributeType.equals(AciHandler.globalAciType))
        {
          hasGlobalAci = true;
        }
        if (hasAci && hasGlobalAci)
        {
          break;
        }
      }
      if (hasAci || hasGlobalAci)
      {
        Entry oldEntry = modifyOperation.getCurrentEntry();
        Entry newEntry = modifyOperation.getModifiedEntry();
        aciList.modAciOldNewEntry(oldEntry, newEntry, hasAci,
            hasGlobalAci);
      }
      // If we've gotten here, then everything is acceptable.
      return PluginResult.PostOperation.continueOperationProcessing();
    }
  }
  /*
   * The configuration DN.
   */
  private DN configurationDN;
  /*
   * True if the server is in lockdown mode.
   */
  private boolean inLockDownMode = false;
  /*
   * The AciList caches the ACIs.
   */
  private AciList aciList;
  /*
   * Search filter used in context search for "aci" attribute types.
   */
  private static SearchFilter aciFilter;
  /*
   * Internal plugin used for updating the cache before a response is
   * sent to the client.
   */
  private final AciChangeListenerPlugin plugin;
  /*
   * The aci attribute type is operational so we need to specify it to
   * be returned.
   */
  private static LinkedHashSet<String> attrs =
      new LinkedHashSet<String>();
  static
  {
    /*
     * Set up the filter used to search private and public contexts.
     */
    try
    {
      aciFilter = SearchFilter.createFilterFromString("(aci=*)");
    }
    catch (DirectoryException ex)
    {
      // TODO should never happen, error message?
    }
    attrs.add("aci");
  }
  /**
   * Save the list created by the AciHandler routine. Registers as an
   * Alert Generator that can send alerts when the server is being put
   * in lockdown mode. Registers as backend initialization listener that
   * is used to manage the ACI list cache when backends are
   * initialized/finalized. Registers as a change notification listener
   * that is used to manage the ACI list cache after ACI modifications
   * have been performed.
   *
   * @param aciList
   *          The list object created and loaded by the handler.
   * @param cfgDN
   *          The DN of the access control configuration entry.
   */
  public AciListenerManager(AciList aciList, DN cfgDN)
  {
    this.aciList = aciList;
    this.configurationDN = cfgDN;
    this.plugin = new AciChangeListenerPlugin();
    DirectoryServer.registerInternalPlugin(plugin);
    DirectoryServer.registerBackendInitializationListener(this);
    DirectoryServer.registerAlertGenerator(this);
  }
  /**
   * Deregister from the change notification listener, the backend
   * initialization listener and the alert generator.
   */
  public void finalizeListenerManager()
  {
    DirectoryServer.deregisterInternalPlugin(plugin);
    DirectoryServer.deregisterBackendInitializationListener(this);
    DirectoryServer.deregisterAlertGenerator(this);
  }
  /**
   * {@inheritDoc} In this case, the server will search the backend to
   * find all aci attribute type values that it may contain and add them
   * to the ACI list.
   */
  public void performBackendInitializationProcessing(Backend backend)
  {
    // Check to make sure that the backend has a presence index defined
    // for the ACI attribute. If it does not, then log a warning message
    // because this processing could be very expensive.
    AttributeType aciType =
        DirectoryServer.getAttributeType("aci", true);
    if (backend.getEntryCount() > 0
        && !backend.isIndexed(aciType, IndexType.PRESENCE))
    {
      logError(WARN_ACI_ATTRIBUTE_NOT_INDEXED.get(backend
          .getBackendID(), "aci"));
    }
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    LinkedList<Message> failedACIMsgs = new LinkedList<Message>();
    // Add manageDsaIT control so any ACIs in referral entries will be
    // picked up.
    ArrayList<Control> controls = new ArrayList<Control>(1);
    controls.add(new LDAPControl(OID_MANAGE_DSAIT_CONTROL, true));
    // Add group membership control to let a backend look for it and
    // decide if it would abort searches.
    controls.add(new LDAPControl(OID_INTERNAL_GROUP_MEMBERSHIP_UPDATE,
        false));
    for (DN baseDN : backend.getBaseDNs())
    {
      try
      {
        if (!backend.entryExists(baseDN))
        {
          continue;
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        continue;
      }
      InternalSearchOperation internalSearch =
          new InternalSearchOperation(conn, InternalClientConnection
              .nextOperationID(), InternalClientConnection
              .nextMessageID(), controls, baseDN,
              SearchScope.WHOLE_SUBTREE,
              DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false,
              aciFilter, attrs, null);
      LocalBackendSearchOperation localInternalSearch =
          new LocalBackendSearchOperation(internalSearch);
        try  {
          backend.search(localInternalSearch);
        } catch (Exception e) {
            if (debugEnabled())
            {
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
            }
            continue;
      try
      {
        backend.search(localInternalSearch);
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        if(!internalSearch.getSearchEntries().isEmpty()) {
          int validAcis = aciList.addAci(
               internalSearch.getSearchEntries(), failedACIMsgs);
          if(!failedACIMsgs.isEmpty())
                    logMsgsSetLockDownMode(failedACIMsgs);
          Message message = INFO_ACI_ADD_LIST_ACIS.get(
              Integer.toString(validAcis), String.valueOf(baseDN));
          logError(message);
        }
        continue;
      }
      if (!internalSearch.getSearchEntries().isEmpty())
      {
        int validAcis =
            aciList.addAci(internalSearch.getSearchEntries(),
                failedACIMsgs);
        if (!failedACIMsgs.isEmpty())
          logMsgsSetLockDownMode(failedACIMsgs);
        Message message =
            INFO_ACI_ADD_LIST_ACIS.get(Integer.toString(validAcis),
                String.valueOf(baseDN));
        logError(message);
      }
    }
    /**
     * {@inheritDoc}  In this case, the server will remove all aci attribute
     * type values associated with entries in the provided backend.
     */
    public void performBackendFinalizationProcessing(Backend backend) {
        aciList.removeAci(backend);
    }
  }
    /**
     * Retrieves the fully-qualified name of the Java class for this alert
     * generator implementation.
     *
     * @return  The fully-qualified name of the Java class for this alert
     *          generator implementation.
     */
    public String getClassName()
  /**
   * {@inheritDoc} In this case, the server will remove all aci
   * attribute type values associated with entries in the provided
   * backend.
   */
  public void performBackendFinalizationProcessing(Backend backend)
  {
    aciList.removeAci(backend);
  }
  /**
   * Retrieves the fully-qualified name of the Java class for this alert
   * generator implementation.
   *
   * @return The fully-qualified name of the Java class for this alert
   *         generator implementation.
   */
  public String getClassName()
  {
    return CLASS_NAME;
  }
  /**
   * Retrieves the DN of the configuration entry used to configure the
   * handler.
   *
   * @return The DN of the configuration entry containing the Access
   *         Control configuration information.
   */
  public DN getComponentEntryDN()
  {
    return this.configurationDN;
  }
  /**
   * Retrieves information about the set of alerts that this generator
   * may produce. The map returned should be between the notification
   * type for a particular notification and the human-readable
   * description for that notification. This alert generator must not
   * generate any alerts with types that are not contained in this list.
   *
   * @return Information about the set of alerts that this generator may
   *         produce.
   */
  public LinkedHashMap<String, String> getAlerts()
  {
    LinkedHashMap<String, String> alerts =
        new LinkedHashMap<String, String>();
    alerts.put(ALERT_TYPE_ACCESS_CONTROL_PARSE_FAILED,
        ALERT_DESCRIPTION_ACCESS_CONTROL_PARSE_FAILED);
    return alerts;
  }
  /**
   * Log the exception messages from the failed ACI decode and then put
   * the server in lockdown mode -- if needed.
   *
   * @param failedACIMsgs
   *          List of exception messages from failed ACI decodes.
   */
  public void logMsgsSetLockDownMode(LinkedList<Message> failedACIMsgs)
  {
    for (Message msg : failedACIMsgs)
    {
        return CLASS_NAME;
      Message message = WARN_ACI_SERVER_DECODE_FAILED.get(msg);
      logError(message);
    }
    if (!inLockDownMode)
      setLockDownMode();
  }
    /**
     * Retrieves the DN of the configuration entry used to configure the
     * handler.
     *
     * @return  The DN of the configuration entry containing the Access Control
     *          configuration information.
     */
    public DN getComponentEntryDN()
  /**
   * Send an WARN_ACI_ENTER_LOCKDOWN_MODE alert notification and put the
   * server in lockdown mode.
   */
  private void setLockDownMode()
  {
    if (!inLockDownMode)
    {
      return this.configurationDN;
    }
    /**
     * Retrieves information about the set of alerts that this generator may
     * produce.  The map returned should be between the notification type for a
     * particular notification and the human-readable description for that
     * notification.  This alert generator must not generate any alerts with
     * types that are not contained in this list.
     *
     * @return  Information about the set of alerts that this generator may
     *          produce.
     */
    public LinkedHashMap<String,String> getAlerts()
    {
        LinkedHashMap<String,String> alerts =
                new LinkedHashMap<String,String>();
        alerts.put(ALERT_TYPE_ACCESS_CONTROL_PARSE_FAILED,
                ALERT_DESCRIPTION_ACCESS_CONTROL_PARSE_FAILED);
        return alerts;
      inLockDownMode = true;
      // Send ALERT_TYPE_ACCESS_CONTROL_PARSE_FAILED alert that
      // lockdown is about to be entered.
      Message lockDownMsg = WARN_ACI_ENTER_LOCKDOWN_MODE.get();
      DirectoryServer.sendAlertNotification(this,
          ALERT_TYPE_ACCESS_CONTROL_PARSE_FAILED, lockDownMsg);
      // Enter lockdown mode.
      DirectoryServer.setLockdownMode(true);
    }
    /**
     * Log the exception messages from the failed ACI decode and then put the
     * server in lockdown mode -- if needed.
     *
     * @param failedACIMsgs  List of exception messages from failed ACI decodes.
     */
    public  void logMsgsSetLockDownMode(LinkedList<Message> failedACIMsgs) {
        for(Message msg : failedACIMsgs) {
            Message message=WARN_ACI_SERVER_DECODE_FAILED.get(msg);
            logError(message);
        }
        if(!inLockDownMode)
            setLockDownMode();
    }
    /**
     * Send an WARN_ACI_ENTER_LOCKDOWN_MODE alert notification and put the
     * server in lockdown mode.
     *
     */
    private void setLockDownMode() {
        if(!inLockDownMode) {
            inLockDownMode=true;
            //Send ALERT_TYPE_ACCESS_CONTROL_PARSE_FAILED alert that
            //lockdown is about to be entered.
            Message lockDownMsg=WARN_ACI_ENTER_LOCKDOWN_MODE.get();
            DirectoryServer.sendAlertNotification(this,
                    ALERT_TYPE_ACCESS_CONTROL_PARSE_FAILED,
                    lockDownMsg );
            //Enter lockdown mode.
            DirectoryServer.setLockdownMode(true);
        }
    }
  }
}
opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -123,6 +123,7 @@
import org.opends.server.api.SynchronizationProvider;
import org.opends.server.api.TrustManagerProvider;
import org.opends.server.api.WorkQueue;
import org.opends.server.api.plugin.InternalDirectoryServerPlugin;
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.api.plugin.PluginType;
import org.opends.server.api.ExtensibleMatchingRule;
@@ -1341,6 +1342,11 @@
      initializeSchema();
      // Initialize the plugin manager so that internal plugins can be
      // registered.
      pluginConfigManager.initializePluginConfigManager();
      // Initialize all the virtual attribute handlers.
      initializeVirtualAttributes();
@@ -1474,9 +1480,8 @@
      initializePasswordPolicyComponents();
      // Load and initialize all the plugins, and then call the registered
      // startup plugins.
      initializePlugins();
      // Load and initialize the user plugins.
      pluginConfigManager.initializeUserPlugins(null);
      // Initialize any synchronization providers that may be defined.
      if (!environmentConfig.disableSynchronization())
@@ -1491,6 +1496,7 @@
      workQueue = new WorkQueueConfigManager().initializeWorkQueue();
      // Invoke the startup plugins.
      PluginResult.Startup startupPluginResult =
           pluginConfigManager.invokeStartupPlugins();
      if (! startupPluginResult.continueProcessing())
@@ -2906,24 +2912,6 @@
  /**
   * Initializes the set of plugins defined in the Directory Server.
   *
   * @throws  ConfigException  If there is a configuration problem with any of
   *                           the Directory Server plugins.
   *
   * @throws  InitializationException  If a problem occurs while initializing
   *                                   the plugins that is not related to the
   *                                   server configuration.
   */
  public void initializePlugins()
         throws ConfigException, InitializationException
  {
    pluginConfigManager.initializePluginConfig(null);
  }
  /**
   * Initializes the set of plugins defined in the Directory Server.  Only the
   * specified types of plugins will be initialized.
   *
@@ -2941,7 +2929,8 @@
         throws ConfigException, InitializationException
  {
    pluginConfigManager = new PluginConfigManager();
    pluginConfigManager.initializePluginConfig(pluginTypes);
    pluginConfigManager.initializePluginConfigManager();
    pluginConfigManager.initializeUserPlugins(pluginTypes);
  }
@@ -3005,6 +2994,37 @@
  /**
   * Registers the provided internal plugin with the Directory Server
   * and ensures that it will be invoked in the specified ways.
   *
   * @param plugin
   *          The internal plugin to register with the Directory Server.
   *          The plugin must specify a configuration entry which is
   *          guaranteed to be unique.
   */
  public static void registerInternalPlugin(
      InternalDirectoryServerPlugin plugin)
  {
    directoryServer.pluginConfigManager.registerInternalPlugin(plugin);
  }
  /**
   * Deregisters the provided internal plugin with the Directory Server.
   *
   * @param plugin
   *          The internal plugin to deregister from the Directory Server.
   */
  public static void deregisterInternalPlugin(
      InternalDirectoryServerPlugin plugin)
  {
    directoryServer.pluginConfigManager.deregisterInternalPlugin(plugin);
  }
  /**
   * Retrieves the requested entry from the Directory Server configuration.
   *
   * @param  entryDN  The DN of the configuration entry to retrieve.
opends/src/server/org/opends/server/core/PluginConfigManager.java
@@ -234,46 +234,58 @@
  /**
   * Initializes the configuration associated with the Directory Server plugins.
   * This should only be called at Directory Server startup.
   * Initializes this plugin configuration manager. This should only
   * be called at Directory Server startup and before user plugins are
   * loaded.
   *
   * @param  pluginTypes  The set of plugin types for the plugins to initialize,
   *                      or <CODE>null</CODE> to initialize all types of
   *                      plugins defined in the server configuration.  In
   *                      general, this should only be non-null for cases in
   *                      which the server is running in a special mode that
   *                      only uses a minimal set of plugins (e.g., LDIF import
   *                      or export).
   *
   * @throws  ConfigException  If a critical configuration problem prevents the
   *                           plugin initialization from succeeding.
   *
   * @throws  InitializationException  If a problem occurs while initializing
   *                                   the plugins that is not related to the
   *                                   server configuration.
   * @throws ConfigException
   *           If a critical configuration problem prevents the plugin
   *           initialization from succeeding.
   */
  public void initializePluginConfig(Set<PluginType> pluginTypes)
         throws ConfigException, InitializationException
  public void initializePluginConfigManager() throws ConfigException
  {
    registeredPlugins.clear();
    // Get the root configuration object.
    ServerManagementContext managementContext =
         ServerManagementContext.getInstance();
    RootCfg rootConfiguration =
         managementContext.getRootConfiguration();
    // Get the plugin root configuration and register with it as an add and
    // delete listener so we can be notified if any plugin entries are added or
    // removed.
    pluginRootConfig = rootConfiguration.getPluginRoot();
    pluginRootConfig.addPluginAddListener(this);
    pluginRootConfig.addPluginDeleteListener(this);
  }
    //Initialize the existing plugins.
  /**
   * Initializes any plugins defined in the directory server
   * configuration. This should only be called at Directory Server
   * startup and after this plugin configuration manager has been
   * initialized.
   *
   * @param pluginTypes
   *          The set of plugin types for the plugins to initialize, or
   *          <CODE>null</CODE> to initialize all types of plugins
   *          defined in the server configuration. In general, this
   *          should only be non-null for cases in which the server is
   *          running in a special mode that only uses a minimal set of
   *          plugins (e.g., LDIF import or export).
   * @throws ConfigException
   *           If a critical configuration problem prevents the plugin
   *           initialization from succeeding.
   * @throws InitializationException
   *           If a problem occurs while initializing the plugins that
   *           is not related to the server configuration.
   */
  public void initializeUserPlugins(Set<PluginType> pluginTypes)
         throws ConfigException, InitializationException
  {
    //Initialize the user plugins.
    for (String pluginName : pluginRootConfig.listPlugins())
    {
      PluginCfg pluginConfiguration = pluginRootConfig.getPlugin(pluginName);
@@ -360,12 +372,12 @@
      if (initialize)
      {
        Method method = plugin.getClass().getMethod("initializeInternal",
                                                    PluginCfg.class, Set.class);
        method.invoke(plugin, configuration, pluginTypes);
        plugin.initializeInternal(configuration.dn(), pluginTypes,
            configuration.isInvokeForInternalOperations());
        method = plugin.getClass().getMethod("initializePlugin", Set.class,
            configuration.configurationClass());
        Method method =
            plugin.getClass().getMethod("initializePlugin", Set.class,
                configuration.configurationClass());
        method.invoke(plugin, pluginTypes, configuration);
      }
      else
@@ -553,297 +565,338 @@
  /**
   * Registers the provided plugin with this plugin config manager and ensures
   * that it will be invoked in the specified ways.
   * Registers the provided internal plugin with this plugin config
   * manager and ensures that it will be invoked in the specified ways.
   *
   * @param  plugin         The plugin to register with the server.
   * @param  pluginEntryDN  The DN of the configuration entry for the provided
   *                        plugin.
   * @param  pluginTypes    The plugin types that will be used to control the
   *                        points at which the provided plugin is invoked.
   * @param plugin
   *          The internal plugin to register with the server. The
   *          plugin must specify a configuration entry which is
   *          guaranteed to be unique.
   */
  private void registerPlugin(
                    DirectoryServerPlugin<? extends PluginCfg> plugin,
                    DN pluginEntryDN, Set<PluginType> pluginTypes)
  void registerInternalPlugin(InternalDirectoryServerPlugin plugin)
  {
    pluginLock.lock();
    try
    {
      registeredPlugins.put(pluginEntryDN, plugin);
      registerPlugin0(plugin, plugin.getPluginTypes());
    }
    finally
    {
      pluginLock.unlock();
    }
  }
      for (PluginType t : pluginTypes)
  /**
   * Register a plugin in the appropriate tables.
   *
   * @param plugin
   *          The plugin to register with the server.
   * @param pluginTypes
   *          The plugin types that will be used to control the points
   *          at which the provided plugin is invoked.
   */
  private void registerPlugin0(
      DirectoryServerPlugin<? extends PluginCfg> plugin,
      Set<PluginType> pluginTypes)
  {
    for (PluginType t : pluginTypes)
    {
      switch (t)
      {
        switch (t)
        {
          case STARTUP:
            startupPlugins =
                 addPlugin(startupPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderStartup());
            break;
          case SHUTDOWN:
            shutdownPlugins =
                 addPlugin(shutdownPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderShutdown());
            break;
          case POST_CONNECT:
            postConnectPlugins =
                 addPlugin(postConnectPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPostConnect());
            break;
          case POST_DISCONNECT:
            postDisconnectPlugins =
                 addPlugin(postDisconnectPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPostDisconnect());
            break;
          case LDIF_IMPORT:
            ldifImportPlugins =
                 addPlugin(ldifImportPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderLDIFImport());
            break;
          case LDIF_IMPORT_END:
            ldifImportEndPlugins =
                 addPlugin(ldifImportEndPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderLDIFImportEnd());
            break;
          case LDIF_IMPORT_BEGIN:
            ldifImportBeginPlugins =
                 addPlugin(ldifImportBeginPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderLDIFImportBegin());
            break;
          case LDIF_EXPORT:
            ldifExportPlugins =
                 addPlugin(ldifExportPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderLDIFExport());
            break;
          case PRE_PARSE_ABANDON:
            preParseAbandonPlugins =
                 addPlugin(preParseAbandonPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreParseAbandon());
            break;
          case PRE_PARSE_ADD:
            preParseAddPlugins =
                 addPlugin(preParseAddPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreParseAdd());
            break;
          case PRE_PARSE_BIND:
            preParseBindPlugins =
                 addPlugin(preParseBindPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreParseBind());
            break;
          case PRE_PARSE_COMPARE:
            preParseComparePlugins =
                 addPlugin(preParseComparePlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreParseCompare());
            break;
          case PRE_PARSE_DELETE:
            preParseDeletePlugins =
                 addPlugin(preParseDeletePlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreParseDelete());
            break;
          case PRE_PARSE_EXTENDED:
            preParseExtendedPlugins =
                 addPlugin(preParseExtendedPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreParseExtended());
            break;
          case PRE_PARSE_MODIFY:
            preParseModifyPlugins =
                 addPlugin(preParseModifyPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreParseModify());
            break;
          case PRE_PARSE_MODIFY_DN:
            preParseModifyDNPlugins =
                 addPlugin(preParseModifyDNPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreParseModifyDN());
            break;
          case PRE_PARSE_SEARCH:
            preParseSearchPlugins =
                 addPlugin(preParseSearchPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreParseSearch());
            break;
          case PRE_PARSE_UNBIND:
            preParseUnbindPlugins =
                 addPlugin(preParseUnbindPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreParseUnbind());
            break;
          case PRE_OPERATION_ADD:
            preOperationAddPlugins =
                 addPlugin(preOperationAddPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreOperationAdd());
            break;
          case PRE_OPERATION_BIND:
            preOperationBindPlugins =
                 addPlugin(preOperationBindPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreOperationBind());
            break;
          case PRE_OPERATION_COMPARE:
            preOperationComparePlugins =
                 addPlugin(preOperationComparePlugins,plugin, t,
                      pluginRootConfig.getPluginOrderPreOperationCompare());
            break;
          case PRE_OPERATION_DELETE:
            preOperationDeletePlugins =
                 addPlugin(preOperationDeletePlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreOperationDelete());
            break;
          case PRE_OPERATION_EXTENDED:
            preOperationExtendedPlugins =
                 addPlugin(preOperationExtendedPlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPreOperationExtended());
            break;
          case PRE_OPERATION_MODIFY:
            preOperationModifyPlugins =
                 addPlugin(preOperationModifyPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreOperationModify());
            break;
          case PRE_OPERATION_MODIFY_DN:
            preOperationModifyDNPlugins =
                 addPlugin(preOperationModifyDNPlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPreOperationModifyDN());
            break;
          case PRE_OPERATION_SEARCH:
            preOperationSearchPlugins =
                 addPlugin(preOperationSearchPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPreOperationSearch());
            break;
          case POST_OPERATION_ABANDON:
            postOperationAbandonPlugins =
                 addPlugin(postOperationAbandonPlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPostOperationAbandon());
            break;
          case POST_OPERATION_ADD:
            postOperationAddPlugins =
                 addPlugin(postOperationAddPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPostOperationAdd());
            break;
          case POST_OPERATION_BIND:
            postOperationBindPlugins =
                 addPlugin(postOperationBindPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPostOperationBind());
            break;
          case POST_OPERATION_COMPARE:
            postOperationComparePlugins =
                 addPlugin(postOperationComparePlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPostOperationCompare());
            break;
          case POST_OPERATION_DELETE:
            postOperationDeletePlugins =
                 addPlugin(postOperationDeletePlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPostOperationDelete());
            break;
          case POST_OPERATION_EXTENDED:
            postOperationExtendedPlugins =
                 addPlugin(postOperationExtendedPlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPostOperationExtended());
            break;
          case POST_OPERATION_MODIFY:
            postOperationModifyPlugins =
                 addPlugin(postOperationModifyPlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPostOperationModify());
            break;
          case POST_OPERATION_MODIFY_DN:
            postOperationModifyDNPlugins =
                 addPlugin(postOperationModifyDNPlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPostOperationModifyDN());
            break;
          case POST_OPERATION_SEARCH:
            postOperationSearchPlugins =
                 addPlugin(postOperationSearchPlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPostOperationSearch());
            break;
          case POST_OPERATION_UNBIND:
            postOperationUnbindPlugins =
                 addPlugin(postOperationUnbindPlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPostOperationUnbind());
            break;
          case POST_RESPONSE_ADD:
            postResponseAddPlugins =
                 addPlugin(postResponseAddPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPostResponseAdd());
            break;
          case POST_RESPONSE_BIND:
            postResponseBindPlugins =
                 addPlugin(postResponseBindPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPostResponseBind());
            break;
          case POST_RESPONSE_COMPARE:
            postResponseComparePlugins =
                 addPlugin(postResponseComparePlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPostResponseCompare());
            break;
          case POST_RESPONSE_DELETE:
            postResponseDeletePlugins =
                 addPlugin(postResponseDeletePlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPostResponseDelete());
            break;
          case POST_RESPONSE_EXTENDED:
            postResponseExtendedPlugins =
                 addPlugin(postResponseExtendedPlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPostResponseExtended());
            break;
          case POST_RESPONSE_MODIFY:
            postResponseModifyPlugins =
                 addPlugin(postResponseModifyPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPostResponseModify());
            break;
          case POST_RESPONSE_MODIFY_DN:
            postResponseModifyDNPlugins =
                 addPlugin(postResponseModifyDNPlugins, plugin, t,
                      pluginRootConfig.getPluginOrderPostResponseModifyDN());
            break;
          case POST_RESPONSE_SEARCH:
            postResponseSearchPlugins =
                 addPlugin(postResponseSearchPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderPostResponseSearch());
            break;
          case POST_SYNCHRONIZATION_ADD:
            postSynchronizationAddPlugins =
                 addPlugin(postSynchronizationAddPlugins, plugin, t,
                           pluginRootConfig.
                                getPluginOrderPostSynchronizationAdd());
            break;
          case POST_SYNCHRONIZATION_DELETE:
            postSynchronizationDeletePlugins =
                 addPlugin(postSynchronizationDeletePlugins, plugin, t,
                           pluginRootConfig.
                                getPluginOrderPostSynchronizationDelete());
            break;
          case POST_SYNCHRONIZATION_MODIFY:
            postSynchronizationModifyPlugins =
                 addPlugin(postSynchronizationModifyPlugins, plugin, t,
                           pluginRootConfig.
                                getPluginOrderPostSynchronizationModify());
            break;
          case POST_SYNCHRONIZATION_MODIFY_DN:
            postSynchronizationModifyDNPlugins =
                 addPlugin(postSynchronizationModifyDNPlugins, plugin, t,
                           pluginRootConfig.
                                getPluginOrderPostSynchronizationModifyDN());
            break;
          case SEARCH_RESULT_ENTRY:
            searchResultEntryPlugins =
                 addPlugin(searchResultEntryPlugins, plugin, t,
                           pluginRootConfig.getPluginOrderSearchResultEntry());
            break;
          case SEARCH_RESULT_REFERENCE:
            searchResultReferencePlugins =
                 addPlugin(searchResultReferencePlugins, plugin, t,
                      pluginRootConfig.getPluginOrderSearchResultReference());
            break;
          case SUBORDINATE_MODIFY_DN:
            subordinateModifyDNPlugins =
                 addPlugin(subordinateModifyDNPlugins, plugin, t,
                      pluginRootConfig.getPluginOrderSubordinateModifyDN());
            break;
          case INTERMEDIATE_RESPONSE:
            intermediateResponsePlugins =
                 addPlugin(intermediateResponsePlugins, plugin, t,
                      pluginRootConfig.getPluginOrderIntermediateResponse());
            break;
          default:
        }
      case STARTUP:
        startupPlugins =
            addPlugin(startupPlugins, plugin, t, pluginRootConfig
                .getPluginOrderStartup());
        break;
      case SHUTDOWN:
        shutdownPlugins =
            addPlugin(shutdownPlugins, plugin, t, pluginRootConfig
                .getPluginOrderShutdown());
        break;
      case POST_CONNECT:
        postConnectPlugins =
            addPlugin(postConnectPlugins, plugin, t, pluginRootConfig
                .getPluginOrderPostConnect());
        break;
      case POST_DISCONNECT:
        postDisconnectPlugins =
            addPlugin(postDisconnectPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostDisconnect());
        break;
      case LDIF_IMPORT:
        ldifImportPlugins =
            addPlugin(ldifImportPlugins, plugin, t, pluginRootConfig
                .getPluginOrderLDIFImport());
        break;
      case LDIF_IMPORT_END:
        ldifImportEndPlugins =
            addPlugin(ldifImportEndPlugins, plugin, t, pluginRootConfig
                .getPluginOrderLDIFImportEnd());
        break;
      case LDIF_IMPORT_BEGIN:
        ldifImportBeginPlugins =
            addPlugin(ldifImportBeginPlugins, plugin, t,
                pluginRootConfig.getPluginOrderLDIFImportBegin());
        break;
      case LDIF_EXPORT:
        ldifExportPlugins =
            addPlugin(ldifExportPlugins, plugin, t, pluginRootConfig
                .getPluginOrderLDIFExport());
        break;
      case PRE_PARSE_ABANDON:
        preParseAbandonPlugins =
            addPlugin(preParseAbandonPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreParseAbandon());
        break;
      case PRE_PARSE_ADD:
        preParseAddPlugins =
            addPlugin(preParseAddPlugins, plugin, t, pluginRootConfig
                .getPluginOrderPreParseAdd());
        break;
      case PRE_PARSE_BIND:
        preParseBindPlugins =
            addPlugin(preParseBindPlugins, plugin, t, pluginRootConfig
                .getPluginOrderPreParseBind());
        break;
      case PRE_PARSE_COMPARE:
        preParseComparePlugins =
            addPlugin(preParseComparePlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreParseCompare());
        break;
      case PRE_PARSE_DELETE:
        preParseDeletePlugins =
            addPlugin(preParseDeletePlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreParseDelete());
        break;
      case PRE_PARSE_EXTENDED:
        preParseExtendedPlugins =
            addPlugin(preParseExtendedPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreParseExtended());
        break;
      case PRE_PARSE_MODIFY:
        preParseModifyPlugins =
            addPlugin(preParseModifyPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreParseModify());
        break;
      case PRE_PARSE_MODIFY_DN:
        preParseModifyDNPlugins =
            addPlugin(preParseModifyDNPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreParseModifyDN());
        break;
      case PRE_PARSE_SEARCH:
        preParseSearchPlugins =
            addPlugin(preParseSearchPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreParseSearch());
        break;
      case PRE_PARSE_UNBIND:
        preParseUnbindPlugins =
            addPlugin(preParseUnbindPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreParseUnbind());
        break;
      case PRE_OPERATION_ADD:
        preOperationAddPlugins =
            addPlugin(preOperationAddPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreOperationAdd());
        break;
      case PRE_OPERATION_BIND:
        preOperationBindPlugins =
            addPlugin(preOperationBindPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreOperationBind());
        break;
      case PRE_OPERATION_COMPARE:
        preOperationComparePlugins =
            addPlugin(preOperationComparePlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreOperationCompare());
        break;
      case PRE_OPERATION_DELETE:
        preOperationDeletePlugins =
            addPlugin(preOperationDeletePlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreOperationDelete());
        break;
      case PRE_OPERATION_EXTENDED:
        preOperationExtendedPlugins =
            addPlugin(preOperationExtendedPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreOperationExtended());
        break;
      case PRE_OPERATION_MODIFY:
        preOperationModifyPlugins =
            addPlugin(preOperationModifyPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreOperationModify());
        break;
      case PRE_OPERATION_MODIFY_DN:
        preOperationModifyDNPlugins =
            addPlugin(preOperationModifyDNPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreOperationModifyDN());
        break;
      case PRE_OPERATION_SEARCH:
        preOperationSearchPlugins =
            addPlugin(preOperationSearchPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPreOperationSearch());
        break;
      case POST_OPERATION_ABANDON:
        postOperationAbandonPlugins =
            addPlugin(postOperationAbandonPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostOperationAbandon());
        break;
      case POST_OPERATION_ADD:
        postOperationAddPlugins =
            addPlugin(postOperationAddPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostOperationAdd());
        break;
      case POST_OPERATION_BIND:
        postOperationBindPlugins =
            addPlugin(postOperationBindPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostOperationBind());
        break;
      case POST_OPERATION_COMPARE:
        postOperationComparePlugins =
            addPlugin(postOperationComparePlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostOperationCompare());
        break;
      case POST_OPERATION_DELETE:
        postOperationDeletePlugins =
            addPlugin(postOperationDeletePlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostOperationDelete());
        break;
      case POST_OPERATION_EXTENDED:
        postOperationExtendedPlugins =
            addPlugin(postOperationExtendedPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostOperationExtended());
        break;
      case POST_OPERATION_MODIFY:
        postOperationModifyPlugins =
            addPlugin(postOperationModifyPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostOperationModify());
        break;
      case POST_OPERATION_MODIFY_DN:
        postOperationModifyDNPlugins =
            addPlugin(postOperationModifyDNPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostOperationModifyDN());
        break;
      case POST_OPERATION_SEARCH:
        postOperationSearchPlugins =
            addPlugin(postOperationSearchPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostOperationSearch());
        break;
      case POST_OPERATION_UNBIND:
        postOperationUnbindPlugins =
            addPlugin(postOperationUnbindPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostOperationUnbind());
        break;
      case POST_RESPONSE_ADD:
        postResponseAddPlugins =
            addPlugin(postResponseAddPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostResponseAdd());
        break;
      case POST_RESPONSE_BIND:
        postResponseBindPlugins =
            addPlugin(postResponseBindPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostResponseBind());
        break;
      case POST_RESPONSE_COMPARE:
        postResponseComparePlugins =
            addPlugin(postResponseComparePlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostResponseCompare());
        break;
      case POST_RESPONSE_DELETE:
        postResponseDeletePlugins =
            addPlugin(postResponseDeletePlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostResponseDelete());
        break;
      case POST_RESPONSE_EXTENDED:
        postResponseExtendedPlugins =
            addPlugin(postResponseExtendedPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostResponseExtended());
        break;
      case POST_RESPONSE_MODIFY:
        postResponseModifyPlugins =
            addPlugin(postResponseModifyPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostResponseModify());
        break;
      case POST_RESPONSE_MODIFY_DN:
        postResponseModifyDNPlugins =
            addPlugin(postResponseModifyDNPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostResponseModifyDN());
        break;
      case POST_RESPONSE_SEARCH:
        postResponseSearchPlugins =
            addPlugin(postResponseSearchPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostResponseSearch());
        break;
      case POST_SYNCHRONIZATION_ADD:
        postSynchronizationAddPlugins =
            addPlugin(postSynchronizationAddPlugins, plugin, t,
                pluginRootConfig.getPluginOrderPostSynchronizationAdd());
        break;
      case POST_SYNCHRONIZATION_DELETE:
        postSynchronizationDeletePlugins =
            addPlugin(postSynchronizationDeletePlugins, plugin, t,
                pluginRootConfig
                    .getPluginOrderPostSynchronizationDelete());
        break;
      case POST_SYNCHRONIZATION_MODIFY:
        postSynchronizationModifyPlugins =
            addPlugin(postSynchronizationModifyPlugins, plugin, t,
                pluginRootConfig
                    .getPluginOrderPostSynchronizationModify());
        break;
      case POST_SYNCHRONIZATION_MODIFY_DN:
        postSynchronizationModifyDNPlugins =
            addPlugin(postSynchronizationModifyDNPlugins, plugin, t,
                pluginRootConfig
                    .getPluginOrderPostSynchronizationModifyDN());
        break;
      case SEARCH_RESULT_ENTRY:
        searchResultEntryPlugins =
            addPlugin(searchResultEntryPlugins, plugin, t,
                pluginRootConfig.getPluginOrderSearchResultEntry());
        break;
      case SEARCH_RESULT_REFERENCE:
        searchResultReferencePlugins =
            addPlugin(searchResultReferencePlugins, plugin, t,
                pluginRootConfig.getPluginOrderSearchResultReference());
        break;
      case SUBORDINATE_MODIFY_DN:
        subordinateModifyDNPlugins =
            addPlugin(subordinateModifyDNPlugins, plugin, t,
                pluginRootConfig.getPluginOrderSubordinateModifyDN());
        break;
      case INTERMEDIATE_RESPONSE:
        intermediateResponsePlugins =
            addPlugin(intermediateResponsePlugins, plugin, t,
                pluginRootConfig.getPluginOrderIntermediateResponse());
        break;
      default:
      }
    }
  }
  /**
   * Registers the provided plugin with this plugin config manager and
   * ensures that it will be invoked in the specified ways.
   *
   * @param plugin
   *          The plugin to register with the server.
   * @param pluginEntryDN
   *          The DN of the configuration entry for the provided plugin.
   * @param pluginTypes
   *          The plugin types that will be used to control the points
   *          at which the provided plugin is invoked.
   */
  private void registerPlugin(
      DirectoryServerPlugin<? extends PluginCfg> plugin,
      DN pluginEntryDN, Set<PluginType> pluginTypes)
  {
    pluginLock.lock();
    registeredPlugins.put(pluginEntryDN, plugin);
    try
    {
      registerPlugin0(plugin, pluginTypes);
    }
    finally
    {
      pluginLock.unlock();
@@ -1067,233 +1120,266 @@
  /**
   * Deregisters the provided internal plugin.
   *
   * @param plugin
   *          The internal plugin to deregister from the server.
   */
  void deregisterInternalPlugin(InternalDirectoryServerPlugin plugin)
  {
    pluginLock.lock();
    try
    {
      deregisterPlugin0(plugin);
      plugin.finalizePlugin();
    }
    finally
    {
      pluginLock.unlock();
    }
  }
  /**
   * Deregisters the plugin with the provided configuration entry DN.
   *
   * @param  configEntryDN  The DN of the configuration entry for the plugin to
   *                        deregister.
   * @param configEntryDN
   *          The DN of the configuration entry for the plugin to
   *          deregister.
   */
  private void deregisterPlugin(DN configEntryDN)
  {
    pluginLock.lock();
    DirectoryServerPlugin<? extends PluginCfg> plugin;
    try
    {
      plugin = registeredPlugins.remove(configEntryDN);
      if (plugin == null)
      if (plugin != null)
      {
        return;
      }
      for (PluginType t : plugin.getPluginTypes())
      {
        switch (t)
        {
          case STARTUP:
            startupPlugins = removePlugin(startupPlugins, plugin);
            break;
          case SHUTDOWN:
            shutdownPlugins = removePlugin(shutdownPlugins, plugin);
            break;
          case POST_CONNECT:
            postConnectPlugins = removePlugin(postConnectPlugins, plugin);
            break;
          case POST_DISCONNECT:
            postDisconnectPlugins = removePlugin(postDisconnectPlugins, plugin);
            break;
          case LDIF_IMPORT:
            ldifImportPlugins = removePlugin(ldifImportPlugins, plugin);
            break;
          case LDIF_IMPORT_END:
            ldifImportEndPlugins = removePlugin(ldifImportEndPlugins, plugin);
            break;
          case LDIF_IMPORT_BEGIN:
            ldifImportBeginPlugins =
              removePlugin(ldifImportBeginPlugins, plugin);
            break;
          case LDIF_EXPORT:
            ldifExportPlugins = removePlugin(ldifExportPlugins, plugin);
            break;
          case PRE_PARSE_ABANDON:
            preParseAbandonPlugins = removePlugin(preParseAbandonPlugins,
                                                  plugin);
            break;
          case PRE_PARSE_ADD:
            preParseAddPlugins = removePlugin(preParseAddPlugins, plugin);
            break;
          case PRE_PARSE_BIND:
            preParseBindPlugins = removePlugin(preParseBindPlugins, plugin);
            break;
          case PRE_PARSE_COMPARE:
            preParseComparePlugins = removePlugin(preParseComparePlugins,
                                                  plugin);
            break;
          case PRE_PARSE_DELETE:
            preParseDeletePlugins = removePlugin(preParseDeletePlugins, plugin);
            break;
          case PRE_PARSE_EXTENDED:
            preParseExtendedPlugins = removePlugin(preParseExtendedPlugins,
                                                   plugin);
            break;
          case PRE_PARSE_MODIFY:
            preParseModifyPlugins = removePlugin(preParseModifyPlugins, plugin);
            break;
          case PRE_PARSE_MODIFY_DN:
            preParseModifyDNPlugins = removePlugin(preParseModifyDNPlugins,
                                                   plugin);
            break;
          case PRE_PARSE_SEARCH:
            preParseSearchPlugins = removePlugin(preParseSearchPlugins, plugin);
            break;
          case PRE_PARSE_UNBIND:
            preParseUnbindPlugins = removePlugin(preParseUnbindPlugins, plugin);
            break;
          case PRE_OPERATION_ADD:
            preOperationAddPlugins = removePlugin(preOperationAddPlugins,
                                                  plugin);
            break;
          case PRE_OPERATION_BIND:
            preOperationBindPlugins = removePlugin(preOperationBindPlugins,
                                                   plugin);
            break;
          case PRE_OPERATION_COMPARE:
            preOperationComparePlugins =
                 removePlugin(preOperationComparePlugins, plugin);
            break;
          case PRE_OPERATION_DELETE:
            preOperationDeletePlugins = removePlugin(preOperationDeletePlugins,
                                                     plugin);
            break;
          case PRE_OPERATION_EXTENDED:
            preOperationExtendedPlugins =
                 removePlugin(preOperationExtendedPlugins, plugin);
            break;
          case PRE_OPERATION_MODIFY:
            preOperationModifyPlugins = removePlugin(preOperationModifyPlugins,
                                                     plugin);
            break;
          case PRE_OPERATION_MODIFY_DN:
            preOperationModifyDNPlugins =
                 removePlugin(preOperationModifyDNPlugins, plugin);
            break;
          case PRE_OPERATION_SEARCH:
            preOperationSearchPlugins = removePlugin(preOperationSearchPlugins,
                                                     plugin);
            break;
          case POST_OPERATION_ABANDON:
            postOperationAbandonPlugins =
                 removePlugin(postOperationAbandonPlugins, plugin);
            break;
          case POST_OPERATION_ADD:
            postOperationAddPlugins = removePlugin(postOperationAddPlugins,
                                                   plugin);
            break;
          case POST_OPERATION_BIND:
            postOperationBindPlugins = removePlugin(postOperationBindPlugins,
                                                    plugin);
            break;
          case POST_OPERATION_COMPARE:
            postOperationComparePlugins =
                 removePlugin(postOperationComparePlugins, plugin);
            break;
          case POST_OPERATION_DELETE:
            postOperationDeletePlugins =
                 removePlugin(postOperationDeletePlugins, plugin);
            break;
          case POST_OPERATION_EXTENDED:
            postOperationExtendedPlugins =
                 removePlugin(postOperationExtendedPlugins, plugin);
            break;
          case POST_OPERATION_MODIFY:
            postOperationModifyPlugins =
                 removePlugin(postOperationModifyPlugins, plugin);
            break;
          case POST_OPERATION_MODIFY_DN:
            postOperationModifyDNPlugins =
                 removePlugin(postOperationModifyDNPlugins, plugin);
            break;
          case POST_OPERATION_SEARCH:
            postOperationSearchPlugins =
                 removePlugin(postOperationSearchPlugins, plugin);
            break;
          case POST_OPERATION_UNBIND:
            postOperationUnbindPlugins =
                 removePlugin(postOperationUnbindPlugins, plugin);
            break;
          case POST_RESPONSE_ADD:
            postResponseAddPlugins = removePlugin(postResponseAddPlugins,
                                                  plugin);
            break;
          case POST_RESPONSE_BIND:
            postResponseBindPlugins = removePlugin(postResponseBindPlugins,
                                                   plugin);
            break;
          case POST_RESPONSE_COMPARE:
            postResponseComparePlugins =
                 removePlugin(postResponseComparePlugins, plugin);
            break;
          case POST_RESPONSE_DELETE:
            postResponseDeletePlugins = removePlugin(postResponseDeletePlugins,
                                                     plugin);
            break;
          case POST_RESPONSE_EXTENDED:
            postResponseExtendedPlugins =
                 removePlugin(postResponseExtendedPlugins, plugin);
            break;
          case POST_RESPONSE_MODIFY:
            postResponseModifyPlugins = removePlugin(postResponseModifyPlugins,
                                                     plugin);
            break;
          case POST_RESPONSE_MODIFY_DN:
            postResponseModifyDNPlugins =
                 removePlugin(postResponseModifyDNPlugins, plugin);
            break;
          case POST_RESPONSE_SEARCH:
            postResponseSearchPlugins = removePlugin(postResponseSearchPlugins,
                                                     plugin);
            break;
          case POST_SYNCHRONIZATION_ADD:
            postSynchronizationAddPlugins =
                 removePlugin(postSynchronizationAddPlugins, plugin);
            break;
          case POST_SYNCHRONIZATION_DELETE:
            postSynchronizationDeletePlugins =
                 removePlugin(postSynchronizationDeletePlugins, plugin);
            break;
          case POST_SYNCHRONIZATION_MODIFY:
            postSynchronizationModifyPlugins =
                 removePlugin(postSynchronizationModifyPlugins, plugin);
            break;
          case POST_SYNCHRONIZATION_MODIFY_DN:
            postSynchronizationModifyDNPlugins =
                 removePlugin(postSynchronizationModifyDNPlugins, plugin);
            break;
          case SEARCH_RESULT_ENTRY:
            searchResultEntryPlugins = removePlugin(searchResultEntryPlugins,
                                                    plugin);
            break;
          case SEARCH_RESULT_REFERENCE:
            searchResultReferencePlugins =
                 removePlugin(searchResultReferencePlugins, plugin);
            break;
          case SUBORDINATE_MODIFY_DN:
            subordinateModifyDNPlugins =
                 removePlugin(subordinateModifyDNPlugins, plugin);
            break;
          case INTERMEDIATE_RESPONSE:
            intermediateResponsePlugins =
                 removePlugin(intermediateResponsePlugins, plugin);
            break;
          default:
        }
        deregisterPlugin0(plugin);
        plugin.finalizePlugin();
      }
    }
    finally
    {
      pluginLock.unlock();
    }
  }
    plugin.finalizePlugin();
  /**
   * Deregisters the provided plugin.
   *
   * @param plugin
   *          The plugin to deregister from the server.
   */
  private void deregisterPlugin0(
      DirectoryServerPlugin<? extends PluginCfg> plugin)
  {
    for (PluginType t : plugin.getPluginTypes())
    {
      switch (t)
      {
        case STARTUP:
          startupPlugins = removePlugin(startupPlugins, plugin);
          break;
        case SHUTDOWN:
          shutdownPlugins = removePlugin(shutdownPlugins, plugin);
          break;
        case POST_CONNECT:
          postConnectPlugins = removePlugin(postConnectPlugins, plugin);
          break;
        case POST_DISCONNECT:
          postDisconnectPlugins = removePlugin(postDisconnectPlugins, plugin);
          break;
        case LDIF_IMPORT:
          ldifImportPlugins = removePlugin(ldifImportPlugins, plugin);
          break;
        case LDIF_IMPORT_END:
          ldifImportEndPlugins = removePlugin(ldifImportEndPlugins, plugin);
          break;
        case LDIF_IMPORT_BEGIN:
          ldifImportBeginPlugins =
            removePlugin(ldifImportBeginPlugins, plugin);
          break;
        case LDIF_EXPORT:
          ldifExportPlugins = removePlugin(ldifExportPlugins, plugin);
          break;
        case PRE_PARSE_ABANDON:
          preParseAbandonPlugins = removePlugin(preParseAbandonPlugins,
                                                plugin);
          break;
        case PRE_PARSE_ADD:
          preParseAddPlugins = removePlugin(preParseAddPlugins, plugin);
          break;
        case PRE_PARSE_BIND:
          preParseBindPlugins = removePlugin(preParseBindPlugins, plugin);
          break;
        case PRE_PARSE_COMPARE:
          preParseComparePlugins = removePlugin(preParseComparePlugins,
                                                plugin);
          break;
        case PRE_PARSE_DELETE:
          preParseDeletePlugins = removePlugin(preParseDeletePlugins, plugin);
          break;
        case PRE_PARSE_EXTENDED:
          preParseExtendedPlugins = removePlugin(preParseExtendedPlugins,
                                                 plugin);
          break;
        case PRE_PARSE_MODIFY:
          preParseModifyPlugins = removePlugin(preParseModifyPlugins, plugin);
          break;
        case PRE_PARSE_MODIFY_DN:
          preParseModifyDNPlugins = removePlugin(preParseModifyDNPlugins,
                                                 plugin);
          break;
        case PRE_PARSE_SEARCH:
          preParseSearchPlugins = removePlugin(preParseSearchPlugins, plugin);
          break;
        case PRE_PARSE_UNBIND:
          preParseUnbindPlugins = removePlugin(preParseUnbindPlugins, plugin);
          break;
        case PRE_OPERATION_ADD:
          preOperationAddPlugins = removePlugin(preOperationAddPlugins,
                                                plugin);
          break;
        case PRE_OPERATION_BIND:
          preOperationBindPlugins = removePlugin(preOperationBindPlugins,
                                                 plugin);
          break;
        case PRE_OPERATION_COMPARE:
          preOperationComparePlugins =
               removePlugin(preOperationComparePlugins, plugin);
          break;
        case PRE_OPERATION_DELETE:
          preOperationDeletePlugins = removePlugin(preOperationDeletePlugins,
                                                   plugin);
          break;
        case PRE_OPERATION_EXTENDED:
          preOperationExtendedPlugins =
               removePlugin(preOperationExtendedPlugins, plugin);
          break;
        case PRE_OPERATION_MODIFY:
          preOperationModifyPlugins = removePlugin(preOperationModifyPlugins,
                                                   plugin);
          break;
        case PRE_OPERATION_MODIFY_DN:
          preOperationModifyDNPlugins =
               removePlugin(preOperationModifyDNPlugins, plugin);
          break;
        case PRE_OPERATION_SEARCH:
          preOperationSearchPlugins = removePlugin(preOperationSearchPlugins,
                                                   plugin);
          break;
        case POST_OPERATION_ABANDON:
          postOperationAbandonPlugins =
               removePlugin(postOperationAbandonPlugins, plugin);
          break;
        case POST_OPERATION_ADD:
          postOperationAddPlugins = removePlugin(postOperationAddPlugins,
                                                 plugin);
          break;
        case POST_OPERATION_BIND:
          postOperationBindPlugins = removePlugin(postOperationBindPlugins,
                                                  plugin);
          break;
        case POST_OPERATION_COMPARE:
          postOperationComparePlugins =
               removePlugin(postOperationComparePlugins, plugin);
          break;
        case POST_OPERATION_DELETE:
          postOperationDeletePlugins =
               removePlugin(postOperationDeletePlugins, plugin);
          break;
        case POST_OPERATION_EXTENDED:
          postOperationExtendedPlugins =
               removePlugin(postOperationExtendedPlugins, plugin);
          break;
        case POST_OPERATION_MODIFY:
          postOperationModifyPlugins =
               removePlugin(postOperationModifyPlugins, plugin);
          break;
        case POST_OPERATION_MODIFY_DN:
          postOperationModifyDNPlugins =
               removePlugin(postOperationModifyDNPlugins, plugin);
          break;
        case POST_OPERATION_SEARCH:
          postOperationSearchPlugins =
               removePlugin(postOperationSearchPlugins, plugin);
          break;
        case POST_OPERATION_UNBIND:
          postOperationUnbindPlugins =
               removePlugin(postOperationUnbindPlugins, plugin);
          break;
        case POST_RESPONSE_ADD:
          postResponseAddPlugins = removePlugin(postResponseAddPlugins,
                                                plugin);
          break;
        case POST_RESPONSE_BIND:
          postResponseBindPlugins = removePlugin(postResponseBindPlugins,
                                                 plugin);
          break;
        case POST_RESPONSE_COMPARE:
          postResponseComparePlugins =
               removePlugin(postResponseComparePlugins, plugin);
          break;
        case POST_RESPONSE_DELETE:
          postResponseDeletePlugins = removePlugin(postResponseDeletePlugins,
                                                   plugin);
          break;
        case POST_RESPONSE_EXTENDED:
          postResponseExtendedPlugins =
               removePlugin(postResponseExtendedPlugins, plugin);
          break;
        case POST_RESPONSE_MODIFY:
          postResponseModifyPlugins = removePlugin(postResponseModifyPlugins,
                                                   plugin);
          break;
        case POST_RESPONSE_MODIFY_DN:
          postResponseModifyDNPlugins =
               removePlugin(postResponseModifyDNPlugins, plugin);
          break;
        case POST_RESPONSE_SEARCH:
          postResponseSearchPlugins = removePlugin(postResponseSearchPlugins,
                                                   plugin);
          break;
        case POST_SYNCHRONIZATION_ADD:
          postSynchronizationAddPlugins =
               removePlugin(postSynchronizationAddPlugins, plugin);
          break;
        case POST_SYNCHRONIZATION_DELETE:
          postSynchronizationDeletePlugins =
               removePlugin(postSynchronizationDeletePlugins, plugin);
          break;
        case POST_SYNCHRONIZATION_MODIFY:
          postSynchronizationModifyPlugins =
               removePlugin(postSynchronizationModifyPlugins, plugin);
          break;
        case POST_SYNCHRONIZATION_MODIFY_DN:
          postSynchronizationModifyDNPlugins =
               removePlugin(postSynchronizationModifyDNPlugins, plugin);
          break;
        case SEARCH_RESULT_ENTRY:
          searchResultEntryPlugins = removePlugin(searchResultEntryPlugins,
                                                  plugin);
          break;
        case SEARCH_RESULT_REFERENCE:
          searchResultReferencePlugins =
               removePlugin(searchResultReferencePlugins, plugin);
          break;
        case SUBORDINATE_MODIFY_DN:
          subordinateModifyDNPlugins =
               removePlugin(subordinateModifyDNPlugins, plugin);
          break;
        case INTERMEDIATE_RESPONSE:
          intermediateResponsePlugins =
               removePlugin(intermediateResponsePlugins, plugin);
          break;
        default:
      }
    }
  }
opends/tests/unit-tests-testng/src/server/org/opends/server/api/plugin/DirectoryServerPluginTestCase.java
@@ -560,8 +560,9 @@
    sigList = new LinkedList<String>();
    sigList.add("initializeInternal");
    sigList.add("void");
    sigList.add("org.opends.server.admin.std.server.PluginCfg");
    sigList.add("org.opends.server.types.DN");
    sigList.add("java.util.Set");
    sigList.add("boolean");
    expectedPublicMethods.add(sigList);
    sigList = new LinkedList<String>();
@@ -821,7 +822,8 @@
      pluginTypes.add(t);
    }
    nullPlugin.initializeInternal(configuration, pluginTypes);
    nullPlugin.initializeInternal(configuration.dn(), pluginTypes,
        configuration.isInvokeForInternalOperations());
    assertEquals(nullPlugin.getPluginEntryDN(), pluginEntryDN);
  }
@@ -907,7 +909,8 @@
      pluginTypes.add(t);
    }
    nullPlugin.initializeInternal(configuration, pluginTypes);
    nullPlugin.initializeInternal(configuration.dn(), pluginTypes,
        configuration.isInvokeForInternalOperations());
    assertEquals(nullPlugin.getPluginTypes(), pluginTypes);
  }