From d8a5f7852b82181e5f9b9317e577d72372b968f7 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 04 Apr 2014 10:26:17 +0000
Subject: [PATCH] OPENDJ-1308 Migrate schema support

---
 opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java                          |  678 ++++++++++++---------------------------
 opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java |   82 ++--
 opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java   |   19 
 /dev/null                                                                                                            |   57 ---
 opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java                             |    1 
 opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java                              |   28 -
 opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java                          |   42 --
 opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java                   |   68 +--
 opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java                             |   11 
 9 files changed, 299 insertions(+), 687 deletions(-)

diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java
index 1a871cc..cbf2c28 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java
@@ -183,13 +183,22 @@
       throws DecodeException
   {
     final ByteString assertionValue = normalizeAssertionValue(value);
-    return new NotImplementedAssertion()
+    return new Assertion()
     {
+      /** {@inheritDoc} */
       @Override
       public ConditionResult matches(ByteSequence attributeValue)
       {
         return valuesMatch(attributeValue, assertionValue);
       }
+
+      /** {@inheritDoc} */
+      @Override
+      public <T> T createIndexQuery(IndexQueryFactory<T> factory)
+          throws DecodeException
+      {
+        throw new RuntimeException("Not implemented");
+      }
     };
   }
 
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java
index 81251f7..7ba3b39 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java
@@ -32,7 +32,6 @@
 import org.forgerock.opendj.ldap.ConditionResult;
 import org.forgerock.opendj.ldap.DecodeException;
 import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
-import org.opends.server.api.AbstractMatchingRule.DefaultAssertion;
 
 /**
  * This class defines the set of methods and structures that must be
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/NotImplementedAssertion.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/NotImplementedAssertion.java
deleted file mode 100644
index f9451cf..0000000
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/NotImplementedAssertion.java
+++ /dev/null
@@ -1,57 +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 legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at legal-notices/CDDLv1_0.txt.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *      Copyright 2014 ForgeRock AS
- */
-package org.opends.server.api;
-
-import org.forgerock.opendj.ldap.Assertion;
-import org.forgerock.opendj.ldap.ByteSequence;
-import org.forgerock.opendj.ldap.ConditionResult;
-import org.forgerock.opendj.ldap.DecodeException;
-import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
-
-/**
- * Avoids repeating again and again the same code when
- * Assertion.createIndexQuery() is not implemented.
- * <p>
- * To be removed once we switch the schema to the SDK.
- */
-public class NotImplementedAssertion implements Assertion
-{
-
-  /** {@inheritDoc} */
-  @Override
-  public ConditionResult matches(ByteSequence normalizedAttributeValue)
-  {
-    throw new RuntimeException("Not implemented");
-  }
-
-  /** {@inheritDoc} */
-  @Override
-  public <T> T createIndexQuery(IndexQueryFactory<T> factory)
-      throws DecodeException
-  {
-    throw new RuntimeException("Not implemented");
-  }
-
-}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
index 0ebde30..d65f259 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
@@ -42,7 +42,6 @@
 import org.forgerock.opendj.ldap.spi.IndexingOptions;
 import org.forgerock.util.Utils;
 import org.opends.server.admin.server.ConfigurationChangeListener;
-import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn;
 import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn.IndexType;
 import org.opends.server.admin.std.server.LocalDBIndexCfg;
 import org.opends.server.api.ExtensibleIndexer;
@@ -53,7 +52,10 @@
 import org.opends.server.types.*;
 import org.opends.server.util.StaticUtils;
 
-import com.sleepycat.je.*;
+import com.sleepycat.je.DatabaseEntry;
+import com.sleepycat.je.DatabaseException;
+import com.sleepycat.je.Environment;
+import com.sleepycat.je.Transaction;
 
 import static org.opends.messages.JebMessages.*;
 import static org.opends.server.util.ServerConstants.*;
@@ -76,7 +78,17 @@
 {
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
-
+  /*
+   * FIXME Matthew Swift: Once the matching rules have been migrated we should
+   * revisit this class. IMO the core indexes (equality, etc) should all be
+   * treated in the same way as extensible indexes. In other words, there should
+   * be one table mapping index ID to index and one IndexQueryFactory. Matching
+   * rules should then be able to select which indexes they need to use when
+   * evaluating searches, and all index queries should be processed using the
+   * IndexQueryFactory implementation. Moreover, all of the evaluateXXX methods
+   * should go (the Matcher class in the SDK could implement the logic, I hope).
+   * That's the theory at least...
+   */
 
   /**
    * A database key for the presence index.
@@ -88,52 +100,23 @@
    * The entryContainer in which this attribute index resides.
    */
   private EntryContainer entryContainer;
-
   private Environment env;
+  private State state;
 
   /**
    * The attribute index configuration.
    */
   private LocalDBIndexCfg indexConfig;
 
-  /**
-   * The index database for attribute equality.
-   */
-  Index equalityIndex = null;
-
-  /**
-   * The index database for attribute presence.
-   */
-  Index presenceIndex = null;
-
-  /**
-   * The index database for attribute substrings.
-   */
-  Index substringIndex = null;
-
-  /**
-   * The index database for attribute ordering.
-   */
-  Index orderingIndex = null;
-
-  /**
-   * The index database for attribute approximate.
-   */
-  Index approximateIndex = null;
-
   /** The mapping from names to indexes. */
-  private Map<String, Index> nameToIndexes;
-
-  private IndexQueryFactory<IndexQuery> indexQueryFactory;
+  private final Map<String, Index> nameToIndexes;
+  private final IndexQueryFactory<IndexQuery> indexQueryFactory;
 
   /**
    * The ExtensibleMatchingRuleIndex instance for ExtensibleMatchingRule
    * indexes.
    */
-  private  ExtensibleMatchingRuleIndex extensibleIndexes = null;
-
-  private State state;
-
+  private ExtensibleMatchingRuleIndex extensibleIndexes;
   private int cursorEntryLimit = 100000;
 
   /**
@@ -158,40 +141,41 @@
 
     AttributeType attrType = indexConfig.getAttribute();
     String name = entryContainer.getDatabasePrefix() + "_" + attrType.getNameOrOID();
+    final int indexEntryLimit = indexConfig.getIndexEntryLimit();
     final JEIndexConfig config = new JEIndexConfig(indexConfig.getSubstringLength());
 
     if (indexConfig.getIndexType().contains(IndexType.EQUALITY))
     {
-      this.equalityIndex = buildExtIndex(
-          name, attrType, attrType.getEqualityMatchingRule(), new EqualityIndexer(attrType));
+      Index equalityIndex = buildExtIndex(name, attrType, indexEntryLimit,
+          attrType.getEqualityMatchingRule(), new EqualityIndexer(attrType));
       nameToIndexes.put(IndexType.EQUALITY.toString(), equalityIndex);
     }
 
     if (indexConfig.getIndexType().contains(IndexType.PRESENCE))
     {
-      this.presenceIndex = newIndex(name + ".presence",
-          new PresenceIndexer(attrType), indexConfig.getIndexEntryLimit());
+      Index presenceIndex = newIndex(name + "." + IndexType.PRESENCE.toString(),
+          indexEntryLimit, new PresenceIndexer(attrType));
       nameToIndexes.put(IndexType.PRESENCE.toString(), presenceIndex);
     }
 
     if (indexConfig.getIndexType().contains(IndexType.SUBSTRING))
     {
-      this.substringIndex = buildExtIndex(
-          name, attrType, attrType.getSubstringMatchingRule(), new SubstringIndexer(attrType, config));
+      Index substringIndex = buildExtIndex(name, attrType, indexEntryLimit,
+          attrType.getSubstringMatchingRule(), new SubstringIndexer(attrType, config));
       nameToIndexes.put(IndexType.SUBSTRING.toString(), substringIndex);
     }
 
     if (indexConfig.getIndexType().contains(IndexType.ORDERING))
     {
-      this.orderingIndex = buildExtIndex(
-          name, attrType, attrType.getOrderingMatchingRule(), new OrderingIndexer(attrType));
+      Index orderingIndex = buildExtIndex(name, attrType, indexEntryLimit,
+          attrType.getOrderingMatchingRule(), new OrderingIndexer(attrType));
       nameToIndexes.put(IndexType.ORDERING.toString(), orderingIndex);
     }
 
     if (indexConfig.getIndexType().contains(IndexType.APPROXIMATE))
     {
-      this.approximateIndex = buildExtIndex(
-          name, attrType, attrType.getApproximateMatchingRule(), new ApproximateIndexer(attrType));
+      Index approximateIndex = buildExtIndex(name, attrType, indexEntryLimit,
+          attrType.getApproximateMatchingRule(), new ApproximateIndexer(attrType));
       nameToIndexes.put(IndexType.APPROXIMATE.toString(), approximateIndex);
     }
 
@@ -227,7 +211,7 @@
           {
             //There is no index available for this index id. Create a new index.
             String indexName = entryContainer.getDatabasePrefix() + "_" + indexID;
-            Index extIndex = newExtensibleIndex(indexName, attrType, indexer);
+            Index extIndex = newExtensibleIndex(indexName, attrType, indexEntryLimit, indexer);
             extensibleIndexes.addIndex(extIndex, indexID);
           }
           extensibleIndexes.addRule(indexID, rule);
@@ -239,15 +223,14 @@
     }
   }
 
-  private Index newIndex(String indexName, Indexer indexer,
-      int indexEntryLimit)
+  private Index newIndex(String indexName, int indexEntryLimit, Indexer indexer)
   {
     return new Index(indexName, indexer, state, indexEntryLimit,
         cursorEntryLimit, false, env, entryContainer);
   }
 
   private Index buildExtIndex(String name, AttributeType attrType,
-      MatchingRule rule, ExtensibleIndexer extIndexer) throws ConfigException
+      int indexEntryLimit, MatchingRule rule, ExtensibleIndexer extIndexer) throws ConfigException
   {
     if (rule == null)
     {
@@ -256,14 +239,14 @@
     }
 
     final String indexName = name + "." + extIndexer.getExtensibleIndexID();
-    return newExtensibleIndex(indexName, attrType, extIndexer);
+    return newExtensibleIndex(indexName, attrType, indexEntryLimit, extIndexer);
   }
 
   private Index newExtensibleIndex(String indexName, AttributeType attrType,
-      ExtensibleIndexer extIndexer)
+      int indexEntryLimit, ExtensibleIndexer extIndexer)
   {
-    return newIndex(indexName, new JEExtensibleIndexer(attrType, extIndexer),
-        indexConfig.getIndexEntryLimit());
+    JEExtensibleIndexer indexer = new JEExtensibleIndexer(attrType, extIndexer);
+    return newIndex(indexName, indexEntryLimit, indexer);
   }
 
   /**
@@ -274,12 +257,10 @@
    */
   public void open() throws DatabaseException
   {
-    open(equalityIndex);
-    open(presenceIndex);
-    open(substringIndex);
-    open(orderingIndex);
-    open(approximateIndex);
-
+    for (Index index : nameToIndexes.values())
+    {
+      index.open();
+    }
     if(extensibleIndexes!=null)
     {
       for(Index extensibleIndex:extensibleIndexes.getIndexes())
@@ -291,14 +272,6 @@
     indexConfig.addChangeListener(this);
   }
 
-  private void open(Index index)
-  {
-    if (index != null)
-    {
-      index.open();
-    }
-  }
-
   /**
    * Close the attribute index.
    *
@@ -307,9 +280,7 @@
    */
   public void close() throws DatabaseException
   {
-    Utils.closeSilently(equalityIndex, presenceIndex, substringIndex,
-        orderingIndex, approximateIndex);
-
+    Utils.closeSilently(nameToIndexes.values());
     if(extensibleIndexes!=null)
     {
       Utils.closeSilently(extensibleIndexes.getIndexes());
@@ -354,11 +325,13 @@
   {
     boolean success = true;
 
-    success = addEntry(equalityIndex, buffer, entryID, entry, success);
-    success = addEntry(presenceIndex, buffer, entryID, entry, success);
-    success = addEntry(substringIndex, buffer, entryID, entry, success);
-    success = addEntry(orderingIndex, buffer, entryID, entry, success);
-    success = addEntry(approximateIndex, buffer, entryID, entry, success);
+    for (Index index : nameToIndexes.values())
+    {
+      if (!index.addEntry(buffer, entryID, entry))
+      {
+        success = false;
+      }
+    }
 
     if(extensibleIndexes!=null)
     {
@@ -374,16 +347,6 @@
     return success;
   }
 
-  private boolean addEntry(Index index, IndexBuffer buffer, EntryID entryID,
-      Entry entry, boolean success) throws DirectoryException, DatabaseException
-  {
-    if (index != null && !index.addEntry(buffer, entryID, entry))
-    {
-      return false;
-    }
-    return success;
-  }
-
   /**
    * Update the attribute index for a new entry.
    *
@@ -400,11 +363,13 @@
   {
     boolean success = true;
 
-    success = addEntry(equalityIndex, txn, entryID, entry, success);
-    success = addEntry(presenceIndex, txn, entryID, entry, success);
-    success = addEntry(substringIndex, txn, entryID, entry, success);
-    success = addEntry(orderingIndex, txn, entryID, entry, success);
-    success = addEntry(approximateIndex, txn, entryID, entry, success);
+    for (Index index : nameToIndexes.values())
+    {
+      if (!index.addEntry(txn, entryID, entry))
+      {
+        success = false;
+      }
+    }
 
     if(extensibleIndexes!=null)
     {
@@ -420,17 +385,6 @@
     return success;
   }
 
-  private boolean addEntry(Index index, Transaction txn, EntryID entryID,
-      Entry entry, boolean success) throws DirectoryException, DatabaseException
-  {
-    if (index != null && !index.addEntry(txn, entryID, entry))
-    {
-      return false;
-    }
-    return success;
-  }
-
-
   /**
    * Update the attribute index for a deleted entry.
    *
@@ -444,11 +398,10 @@
                           Entry entry)
        throws DatabaseException, DirectoryException
   {
-    removeEntry(equalityIndex, buffer, entryID, entry);
-    removeEntry(presenceIndex, buffer, entryID, entry);
-    removeEntry(substringIndex, buffer, entryID, entry);
-    removeEntry(orderingIndex, buffer, entryID, entry);
-    removeEntry(approximateIndex, buffer, entryID, entry);
+    for (Index index : nameToIndexes.values())
+    {
+      index.removeEntry(buffer, entryID, entry);
+    }
 
     if(extensibleIndexes!=null)
     {
@@ -459,15 +412,6 @@
     }
   }
 
-  private void removeEntry(Index index, IndexBuffer buffer, EntryID entryID,
-      Entry entry) throws DirectoryException, DatabaseException
-  {
-    if (index != null)
-    {
-      index.removeEntry(buffer, entryID, entry);
-    }
-  }
-
   /**
    * Update the attribute index for a deleted entry.
    *
@@ -480,11 +424,10 @@
   public void removeEntry(Transaction txn, EntryID entryID, Entry entry)
        throws DatabaseException, DirectoryException
   {
-    removeEntry(equalityIndex, txn, entryID, entry);
-    removeEntry(presenceIndex, txn, entryID, entry);
-    removeEntry(substringIndex, txn, entryID, entry);
-    removeEntry(orderingIndex, txn, entryID, entry);
-    removeEntry(approximateIndex, txn, entryID, entry);
+    for (Index index : nameToIndexes.values())
+    {
+      index.removeEntry(txn, entryID, entry);
+    }
 
     if(extensibleIndexes!=null)
     {
@@ -495,15 +438,6 @@
     }
   }
 
-  private void removeEntry(Index index, Transaction txn, EntryID entryID,
-      Entry entry) throws DirectoryException, DatabaseException
-  {
-    if (index != null)
-    {
-      index.removeEntry(txn, entryID, entry);
-    }
-  }
-
   /**
    * Update the index to reflect a sequence of modifications in a Modify
    * operation.
@@ -523,11 +457,10 @@
                           List<Modification> mods)
        throws DatabaseException
   {
-    modifyEntry(equalityIndex, txn, entryID, oldEntry, newEntry, mods);
-    modifyEntry(presenceIndex, txn, entryID, oldEntry, newEntry, mods);
-    modifyEntry(substringIndex, txn, entryID, oldEntry, newEntry, mods);
-    modifyEntry(orderingIndex, txn, entryID, oldEntry, newEntry, mods);
-    modifyEntry(approximateIndex, txn, entryID, oldEntry, newEntry, mods);
+    for (Index index : nameToIndexes.values())
+    {
+      index.modifyEntry(txn, entryID, oldEntry, newEntry, mods);
+    }
 
     if(extensibleIndexes!=null)
     {
@@ -538,16 +471,6 @@
     }
   }
 
-  private void modifyEntry(Index index, Transaction txn, EntryID entryID,
-      Entry oldEntry, Entry newEntry, List<Modification> mods)
-      throws DatabaseException
-  {
-    if (index != null)
-    {
-      index.modifyEntry(txn, entryID, oldEntry, newEntry, mods);
-    }
-  }
-
   /**
    * Update the index to reflect a sequence of modifications in a Modify
    * operation.
@@ -567,11 +490,10 @@
                           List<Modification> mods)
        throws DatabaseException
   {
-    modifyEntry(equalityIndex, buffer, entryID, oldEntry, newEntry, mods);
-    modifyEntry(presenceIndex, buffer, entryID, oldEntry, newEntry, mods);
-    modifyEntry(substringIndex, buffer, entryID, oldEntry, newEntry, mods);
-    modifyEntry(orderingIndex, buffer, entryID, oldEntry, newEntry, mods);
-    modifyEntry(approximateIndex, buffer, entryID, oldEntry, newEntry, mods);
+    for (Index index : nameToIndexes.values())
+    {
+      index.modifyEntry(buffer, entryID, oldEntry, newEntry, mods);
+    }
 
     if(extensibleIndexes!=null)
     {
@@ -582,16 +504,6 @@
     }
   }
 
-  private void modifyEntry(Index index, IndexBuffer buffer, EntryID entryID,
-      Entry oldEntry, Entry newEntry, List<Modification> mods)
-      throws DatabaseException
-  {
-    if (index != null)
-    {
-      index.modifyEntry(buffer, entryID, oldEntry, newEntry, mods);
-    }
-  }
-
   /**
    * Makes a byte array representing a substring index key for
    * one substring of a value.
@@ -700,9 +612,8 @@
    * @return The candidate entry IDs that might contain the filter
    *         assertion value.
    */
-  public EntryIDSet evaluateEqualityFilter(SearchFilter equalityFilter,
-                                           StringBuilder debugBuffer,
-                                           DatabaseEnvironmentMonitor monitor)
+  public EntryIDSet evaluateEqualityFilter(SearchFilter equalityFilter, StringBuilder debugBuffer,
+      DatabaseEnvironmentMonitor monitor)
   {
     try {
       final MatchingRule matchRule = equalityFilter.getAttributeType().getEqualityMatchingRule();
@@ -729,9 +640,8 @@
    * @return The candidate entry IDs that might contain one or more
    *         values of the attribute type in the filter.
    */
-  public EntryIDSet evaluatePresenceFilter(SearchFilter filter,
-                                           StringBuilder debugBuffer,
-                                           DatabaseEnvironmentMonitor monitor)
+  public EntryIDSet evaluatePresenceFilter(SearchFilter filter, StringBuilder debugBuffer,
+      DatabaseEnvironmentMonitor monitor)
   {
     final IndexQuery indexQuery = indexQueryFactory.createMatchAllQuery();
     return evaluateIndexQuery(indexQuery, "presence", filter, debugBuffer, monitor);
@@ -749,8 +659,7 @@
    * @return The candidate entry IDs that might contain a value
    *         greater than or equal to the filter assertion value.
    */
-  public EntryIDSet evaluateGreaterOrEqualFilter(
-      SearchFilter filter, StringBuilder debugBuffer,
+  public EntryIDSet evaluateGreaterOrEqualFilter(SearchFilter filter, StringBuilder debugBuffer,
       DatabaseEnvironmentMonitor monitor)
   {
     return evaluateOrderingFilter(filter, true, debugBuffer, monitor);
@@ -901,10 +810,7 @@
       {
         return 1;
       }
-      else
-      {
-        return -1;
-      }
+      return -1;
     }
   }
 
@@ -954,10 +860,7 @@
       {
         return 1;
       }
-      else
-      {
-        return -1;
-      }
+      return -1;
     }
   }
 
@@ -995,29 +898,9 @@
    * @throws DatabaseException If a database error occurs.
    */
   public void closeCursors() throws DatabaseException {
-    if (equalityIndex != null)
+    for (Index index : nameToIndexes.values())
     {
-      equalityIndex.closeCursor();
-    }
-
-    if (presenceIndex != null)
-    {
-      presenceIndex.closeCursor();
-    }
-
-    if (substringIndex != null)
-    {
-      substringIndex.closeCursor();
-    }
-
-    if (orderingIndex != null)
-    {
-      orderingIndex.closeCursor();
-    }
-
-    if (approximateIndex != null)
-    {
-      approximateIndex.closeCursor();
+      index.closeCursor();
     }
 
     if(extensibleIndexes!=null)
@@ -1039,38 +922,16 @@
   {
     long entryLimitExceededCount = 0;
 
-    if (equalityIndex != null)
+    for (Index index : nameToIndexes.values())
     {
-      entryLimitExceededCount += equalityIndex.getEntryLimitExceededCount();
+      entryLimitExceededCount += index.getEntryLimitExceededCount();
     }
 
-    if (presenceIndex != null)
-    {
-      entryLimitExceededCount += presenceIndex.getEntryLimitExceededCount();
-    }
-
-    if (substringIndex != null)
-    {
-      entryLimitExceededCount += substringIndex.getEntryLimitExceededCount();
-    }
-
-    if (orderingIndex != null)
-    {
-      entryLimitExceededCount += orderingIndex.getEntryLimitExceededCount();
-    }
-
-    if (approximateIndex != null)
-    {
-      entryLimitExceededCount +=
-          approximateIndex.getEntryLimitExceededCount();
-    }
-
-     if(extensibleIndexes!=null)
+    if (extensibleIndexes != null)
     {
       for(Index extensibleIndex:extensibleIndexes.getIndexes())
       {
-        entryLimitExceededCount +=
-                extensibleIndex.getEntryLimitExceededCount();
+        entryLimitExceededCount += extensibleIndex.getEntryLimitExceededCount();
       }
     }
     return entryLimitExceededCount;
@@ -1082,11 +943,7 @@
    */
   public void listDatabases(List<DatabaseContainer> dbList)
   {
-    addIfNotNull(dbList, equalityIndex);
-    addIfNotNull(dbList, presenceIndex);
-    addIfNotNull(dbList, substringIndex);
-    addIfNotNull(dbList, orderingIndex);
-    addIfNotNull(dbList, approximateIndex);
+    dbList.addAll(nameToIndexes.values());
 
     if(extensibleIndexes!=null)
     {
@@ -1094,14 +951,6 @@
     }
   }
 
-  private void addIfNotNull(Collection<? super Index> dbList, Index index)
-  {
-    if (index != null)
-    {
-      dbList.add(index);
-    }
-  }
-
   /**
    * Get a string representation of this object.
    * @return return A string representation of this object.
@@ -1115,42 +964,39 @@
   /** {@inheritDoc} */
   @Override
   public synchronized boolean isConfigurationChangeAcceptable(
-      LocalDBIndexCfg cfg,
-      List<LocalizableMessage> unacceptableReasons)
+      LocalDBIndexCfg cfg, List<LocalizableMessage> unacceptableReasons)
   {
     AttributeType attrType = cfg.getAttribute();
 
-    if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.EQUALITY)
-        && equalityIndex == null
+    if (cfg.getIndexType().contains(IndexType.EQUALITY)
+        && nameToIndexes.get(IndexType.EQUALITY.toString()) == null
         && attrType.getEqualityMatchingRule() == null)
     {
       unacceptableReasons.add(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, "equality"));
       return false;
     }
-
-    if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.SUBSTRING)
-        && substringIndex == null
+    if (cfg.getIndexType().contains(IndexType.SUBSTRING)
+        && nameToIndexes.get(IndexType.SUBSTRING.toString()) == null
         && attrType.getSubstringMatchingRule() == null)
     {
       unacceptableReasons.add(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, "substring"));
       return false;
     }
-
-    if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.ORDERING)
-        && orderingIndex == null
+    if (cfg.getIndexType().contains(IndexType.ORDERING)
+        && nameToIndexes.get(IndexType.ORDERING.toString()) == null
         && attrType.getOrderingMatchingRule() == null)
     {
       unacceptableReasons.add(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, "ordering"));
       return false;
     }
-    if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.APPROXIMATE)
-        && approximateIndex == null
+    if (cfg.getIndexType().contains(IndexType.APPROXIMATE)
+        && nameToIndexes.get(IndexType.APPROXIMATE.toString()) == null
         && attrType.getApproximateMatchingRule() == null)
     {
       unacceptableReasons.add(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, "approximate"));
       return false;
     }
-    if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.EXTENSIBLE))
+    if (cfg.getIndexType().contains(IndexType.EXTENSIBLE))
     {
       Set<String> newRules = cfg.getIndexExtensibleMatchingRule();
       if (newRules == null || newRules.isEmpty())
@@ -1178,56 +1024,23 @@
       final int indexEntryLimit = cfg.getIndexEntryLimit();
       final JEIndexConfig config = new JEIndexConfig(cfg.getSubstringLength());
 
-      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.EQUALITY))
-      {
-        if (equalityIndex == null)
-        {
-          equalityIndex = openNewIndex(name, attrType,
-              new EqualityIndexer(attrType), adminActionRequired, messages);
-          nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.EQUALITY.toString(), equalityIndex);
-        }
-        else
-        {
-          // already exists. Just update index entry limit.
-          if(this.equalityIndex.setIndexEntryLimit(indexEntryLimit))
-          {
-            adminActionRequired.set(true);
-            messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(equalityIndex.getName()));
-            this.equalityIndex.setIndexEntryLimit(indexEntryLimit);
-          }
-        }
-      }
-      else
-      {
-        if (equalityIndex != null)
-        {
-          entryContainer.exclusiveLock.lock();
-          try
-          {
-            nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.EQUALITY.toString());
-            entryContainer.deleteDatabase(equalityIndex);
-            equalityIndex = null;
-          }
-          finally
-          {
-            entryContainer.exclusiveLock.unlock();
-          }
-        }
-      }
+      applyChangeToIndex(cfg, attrType, name, IndexType.EQUALITY,
+          new EqualityIndexer(attrType), adminActionRequired, messages);
 
-      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.PRESENCE))
+      Index presenceIndex = nameToIndexes.get(IndexType.PRESENCE.toString());
+      if (cfg.getIndexType().contains(IndexType.PRESENCE))
       {
         if(presenceIndex == null)
         {
           Indexer presenceIndexer = new PresenceIndexer(attrType);
-          presenceIndex = newIndex(name + ".presence", presenceIndexer, indexEntryLimit);
+          presenceIndex = newIndex(name + ".presence", indexEntryLimit, presenceIndexer);
           openIndex(presenceIndex, adminActionRequired, messages);
-          nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.PRESENCE.toString(), presenceIndex);
+          nameToIndexes.put(IndexType.PRESENCE.toString(), presenceIndex);
         }
         else
         {
           // already exists. Just update index entry limit.
-          if(this.presenceIndex.setIndexEntryLimit(indexEntryLimit))
+          if(presenceIndex.setIndexEntryLimit(indexEntryLimit))
           {
             adminActionRequired.set(true);
             messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(presenceIndex.getName()));
@@ -1236,37 +1049,25 @@
       }
       else
       {
-        if (presenceIndex != null)
-        {
-          entryContainer.exclusiveLock.lock();
-          try
-          {
-            nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.PRESENCE.toString());
-            entryContainer.deleteDatabase(presenceIndex);
-            presenceIndex = null;
-          }
-          finally
-          {
-            entryContainer.exclusiveLock.unlock();
-          }
-        }
+        removeIndex(presenceIndex, IndexType.PRESENCE);
       }
 
-      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.SUBSTRING))
+      Index substringIndex = nameToIndexes.get(IndexType.SUBSTRING.toString());
+      if (cfg.getIndexType().contains(IndexType.SUBSTRING))
       {
         SubstringIndexer indexer = new SubstringIndexer(attrType, config);
         Indexer extIndexer = new JEExtensibleIndexer(attrType, indexer);
         if(substringIndex == null)
         {
           Index index = newIndex(name + "." + indexer.getExtensibleIndexID(),
-              extIndexer, indexEntryLimit);
+              indexEntryLimit, extIndexer);
           substringIndex = openIndex(index, adminActionRequired, messages);
-          nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.SUBSTRING.toString(), substringIndex);
+          nameToIndexes.put(IndexType.SUBSTRING.toString(), substringIndex);
         }
         else
         {
           // already exists. Just update index entry limit.
-          if(this.substringIndex.setIndexEntryLimit(indexEntryLimit))
+          if(substringIndex.setIndexEntryLimit(indexEntryLimit))
           {
             adminActionRequired.set(true);
             messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(substringIndex.getName()));
@@ -1274,101 +1075,21 @@
 
           if (indexConfig.getSubstringLength() != cfg.getSubstringLength())
           {
-            this.substringIndex.setIndexer(extIndexer);
+            substringIndex.setIndexer(extIndexer);
           }
         }
       }
       else
       {
-        if (substringIndex != null)
-        {
-          entryContainer.exclusiveLock.lock();
-          try
-          {
-            nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.SUBSTRING.toString());
-            entryContainer.deleteDatabase(substringIndex);
-            substringIndex = null;
-          }
-          finally
-          {
-            entryContainer.exclusiveLock.unlock();
-          }
-        }
+        removeIndex(substringIndex, IndexType.SUBSTRING);
       }
 
-      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.ORDERING))
-      {
-        if(orderingIndex == null)
-        {
-          orderingIndex = openNewIndex(name, attrType,
-              new OrderingIndexer(attrType), adminActionRequired, messages);
-          nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.ORDERING.toString(), orderingIndex);
-        }
-        else
-        {
-          // already exists. Just update index entry limit.
-          if(this.orderingIndex.setIndexEntryLimit(indexEntryLimit))
-          {
-            adminActionRequired.set(true);
-            messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(orderingIndex.getName()));
-          }
-        }
-      }
-      else
-      {
-        if (orderingIndex != null)
-        {
-          entryContainer.exclusiveLock.lock();
-          try
-          {
-            nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.ORDERING.toString());
-            entryContainer.deleteDatabase(orderingIndex);
-            orderingIndex = null;
-          }
-          finally
-          {
-            entryContainer.exclusiveLock.unlock();
-          }
-        }
-      }
+      applyChangeToIndex(cfg, attrType, name, IndexType.ORDERING,
+          new OrderingIndexer(attrType), adminActionRequired, messages);
+      applyChangeToIndex(cfg, attrType, name, IndexType.APPROXIMATE,
+          new ApproximateIndexer(attrType), adminActionRequired, messages);
 
-      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.APPROXIMATE))
-      {
-        if(approximateIndex == null)
-        {
-          approximateIndex = openNewIndex(name, attrType,
-              new ApproximateIndexer(attrType), adminActionRequired, messages);
-          nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.APPROXIMATE.toString(), approximateIndex);
-        }
-        else
-        {
-          // already exists. Just update index entry limit.
-          if(this.approximateIndex.setIndexEntryLimit(indexEntryLimit))
-          {
-            adminActionRequired.set(true);
-            messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(approximateIndex.getName()));
-          }
-        }
-      }
-      else
-      {
-        if (approximateIndex != null)
-        {
-          entryContainer.exclusiveLock.lock();
-          try
-          {
-            nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.APPROXIMATE.toString());
-            entryContainer.deleteDatabase(approximateIndex);
-            approximateIndex = null;
-          }
-          finally
-          {
-            entryContainer.exclusiveLock.unlock();
-          }
-        }
-      }
-
-      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.EXTENSIBLE))
+      if (cfg.getIndexType().contains(IndexType.EXTENSIBLE))
       {
         Set<String> extensibleRules = cfg.getIndexExtensibleMatchingRule();
         Set<ExtensibleMatchingRule> validRules = new HashSet<ExtensibleMatchingRule>();
@@ -1392,7 +1113,7 @@
             if(!extensibleIndexes.isIndexPresent(indexID))
             {
               String indexName =  entryContainer.getDatabasePrefix() + "_" + indexID;
-              Index extIndex = newExtensibleIndex(indexName, attrType, indexer);
+              Index extIndex = newExtensibleIndex(indexName, attrType, indexEntryLimit, indexer);
               extensibleIndexes.addIndex(extIndex,indexID);
               openIndex(extIndex, adminActionRequired, messages);
             }
@@ -1427,14 +1148,13 @@
           {
             for(ExtensibleMatchingRule rule:deletedRules)
             {
-              Set<ExtensibleMatchingRule> rules =
-                      new HashSet<ExtensibleMatchingRule>();
+              Set<ExtensibleMatchingRule> rules = new HashSet<ExtensibleMatchingRule>();
               List<String> ids = new ArrayList<String>();
               for (ExtensibleIndexer indexer : rule.getIndexers())
               {
                 String id = attrType.getNameOrOID()  + "." + indexer.getIndexID();
-                rules.addAll(extensibleIndexes.getRules(id));
                 ids.add(id);
+                rules.addAll(extensibleIndexes.getRules(id));
               }
               if(rules.isEmpty())
               {
@@ -1500,12 +1220,60 @@
     }
   }
 
-  private Index openNewIndex(String name, AttributeType attrType,
-      ExtensibleIndexer indexer, AtomicBoolean adminActionRequired,
-      ArrayList<LocalizableMessage> messages)
+  private void applyChangeToIndex(LocalDBIndexCfg cfg, AttributeType attrType,
+      String name, IndexType indexType, ExtensibleIndexer indexer,
+      AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
   {
-    String indexName = name + "." + indexer.getExtensibleIndexID();
-    Index index = newExtensibleIndex(indexName, attrType, indexer);
+    final int indexEntryLimit = cfg.getIndexEntryLimit();
+
+    Index index = nameToIndexes.get(indexType.toString());
+    if (cfg.getIndexType().contains(indexType))
+    {
+      if (index == null)
+      {
+        index = openNewIndex(name, attrType, indexEntryLimit,
+            indexer, adminActionRequired, messages);
+        nameToIndexes.put(indexType.toString(), index);
+      }
+      else
+      {
+        // already exists. Just update index entry limit.
+        if(index.setIndexEntryLimit(indexEntryLimit))
+        {
+          adminActionRequired.set(true);
+          messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(index.getName()));
+        }
+      }
+    }
+    else
+    {
+      removeIndex(index, indexType);
+    }
+  }
+
+  private void removeIndex(Index index, IndexType indexType)
+  {
+    if (index != null)
+    {
+      entryContainer.exclusiveLock.lock();
+      try
+      {
+        nameToIndexes.remove(indexType.toString());
+        entryContainer.deleteDatabase(index);
+      }
+      finally
+      {
+        entryContainer.exclusiveLock.unlock();
+      }
+    }
+  }
+
+  private Index openNewIndex(String name, AttributeType attrType,
+      int indexEntryLimit, ExtensibleIndexer indexer,
+      AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
+  {
+    final String indexName = name + "." + indexer.getExtensibleIndexID();
+    Index index = newExtensibleIndex(indexName, attrType, indexEntryLimit, indexer);
     return openIndex(index, adminActionRequired, messages);
   }
 
@@ -1532,11 +1300,10 @@
   public synchronized void setTrusted(Transaction txn, boolean trusted)
       throws DatabaseException
   {
-    setTrusted(equalityIndex, txn, trusted);
-    setTrusted(presenceIndex, txn, trusted);
-    setTrusted(substringIndex, txn, trusted);
-    setTrusted(orderingIndex, txn, trusted);
-    setTrusted(approximateIndex, txn, trusted);
+    for (Index index : nameToIndexes.values())
+    {
+      index.setTrusted(txn, trusted);
+    }
 
     if(extensibleIndexes!=null)
     {
@@ -1547,34 +1314,25 @@
     }
   }
 
-  private void setTrusted(Index index, Transaction txn, boolean trusted)
-  {
-    if (index != null)
-    {
-      index.setTrusted(txn, trusted);
-    }
-  }
-
   /**
    * Return true iff this index is trusted.
    * @return the trusted state of this index
    */
   public boolean isTrusted()
   {
-    if ((equalityIndex != null && !equalityIndex.isTrusted())
-        || (presenceIndex != null && !presenceIndex.isTrusted())
-        || (substringIndex != null && !substringIndex.isTrusted())
-        || (orderingIndex != null && !orderingIndex.isTrusted())
-        || (approximateIndex != null && !approximateIndex.isTrusted()))
+    for (Index index : nameToIndexes.values())
     {
-      return false;
+      if (!index.isTrusted())
+      {
+        return false;
+      }
     }
 
     if(extensibleIndexes!=null)
     {
       for(Index extensibleIndex:extensibleIndexes.getIndexes())
       {
-        if(extensibleIndex !=null && !extensibleIndex.isTrusted())
+        if (!extensibleIndex.isTrusted())
         {
           return false;
         }
@@ -1591,11 +1349,10 @@
    */
   public synchronized void setRebuildStatus(boolean rebuildRunning)
   {
-    setRebuildStatus(rebuildRunning, equalityIndex);
-    setRebuildStatus(rebuildRunning, presenceIndex);
-    setRebuildStatus(rebuildRunning, substringIndex);
-    setRebuildStatus(rebuildRunning, orderingIndex);
-    setRebuildStatus(rebuildRunning, approximateIndex);
+    for (Index index : nameToIndexes.values())
+    {
+      index.setRebuildStatus(rebuildRunning);
+    }
 
     if(extensibleIndexes!=null)
     {
@@ -1606,14 +1363,6 @@
     }
   }
 
-  private void setRebuildStatus(boolean rebuildRunning, Index index)
-  {
-    if (index != null)
-    {
-      index.setRebuildStatus(rebuildRunning);
-    }
-  }
-
   /**
    * Get the JE database name prefix for indexes in this attribute index.
    *
@@ -1632,7 +1381,7 @@
    * @return The equality index.
    */
   public Index getEqualityIndex() {
-    return  equalityIndex;
+    return nameToIndexes.get(IndexType.EQUALITY.toString());
   }
 
   /**
@@ -1641,7 +1390,7 @@
    * @return The approximate index.
    */
   public Index getApproximateIndex() {
-    return approximateIndex;
+    return nameToIndexes.get(IndexType.APPROXIMATE.toString());
   }
 
   /**
@@ -1650,7 +1399,7 @@
    * @return  The ordering index.
    */
   public Index getOrderingIndex() {
-    return orderingIndex;
+    return nameToIndexes.get(IndexType.ORDERING.toString());
   }
 
   /**
@@ -1659,7 +1408,7 @@
    * @return The substring index.
    */
   public Index getSubstringIndex() {
-    return substringIndex;
+    return nameToIndexes.get(IndexType.SUBSTRING.toString());
   }
 
   /**
@@ -1668,7 +1417,7 @@
    * @return The presence index.
    */
   public Index getPresenceIndex() {
-    return presenceIndex;
+    return nameToIndexes.get(IndexType.PRESENCE.toString());
   }
 
   /**
@@ -1678,11 +1427,11 @@
    */
   public Map<String,Collection<Index>> getExtensibleIndexes()
   {
-    if(extensibleIndexes == null)
+    if (extensibleIndexes != null)
     {
-      return Collections.emptyMap();
+      return extensibleIndexes.getIndexMap();
     }
-    return extensibleIndexes.getIndexMap();
+    return Collections.emptyMap();
   }
 
 
@@ -1694,19 +1443,11 @@
    */
   public Collection<Index> getAllIndexes() {
     LinkedHashSet<Index> indexes = new LinkedHashSet<Index>();
-
-    addIfNotNull(indexes, equalityIndex);
-    addIfNotNull(indexes, presenceIndex);
-    addIfNotNull(indexes, substringIndex);
-    addIfNotNull(indexes, orderingIndex);
-    addIfNotNull(indexes, approximateIndex);
+    indexes.addAll(nameToIndexes.values());
 
     if(extensibleIndexes!=null)
     {
-      for(Index extensibleIndex:extensibleIndexes.getIndexes())
-      {
-        indexes.add(extensibleIndex);
-      }
+      indexes.addAll(extensibleIndexes.getIndexes());
     }
     return indexes;
   }
@@ -1715,7 +1456,7 @@
   /**
    * Retrieve the entry IDs that might match an extensible filter.
    *
-   * @param extensibleFilter The extensible filter.
+   * @param filter The extensible filter.
    * @param debugBuffer If not null, a diagnostic string will be written
    *                     which will help determine how the indexes contributed
    *                     to this search.
@@ -1724,12 +1465,12 @@
    * @return The candidate entry IDs that might contain the filter
    *         assertion value.
    */
-  public EntryIDSet evaluateExtensibleFilter(SearchFilter extensibleFilter,
+  public EntryIDSet evaluateExtensibleFilter(SearchFilter filter,
                                              StringBuilder debugBuffer,
                                              DatabaseEnvironmentMonitor monitor)
   {
     //Get the Matching Rule OID of the filter.
-    String matchRuleOID  = extensibleFilter.getMatchingRuleID();
+    String matchRuleOID  = filter.getMatchingRuleID();
     /**
      * Use the default equality index in two conditions:
      * 1. There is no matching rule provided
@@ -1741,7 +1482,7 @@
         || matchRuleOID.equalsIgnoreCase(eqRule.getNameOrOID()))
     {
       //No matching rule is defined; use the default equality matching rule.
-      return evaluateEqualityFilter(extensibleFilter, debugBuffer, monitor);
+      return evaluateEqualityFilter(filter, debugBuffer, monitor);
     }
 
     ExtensibleMatchingRule rule = DirectoryServer.getExtensibleMatchingRule(matchRuleOID);
@@ -1751,7 +1492,7 @@
       // There is no index on this matching rule.
       if (monitor.isFilterUseEnabled())
       {
-        monitor.updateStats(extensibleFilter, INFO_JEB_INDEX_FILTER_MATCHING_RULE_NOT_INDEXED.get(
+        monitor.updateStats(filter, INFO_JEB_INDEX_FILTER_MATCHING_RULE_NOT_INDEXED.get(
             matchRuleOID, indexConfig.getAttribute().getNameOrOID()));
       }
       return IndexQuery.createNullIndexQuery().evaluate(null);
@@ -1765,28 +1506,28 @@
         for (ExtensibleIndexer indexer : rule.getIndexers())
         {
           debugBuffer.append(" ")
-                     .append(extensibleFilter.getAttributeType().getNameOrOID())
+                     .append(filter.getAttributeType().getNameOrOID())
                      .append(".")
                      .append(indexer.getIndexID());
         }
         debugBuffer.append("]");
       }
-      ByteString assertionValue = extensibleFilter.getAssertionValue();
-      IndexQuery expression = rule.createIndexQuery(assertionValue, factory);
+      ByteString assertionValue = filter.getAssertionValue();
+      IndexQuery indexQuery = rule.createIndexQuery(assertionValue, factory);
       LocalizableMessageBuilder debugMessage = monitor.isFilterUseEnabled() ? new LocalizableMessageBuilder() : null;
-      EntryIDSet idSet = expression.evaluate(debugMessage);
+      EntryIDSet results = indexQuery.evaluate(debugMessage);
       if (monitor.isFilterUseEnabled())
       {
-        if (idSet.isDefined())
+        if (results.isDefined())
         {
-          monitor.updateStats(extensibleFilter, idSet.size());
+          monitor.updateStats(filter, results.size());
         }
         else
         {
-          monitor.updateStats(extensibleFilter, debugMessage.toMessage());
+          monitor.updateStats(filter, debugMessage.toMessage());
         }
       }
-      return idSet;
+      return results;
     }
     catch (DecodeException e)
     {
@@ -2031,7 +1772,6 @@
     /** The length of the substring index. */
     private int substringLength;
 
-
     /**
      * Creates a new JEIndexConfig instance.
      * @param substringLength The length of the substring.
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java
index 6deb4fe..0890092 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -3271,52 +3271,22 @@
   /**
    * Removes a attribute index from disk.
    *
-   * @param index The attribute index to remove.
+   * @param attributeIndex The attribute index to remove.
    * @throws DatabaseException If an JE database error occurs while attempting
    * to delete the index.
    */
-  public void deleteAttributeIndex(AttributeIndex index)
+  public void deleteAttributeIndex(AttributeIndex attributeIndex)
   throws DatabaseException
   {
-    index.close();
+    attributeIndex.close();
     Transaction txn = env.getConfig().getTransactional()
       ? beginTransaction() : null;
     try
     {
-      if(index.equalityIndex != null)
+      for (Index index : attributeIndex.getAllIndexes())
       {
-        env.removeDatabase(txn, index.equalityIndex.getName());
-        state.removeIndexTrustState(txn, index.equalityIndex);
-      }
-      if(index.presenceIndex != null)
-      {
-        env.removeDatabase(txn, index.presenceIndex.getName());
-        state.removeIndexTrustState(txn, index.presenceIndex);
-      }
-      if(index.substringIndex != null)
-      {
-        env.removeDatabase(txn, index.substringIndex.getName());
-        state.removeIndexTrustState(txn, index.substringIndex);
-      }
-      if(index.orderingIndex != null)
-      {
-        env.removeDatabase(txn, index.orderingIndex.getName());
-        state.removeIndexTrustState(txn, index.orderingIndex);
-      }
-      if(index.approximateIndex != null)
-      {
-        env.removeDatabase(txn, index.approximateIndex.getName());
-        state.removeIndexTrustState(txn, index.approximateIndex);
-      }
-      Map <String,Collection<Index>> extensibleIndexes =
-        index.getExtensibleIndexes();
-      for (String name : extensibleIndexes.keySet())
-      {
-        for (Index extensibleIndex : extensibleIndexes.get(name))
-        {
-          env.removeDatabase(txn, extensibleIndex.getName());
-          state.removeIndexTrustState(txn, extensibleIndex);
-        }
+        env.removeDatabase(txn, index.getName());
+        state.removeIndexTrustState(txn, index);
       }
       if (txn != null)
       {
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java
index c15aa73..418626b 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java
@@ -24,19 +24,14 @@
  *      Copyright 2009-2010 Sun Microsystems, Inc.
  *      Portions Copyright 2014 ForgeRock AS
  */
-
 package org.opends.server.backends.jeb;
 
-
-
-import org.forgerock.i18n.LocalizableMessageBuilder;
-
 import java.util.Collection;
 
+import org.forgerock.i18n.LocalizableMessageBuilder;
+
 import static org.opends.server.backends.jeb.IndexFilter.*;
 
-
-
 /**
  * This class represents a JE Backend Query.
  */
@@ -111,10 +106,7 @@
    */
   private static final class NullIndexQuery extends IndexQuery
   {
-    /**
-     * {@inheritDoc}
-     * @param debugMessages
-     */
+    /** {@inheritDoc} */
     @Override
     public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
     {
@@ -146,12 +138,7 @@
       this.subIndexQueries = subIndexQueries;
     }
 
-
-
-    /**
-     * {@inheritDoc}
-     * @param debugMessages
-     */
+    /** {@inheritDoc} */
     @Override
     public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
     {
@@ -199,12 +186,7 @@
       this.subIndexQueries = subIndexQueries;
     }
 
-
-
-    /**
-     * {@inheritDoc}
-     * @param debugMessages
-     */
+    /** {@inheritDoc} */
     @Override
     public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
     {
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java
index 92386d9..7dd2eef 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java
@@ -73,8 +73,7 @@
 
   /** {@inheritDoc} */
   @Override
-  public IndexQuery createExactMatchQuery(final String indexID,
-      final ByteSequence value)
+  public IndexQuery createExactMatchQuery(final String indexID, final ByteSequence value)
   {
     return new IndexQuery()
       {
@@ -98,18 +97,7 @@
           EntryIDSet entrySet = index.readKey(key, null, LockMode.DEFAULT);
           if(debugMessage != null && !entrySet.isDefined())
           {
-            if(!index.isTrusted())
-            {
-              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(index.getName()));
-            }
-            else if(index.isRebuildRunning())
-            {
-              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(index.getName()));
-            }
-            else
-            {
-              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(index.getName()));
-            }
+            updateStatsUndefinedResults(debugMessage, index);
           }
           return entrySet;
         }
@@ -144,18 +132,7 @@
               includeLowerBound, includeUpperBound);
           if(debugMessage != null && !entrySet.isDefined())
           {
-            if(!index.isTrusted())
-            {
-              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(index.getName()));
-            }
-            else if(index.isRebuildRunning())
-            {
-              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(index.getName()));
-            }
-            else
-            {
-              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(index.getName()));
-            }
+            updateStatsUndefinedResults(debugMessage, index);
           }
           return entrySet;
         }
@@ -166,8 +143,7 @@
 
   /** {@inheritDoc} */
   @Override
-  public IndexQuery createIntersectionQuery(
-      Collection<IndexQuery> subqueries)
+  public IndexQuery createIntersectionQuery(Collection<IndexQuery> subqueries)
   {
     return IndexQuery.createIntersectionIndexQuery(subqueries);
   }
@@ -197,39 +173,43 @@
         @Override
         public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
         {
-          Index index = indexMap.get(PRESENCE_INDEX_KEY);
+        final String indexID = PRESENCE_INDEX_KEY;
+        final Index index = indexMap.get(indexID);
           if (index == null)
           {
             if(debugMessage != null)
             {
-              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get(index.getName(), ""));
+              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get(indexID, ""));
             }
             return new EntryIDSet();
           }
 
           EntryIDSet entrySet = index.readKey(AttributeIndex.presenceKey, null, LockMode.DEFAULT);
-
           if (debugMessage != null && !entrySet.isDefined())
           {
-            if (!index.isTrusted())
-            {
-              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(index.getName()));
-            }
-            else if (index.isRebuildRunning())
-            {
-              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(index.getName()));
-            }
-            else
-            {
-              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(index.getName()));
-            }
+            updateStatsUndefinedResults(debugMessage, index);
           }
-
           return entrySet;
         }
       };
   }
 
+  private static void updateStatsUndefinedResults(LocalizableMessageBuilder debugMessage, Index index)
+  {
+    if (!index.isTrusted())
+    {
+      debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(index.getName()));
+    }
+    else if (index.isRebuildRunning())
+    {
+      debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(index.getName()));
+    }
+    else
+    {
+      debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(index.getName()));
+    }
+  }
+
   /** {@inheritDoc} */
   @Override
   public IndexingOptions getIndexingOptions()
diff --git a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
index a4539be6..0d33762 100644
--- a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
+++ b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
@@ -47,6 +47,12 @@
 import org.opends.server.protocols.internal.InternalSearchOperation;
 import org.opends.server.protocols.ldap.LDAPFilter;
 import org.opends.server.types.*;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.Attributes;
+import org.opends.server.types.DN;
+import org.opends.server.types.Entry;
+import org.opends.server.types.Modification;
+import org.opends.server.types.RDN;
 import org.opends.server.util.Base64;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -795,22 +801,17 @@
           entries.get(0).getAttribute("cn").get(0).getAttributeType();
       AttributeIndex index = ec.getAttributeIndex(attribute);
 
-
       Indexer presenceIndexer = new PresenceIndexer(index.getAttributeType());
-      assertIndexContainsID(presenceIndexer, entry, index.presenceIndex,
-          entryID, FALSE);
+      assertIndexContainsID(presenceIndexer, entry, index.getPresenceIndex(), entryID, FALSE);
 
       Indexer equalityIndexer = newEqualityIndexer(index);
-      assertIndexContainsID(equalityIndexer, entry, index.equalityIndex,
-          entryID, FALSE);
+      assertIndexContainsID(equalityIndexer, entry, index.getEqualityIndex(), entryID, FALSE);
 
       Indexer substringIndexer = newSubstringIndexer(index);
-      assertIndexContainsID(substringIndexer, entry, index.substringIndex,
-          entryID, FALSE);
+      assertIndexContainsID(substringIndexer, entry, index.getSubstringIndex(), entryID, FALSE);
 
       Indexer orderingIndexer = newOrderingIndexer(index);
-      assertIndexContainsID(orderingIndexer, entry, index.orderingIndex,
-          entryID, FALSE);
+      assertIndexContainsID(orderingIndexer, entry, index.getOrderingIndex(), entryID, FALSE);
     }
     finally
     {
@@ -909,22 +910,16 @@
       AttributeIndex index = ec.getAttributeIndex(attribute);
 
       Indexer orderingIndexer = newOrderingIndexer(index);
-      assertIndexContainsID(orderingIndexer, entry, index.orderingIndex,
-          entryID, TRUE);
-      assertIndexContainsID(orderingIndexer, oldEntry, index.orderingIndex,
-          entryID, FALSE);
+      assertIndexContainsID(orderingIndexer, entry, index.getOrderingIndex(), entryID, TRUE);
+      assertIndexContainsID(orderingIndexer, oldEntry, index.getOrderingIndex(), entryID, FALSE);
 
       Indexer substringIndexer = newSubstringIndexer(index);
-      assertIndexContainsID(substringIndexer, entry, index.substringIndex,
-          entryID, TRUE);
-      assertIndexContainsID(substringIndexer, oldEntry, index.substringIndex,
-          entryID, FALSE);
+      assertIndexContainsID(substringIndexer, entry, index.getSubstringIndex(), entryID, TRUE);
+      assertIndexContainsID(substringIndexer, oldEntry, index.getSubstringIndex(), entryID, FALSE);
 
       Indexer equalityIndexer = newEqualityIndexer(index);
-      assertIndexContainsID(equalityIndexer, entry, index.equalityIndex,
-          entryID, TRUE);
-      assertIndexContainsID(equalityIndexer, oldEntry, index.equalityIndex,
-          entryID, FALSE);
+      assertIndexContainsID(equalityIndexer, entry, index.getEqualityIndex(), entryID, TRUE);
+      assertIndexContainsID(equalityIndexer, oldEntry, index.getEqualityIndex(), entryID, FALSE);
     }
     finally
     {
@@ -998,16 +993,15 @@
       // This current entry in the DB shouldn't be in the presence titleIndex.
       addKeys = new HashSet<ByteString>();
       addKeys.add(ByteString.wrap(AttributeIndex.presenceKey.getData()));
-      assertIndexContainsID(addKeys, titleIndex.presenceIndex, entryID, FALSE);
+      assertIndexContainsID(addKeys, titleIndex.getPresenceIndex(), entryID, FALSE);
 
       // This current entry should be in the presence nameIndex.
       addKeys = new HashSet<ByteString>();
       addKeys.add(ByteString.wrap(AttributeIndex.presenceKey.getData()));
-      assertIndexContainsID(addKeys, nameIndex.presenceIndex, entryID, TRUE);
+      assertIndexContainsID(addKeys, nameIndex.getPresenceIndex(), entryID, TRUE);
 
       List<Control> noControls = new ArrayList<Control>(0);
-      InternalClientConnection conn = InternalClientConnection
-          .getRootConnection();
+      InternalClientConnection conn = InternalClientConnection.getRootConnection();
 
       ModifyOperationBasis modifyOp = new ModifyOperationBasis(conn, InternalClientConnection
           .nextOperationID(), InternalClientConnection.nextMessageID(), noControls, DN
@@ -1043,28 +1037,28 @@
           Attributes.create("employeenumber", "1")));
 
       presenceIndexer = new PresenceIndexer(titleIndex.getAttributeType());
-      assertIndexContainsID(presenceIndexer, entry, titleIndex.presenceIndex, entryID);
+      assertIndexContainsID(presenceIndexer, entry, titleIndex.getPresenceIndex(), entryID);
 
       presenceIndexer = new PresenceIndexer(nameIndex.getAttributeType());
-      assertIndexContainsID(presenceIndexer, entry, nameIndex.presenceIndex, entryID);
+      assertIndexContainsID(presenceIndexer, entry, nameIndex.getPresenceIndex(), entryID);
 
       orderingIndexer = newOrderingIndexer(titleIndex);
-      assertIndexContainsID(orderingIndexer, entry, titleIndex.orderingIndex, entryID);
+      assertIndexContainsID(orderingIndexer, entry, titleIndex.getOrderingIndex(), entryID);
 
       orderingIndexer = newOrderingIndexer(nameIndex);
-      assertIndexContainsID(orderingIndexer, entry, nameIndex.orderingIndex, entryID);
+      assertIndexContainsID(orderingIndexer, entry, nameIndex.getOrderingIndex(), entryID);
 
       equalityIndexer = newEqualityIndexer(titleIndex);
-      assertIndexContainsID(equalityIndexer, entry, titleIndex.equalityIndex, entryID);
+      assertIndexContainsID(equalityIndexer, entry, titleIndex.getEqualityIndex(), entryID);
 
       equalityIndexer = newEqualityIndexer(nameIndex);
-      assertIndexContainsID(equalityIndexer, entry, nameIndex.equalityIndex, entryID);
+      assertIndexContainsID(equalityIndexer, entry, nameIndex.getEqualityIndex(), entryID);
 
       substringIndexer = newSubstringIndexer(titleIndex);
-      assertIndexContainsID(substringIndexer, entry, titleIndex.substringIndex, entryID);
+      assertIndexContainsID(substringIndexer, entry, titleIndex.getSubstringIndex(), entryID);
 
       substringIndexer = newSubstringIndexer(nameIndex);
-      assertIndexContainsID(substringIndexer, entry, nameIndex.substringIndex, entryID);
+      assertIndexContainsID(substringIndexer, entry, nameIndex.getSubstringIndex(), entryID);
     }
     finally
     {
@@ -1210,13 +1204,13 @@
     RootContainer rootContainer = backend.getRootContainer();
     EntryContainer ec = rootContainer.getEntryContainer(DN.valueOf("dc=test,dc=com"));
 
-    AttributeIndex index =
+    AttributeIndex attributeIndex =
         ec.getAttributeIndex(DirectoryServer.getAttributeType("givenname"));
-    assertNull(index.equalityIndex);
-    assertNull(index.presenceIndex);
-    assertNull(index.substringIndex);
-    assertNull(index.orderingIndex);
-    assertNotNull(index.approximateIndex);
+    assertNull(attributeIndex.getEqualityIndex());
+    assertNull(attributeIndex.getPresenceIndex());
+    assertNull(attributeIndex.getSubstringIndex());
+    assertNull(attributeIndex.getOrderingIndex());
+    assertNotNull(attributeIndex.getApproximateIndex());
     List<DatabaseContainer> databases = new ArrayList<DatabaseContainer>();
     ec.listDatabases(databases);
     boolean eqfound = false;
@@ -1287,11 +1281,11 @@
 
     assertEquals(resultCode, 0);
 
-    assertNotNull(index.equalityIndex);
-    assertNotNull(index.presenceIndex);
-    assertNotNull(index.substringIndex);
-    assertNotNull(index.orderingIndex);
-    assertNull(index.approximateIndex);
+    assertNotNull(attributeIndex.getEqualityIndex());
+    assertNotNull(attributeIndex.getPresenceIndex());
+    assertNotNull(attributeIndex.getSubstringIndex());
+    assertNotNull(attributeIndex.getOrderingIndex());
+    assertNull(attributeIndex.getApproximateIndex());
     databases = new ArrayList<DatabaseContainer>();
     ec.listDatabases(databases);
     eqfound = false;
diff --git a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java
index 93b7b2c..3dc3c6a 100644
--- a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java
+++ b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java
@@ -345,10 +345,8 @@
     eContainer.sharedLock.lock();
     try
     {
-      AttributeType attributeType =
-          DirectoryServer.getAttributeType(phoneType);
-      Index index =
-           eContainer.getAttributeIndex(attributeType).equalityIndex;
+      AttributeType attributeType = DirectoryServer.getAttributeType(phoneType);
+      Index index = eContainer.getAttributeIndex(attributeType).getEqualityIndex();
       //Add entry with bad JEB format Version
       addID2EntryReturnKey(junkDN, 4, true);
       //Add phone number with various bad id list entryIDs
@@ -634,14 +632,11 @@
       AttributeType attributeType =
           DirectoryServer.getAttributeType(mailType);
       //Get db handles to each index.
-      Index eqIndex =
-          eContainer.getAttributeIndex(attributeType).equalityIndex;
-      Index presIndex =
-          eContainer.getAttributeIndex(attributeType).presenceIndex;
-      Index subIndex =
-          eContainer.getAttributeIndex(attributeType).substringIndex;
-      Index ordIndex =
-          eContainer.getAttributeIndex(attributeType).orderingIndex;
+      AttributeIndex attributeIndex = eContainer.getAttributeIndex(attributeType);
+      Index eqIndex = attributeIndex.getEqualityIndex();
+      Index presIndex = attributeIndex.getPresenceIndex();
+      Index subIndex = attributeIndex.getSubstringIndex();
+      Index ordIndex = attributeIndex.getOrderingIndex();
       //Add invalid idlist ids to both equality and ordering indexes.
       DatabaseEntry key=
            new DatabaseEntry(StaticUtils.getBytes("user.0@example.com"));

--
Gitblit v1.10.0