From 4cb8262e95fde77e6a0d2c84f1aa118e3b1ee850 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Thu, 06 Nov 2014 14:50:48 +0000
Subject: [PATCH] OPENDJ-1591 CR-5092 Switch server to SDK matching rules

---
 opendj3-server-dev/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java | 1765 ----------------------------------------------------------
 1 files changed, 23 insertions(+), 1,742 deletions(-)

diff --git a/opendj3-server-dev/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java b/opendj3-server-dev/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java
index e4382c7..2cdb892 100644
--- a/opendj3-server-dev/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java
+++ b/opendj3-server-dev/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java
@@ -26,55 +26,34 @@
  */
 package org.opends.server.schema;
 
-import java.nio.CharBuffer;
-import java.text.CollationKey;
-import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.forgerock.opendj.config.server.ConfigException;
-import org.forgerock.opendj.ldap.ByteSequence;
-import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.ByteStringBuilder;
-import org.forgerock.opendj.ldap.ConditionResult;
-import org.forgerock.opendj.ldap.DecodeException;
 import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.schema.CoreSchema;
+import org.forgerock.opendj.ldap.schema.MatchingRule;
 import org.forgerock.opendj.ldap.schema.Schema;
-import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
-import org.forgerock.opendj.ldap.spi.IndexingOptions;
 import org.opends.server.admin.server.ConfigurationChangeListener;
-import org.opends.server.admin.std.meta.CollationMatchingRuleCfgDefn.MatchingRuleType;
 import org.opends.server.admin.std.server.CollationMatchingRuleCfg;
-import org.opends.server.api.AbstractMatchingRule;
-import org.opends.server.api.ExtensibleIndexer;
-import org.opends.server.api.ExtensibleMatchingRule;
-import org.opends.server.api.MatchingRule;
 import org.opends.server.api.MatchingRuleFactory;
-import org.opends.server.api.OrderingMatchingRule;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.ConfigChangeResult;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.InitializationException;
-import org.opends.server.util.StaticUtils;
 
 import static org.opends.messages.ConfigMessages.*;
-import static org.opends.messages.CoreMessages.*;
 import static org.opends.messages.SchemaMessages.*;
-import static org.opends.server.schema.SchemaConstants.*;
-import static org.opends.server.util.ServerConstants.*;
 
 /**
  * This class is a factory class for Collation matching rules. It
@@ -87,25 +66,6 @@
 
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
-
-  // Whether equality matching rules are enabled.
-  private boolean equalityMatchingRuleType;
-
-  // Whether less-than matching rules are enabled.
-  private boolean lessThanMatchingRuleType;
-
-  // Whether less-than-equal-to matching rules are enabled.
-  private boolean lessThanEqualToMatchingRuleType;
-
-  // Whether less-than-equal-to matching rules are enabled.
-  private boolean greaterThanMatchingRuleType;
-
-  // Whether greater-than matching rules are enabled.
-  private boolean greaterThanEqualToMatchingRuleType;
-
-  // Whether greater-than-equal-to matching rules are enabled.
-  private boolean substringMatchingRuleType;
-
   // Stores the list of available locales on this JVM.
   private static final Set<Locale> supportedLocales = new HashSet<Locale>(
       Arrays.asList(Locale.getAvailableLocales()));
@@ -118,7 +78,6 @@
       new HashMap<String, MatchingRule>();
 
 
-
   /**
    * Creates a new instance of CollationMatchingRuleFactory.
    */
@@ -127,19 +86,15 @@
     super();
   }
 
-
-
   /**
    * {@inheritDoc}
    */
   @Override
-  public final Collection<MatchingRule> getMatchingRules()
+  public final Collection<org.forgerock.opendj.ldap.schema.MatchingRule> getMatchingRules()
   {
     return Collections.unmodifiableCollection(matchingRules.values());
   }
 
-
-
   /**
    * Adds a new mapping of OID and MatchingRule.
    *
@@ -153,22 +108,6 @@
     matchingRules.put(oid, matchingRule);
   }
 
-
-
-  /**
-   * Returns the Matching rule for the specified OID.
-   *
-   * @param oid
-   *          OID of the matching rule to be searched.
-   * @return MatchingRule corresponding to an OID.
-   */
-  private MatchingRule getMatchingRule(String oid)
-  {
-    return matchingRules.get(oid);
-  }
-
-
-
   /**
    * Clears the Map containing matching Rules.
    */
@@ -177,63 +116,6 @@
     matchingRules.clear();
   }
 
-
-
-  /**
-   * Reads the configuration and initializes matching rule types.
-   *
-   * @param ruleTypes
-   *          The Set containing allowed matching rule types.
-   */
-  private void initializeMatchingRuleTypes(SortedSet<MatchingRuleType> ruleTypes)
-  {
-    for (MatchingRuleType type : ruleTypes)
-    {
-      switch (type)
-      {
-      case EQUALITY:
-        equalityMatchingRuleType = true;
-        break;
-      case LESS_THAN:
-        lessThanMatchingRuleType = true;
-        break;
-      case LESS_THAN_OR_EQUAL_TO:
-        lessThanEqualToMatchingRuleType = true;
-        break;
-      case GREATER_THAN:
-        greaterThanMatchingRuleType = true;
-        break;
-      case GREATER_THAN_OR_EQUAL_TO:
-        greaterThanEqualToMatchingRuleType = true;
-        break;
-      case SUBSTRING:
-        substringMatchingRuleType = true;
-        break;
-      default:
-        // No default values allowed.
-      }
-    }
-  }
-
-
-
-  /**
-   * Creates a new Collator instance.
-   *
-   * @param locale
-   *          Locale for the collator
-   * @return Returns a new Collator instance
-   */
-  private Collator createCollator(Locale locale)
-  {
-    Collator collator = Collator.getInstance(locale);
-    collator.setStrength(Collator.PRIMARY);
-    collator.setDecomposition(Collator.FULL_DECOMPOSITION);
-    return collator;
-  }
-
-
-
   /**
    * {@inheritDoc}
    */
@@ -241,7 +123,7 @@
   public void initializeMatchingRule(CollationMatchingRuleCfg configuration)
       throws ConfigException, InitializationException
   {
-    initializeMatchingRuleTypes(configuration.getMatchingRuleType());
+    final Schema coreSchema = CoreSchema.getInstance();
     for (String collation : configuration.getCollation())
     {
       CollationMapper mapper = new CollationMapper(collation);
@@ -257,12 +139,22 @@
       Locale locale = getLocale(languageTag);
       if (locale != null)
       {
-        createLessThanMatchingRule(mapper, locale);
-        createLessThanOrEqualToMatchingRule(mapper, locale);
-        createEqualityMatchingRule(mapper, locale);
-        createGreaterThanOrEqualToMatchingRule(mapper, locale);
-        createGreaterThanMatchingRule(mapper, locale);
-        createSubstringMatchingRule(mapper, locale);
+        try
+        {
+          final int[] numericSuffixes = { 1, 2, 3, 4, 5, 6 };
+          for (int suffix : numericSuffixes)
+          {
+            final String oid =  nOID + "." + suffix;
+            addMatchingRule(oid, coreSchema.getMatchingRule(oid));
+          }
+          // the default (equality) matching rule
+          addMatchingRule(nOID, coreSchema.getMatchingRule(nOID));
+        }
+        catch (Exception e)
+        {
+          logger.error(LocalizableMessage.raw("Error when adding a collation matching rule with oid %s, tag %s: %s",
+              nOID, languageTag, e.getMessage()));
+        }
       }
       else
       {
@@ -327,19 +219,13 @@
     // Clear the associated matching rules.
     resetRules();
 
-    initializeMatchingRuleTypes(configuration.getMatchingRuleType());
+    final Schema coreSchema = CoreSchema.getInstance();
     for (String collation : configuration.getCollation())
     {
       // validation has already been performed in isConfigurationChangeAcceptable()
       CollationMapper mapper = new CollationMapper(collation);
-      String languageTag = mapper.getLanguageTag();
-      Locale locale = getLocale(languageTag);
-      createLessThanMatchingRule(mapper, locale);
-      createLessThanOrEqualToMatchingRule(mapper, locale);
-      createEqualityMatchingRule(mapper, locale);
-      createGreaterThanOrEqualToMatchingRule(mapper, locale);
-      createGreaterThanMatchingRule(mapper, locale);
-      createSubstringMatchingRule(mapper, locale);
+      String nOID = mapper.getNumericOID();
+      addMatchingRule(nOID, coreSchema.getMatchingRule(nOID));
     }
 
     try
@@ -360,8 +246,6 @@
     return new ConfigChangeResult(resultCode, adminActionRequired, messages);
   }
 
-
-
   /**
    * {@inheritDoc}
    */
@@ -415,191 +299,6 @@
   }
 
 
-
-  private Collection<String> copyNames(MatchingRule matchingRule)
-  {
-    Collection<String> defaultNames = new HashSet<String>();
-    if (matchingRule != null)
-    {
-      defaultNames.addAll(matchingRule.getNames());
-    }
-    return defaultNames;
-  }
-
-
-
-  /**
-   * Creates Less-than Matching Rule.
-   *
-   * @param mapper
-   *          CollationMapper containing OID and the language Tag.
-   * @param locale
-   *          Locale value
-   */
-  private void createLessThanMatchingRule(CollationMapper mapper, Locale locale)
-  {
-    if (!lessThanMatchingRuleType) return;
-
-    String oid = mapper.getNumericOID() + ".1";
-    String lTag = mapper.getLanguageTag();
-
-    Collection<String> names = copyNames(getMatchingRule(oid));
-    names.add(lTag + ".lt");
-    names.add(lTag + ".1");
-
-    MatchingRule matchingRule =
-        new CollationLessThanMatchingRule(oid, names, locale);
-    addMatchingRule(oid, matchingRule);
-  }
-
-
-
-  /**
-   * Creates Less-Than-Equal-To Matching Rule.
-   *
-   * @param mapper
-   *          CollationMapper containing OID and the language Tag.
-   * @param locale
-   *          Locale value
-   */
-  private void createLessThanOrEqualToMatchingRule(
-      CollationMapper mapper, Locale locale)
-  {
-    if (!lessThanEqualToMatchingRuleType) return;
-
-    String oid = mapper.getNumericOID() + ".2";
-    String lTag = mapper.getLanguageTag();
-
-    Collection<String> names = copyNames(getMatchingRule(oid));
-    names.add(lTag + ".lte");
-    names.add(lTag + ".2");
-
-    MatchingRule matchingRule =
-        new CollationLessThanOrEqualToMatchingRule(oid, names, locale);
-    addMatchingRule(oid, matchingRule);
-  }
-
-
-
-  /**
-   * Creates Equality Matching Rule.
-   *
-   * @param mapper
-   *          CollationMapper containing OID and the language Tag.
-   * @param locale
-   *          Locale value
-   */
-  private void createEqualityMatchingRule(CollationMapper mapper, Locale locale)
-  {
-    if (!equalityMatchingRuleType)
-    {
-      return;
-    }
-
-    // Register the default OID as equality matching rule.
-    String lTag = mapper.getLanguageTag();
-    String nOID = mapper.getNumericOID();
-
-    Collection<String> defaultNames = copyNames(getMatchingRule(nOID));
-    defaultNames.add(lTag);
-    MatchingRule matchingRule =
-        new CollationEqualityMatchingRule(nOID, defaultNames, locale);
-    addMatchingRule(nOID, matchingRule);
-
-    // Register OID.3 as the equality matching rule.
-    String OID = mapper.getNumericOID() + ".3";
-    Collection<String> names = copyNames(getMatchingRule(OID));
-    names.add(lTag + ".eq");
-    names.add(lTag + ".3");
-
-    MatchingRule equalityMatchingRule =
-        new CollationEqualityMatchingRule(OID, names, locale);
-    addMatchingRule(OID, equalityMatchingRule);
-  }
-
-
-
-  /**
-   * Creates Greater-than-equal-to Matching Rule.
-   *
-   * @param mapper
-   *          CollationMapper containing OID and the language Tag.
-   * @param locale
-   *          Locale value
-   */
-  private void createGreaterThanOrEqualToMatchingRule(
-      CollationMapper mapper, Locale locale)
-  {
-    if (!greaterThanEqualToMatchingRuleType) return;
-
-    String oid = mapper.getNumericOID() + ".4";
-    String lTag = mapper.getLanguageTag();
-
-    Collection<String> names = copyNames(getMatchingRule(oid));
-    names.add(lTag + ".gte");
-    names.add(lTag + ".4");
-
-    MatchingRule matchingRule =
-        new CollationGreaterThanOrEqualToMatchingRule(oid, names, locale);
-    addMatchingRule(oid, matchingRule);
-  }
-
-
-
-  /**
-   * Creates Greater-than Matching Rule.
-   *
-   * @param mapper
-   *          CollationMapper containing OID and the language Tag.
-   * @param locale
-   *          Locale value
-   */
-  private void createGreaterThanMatchingRule(CollationMapper mapper,
-      Locale locale)
-  {
-    if (!greaterThanMatchingRuleType) return;
-
-    String oid = mapper.getNumericOID() + ".5";
-    String lTag = mapper.getLanguageTag();
-
-    Collection<String> names = copyNames(getMatchingRule(oid));
-    names.add(lTag + ".gt");
-    names.add(lTag + ".5");
-
-    MatchingRule matchingRule =
-        new CollationGreaterThanMatchingRule(oid, names, locale);
-    addMatchingRule(oid, matchingRule);
-  }
-
-
-
-  /**
-   * Creates substring Matching Rule.
-   *
-   * @param mapper
-   *          CollationMapper containing OID and the language Tag.
-   * @param locale
-   *          Locale value
-   */
-  private void createSubstringMatchingRule(CollationMapper mapper,
-      Locale locale)
-  {
-    if (!substringMatchingRuleType) return;
-
-    String oid = mapper.getNumericOID() + ".6";
-    String lTag = mapper.getLanguageTag();
-
-    Collection<String> names = copyNames(getMatchingRule(oid));
-    names.add(lTag + ".sub");
-    names.add(lTag + ".6");
-
-    MatchingRule matchingRule =
-        new CollationSubstringMatchingRule(oid, names, locale);
-    addMatchingRule(oid, matchingRule);
-  }
-
-
-
   /**
    * Verifies if the locale is supported by the JVM.
    *
@@ -648,1424 +347,6 @@
 
 
   /**
-   * Evaluates and converts 2 consecutive characters of the provided string
-   * starting at startPos and converts them into a single escaped char.
-   *
-   * @param hexString
-   *          The hexadecimal string containing the escape sequence.
-   * @param startPos
-   *          The starting position of the hexadecimal escape sequence.
-   * @return The escaped character
-   * @throws DecodeException
-   *           If the provided string contains invalid hexadecimal digits .
-   */
-  private static char hexToEscapedChar(String hexString, int startPos)
-      throws DecodeException
-  {
-    // The two positions must be the hex characters that
-    // comprise the escaped value.
-    if ((startPos + 1) >= hexString.length())
-    {
-      LocalizableMessage message =
-          ERR_SEARCH_FILTER_INVALID_ESCAPED_BYTE.get(hexString,
-              startPos + 1);
-      throw DecodeException.error(message);
-    }
-    byte byteValue = 0;
-    switch (hexString.charAt(startPos))
-    {
-    case 0x30: // '0'
-      break;
-    case 0x31: // '1'
-      byteValue = (byte) 0x10;
-      break;
-    case 0x32: // '2'
-      byteValue = (byte) 0x20;
-      break;
-    case 0x33: // '3'
-      byteValue = (byte) 0x30;
-      break;
-    case 0x34: // '4'
-      byteValue = (byte) 0x40;
-      break;
-    case 0x35: // '5'
-      byteValue = (byte) 0x50;
-      break;
-    case 0x36: // '6'
-      byteValue = (byte) 0x60;
-      break;
-    case 0x37: // '7'
-      byteValue = (byte) 0x70;
-      break;
-    case 0x38: // '8'
-      byteValue = (byte) 0x80;
-      break;
-    case 0x39: // '9'
-      byteValue = (byte) 0x90;
-      break;
-    case 0x41: // 'A'
-    case 0x61: // 'a'
-      byteValue = (byte) 0xA0;
-      break;
-    case 0x42: // 'B'
-    case 0x62: // 'b'
-      byteValue = (byte) 0xB0;
-      break;
-    case 0x43: // 'C'
-    case 0x63: // 'c'
-      byteValue = (byte) 0xC0;
-      break;
-    case 0x44: // 'D'
-    case 0x64: // 'd'
-      byteValue = (byte) 0xD0;
-      break;
-    case 0x45: // 'E'
-    case 0x65: // 'e'
-      byteValue = (byte) 0xE0;
-      break;
-    case 0x46: // 'F'
-    case 0x66: // 'f'
-      byteValue = (byte) 0xF0;
-      break;
-    default:
-      LocalizableMessage message =
-          ERR_SEARCH_FILTER_INVALID_ESCAPED_BYTE.get(hexString, startPos);
-      throw DecodeException.error(message);
-    }
-
-    switch (hexString.charAt(++startPos))
-    {
-    case 0x30: // '0'
-      break;
-    case 0x31: // '1'
-      byteValue |= (byte) 0x01;
-      break;
-    case 0x32: // '2'
-      byteValue |= (byte) 0x02;
-      break;
-    case 0x33: // '3'
-      byteValue |= (byte) 0x03;
-      break;
-    case 0x34: // '4'
-      byteValue |= (byte) 0x04;
-      break;
-    case 0x35: // '5'
-      byteValue |= (byte) 0x05;
-      break;
-    case 0x36: // '6'
-      byteValue |= (byte) 0x06;
-      break;
-    case 0x37: // '7'
-      byteValue |= (byte) 0x07;
-      break;
-    case 0x38: // '8'
-      byteValue |= (byte) 0x08;
-      break;
-    case 0x39: // '9'
-      byteValue |= (byte) 0x09;
-      break;
-    case 0x41: // 'A'
-    case 0x61: // 'a'
-      byteValue |= (byte) 0x0A;
-      break;
-    case 0x42: // 'B'
-    case 0x62: // 'b'
-      byteValue |= (byte) 0x0B;
-      break;
-    case 0x43: // 'C'
-    case 0x63: // 'c'
-      byteValue |= (byte) 0x0C;
-      break;
-    case 0x44: // 'D'
-    case 0x64: // 'd'
-      byteValue |= (byte) 0x0D;
-      break;
-    case 0x45: // 'E'
-    case 0x65: // 'e'
-      byteValue |= (byte) 0x0E;
-      break;
-    case 0x46: // 'F'
-    case 0x66: // 'f'
-      byteValue |= (byte) 0x0F;
-      break;
-    default:
-      LocalizableMessage message =
-          ERR_SEARCH_FILTER_INVALID_ESCAPED_BYTE.get(hexString, startPos);
-      throw DecodeException.error(message);
-    }
-    return (char) byteValue;
-  }
-
-  /**
-   * Collation Extensible matching rule.
-   */
-  private abstract class CollationMatchingRule
-          extends AbstractMatchingRule
-          implements ExtensibleMatchingRule
-  {
-    // Names for this class.
-    private final Collection<String> names;
-
-    // Collator for performing equality match.
-    protected final Collator collator;
-
-    // Numeric OID of the rule.
-    private final String nOID;
-
-    // Locale associated with this rule.
-    private final Locale locale;
-
-    // Indexer of this rule.
-    protected ExtensibleIndexer indexer;
-
-
-
-    /**
-     * Constructs a new CollationMatchingRule.
-     *
-     * @param nOID
-     *          OID of the collation matching rule
-     * @param names
-     *          names of this matching rule
-     * @param locale
-     *          Locale of the collation matching rule
-     */
-    private CollationMatchingRule(String nOID,
-        Collection<String> names, Locale locale)
-    {
-      this.names = names;
-      this.collator = createCollator(locale);
-      this.locale = locale;
-      this.nOID = nOID;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Collection<String> getNames()
-    {
-      return Collections.unmodifiableCollection(names);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getOID()
-    {
-      return nOID;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getDescription()
-    {
-      // There is no standard description for this matching rule.
-      return null;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getSyntaxOID()
-    {
-      return SYNTAX_DIRECTORY_STRING_OID;
-    }
-
-
-
-    /**
-     * Returns the name of the index database for this matching rule. An
-     * index name for this rule will be based upon the Locale. This will
-     * ensure that multiple collation matching rules corresponding to
-     * the same Locale can share the same index database.
-     *
-     * @return The name of the index for this matching rule.
-     */
-    public String getIndexName()
-    {
-      String language = locale.getLanguage();
-      String country = locale.getCountry();
-      String variant = locale.getVariant();
-      StringBuilder builder = new StringBuilder(language);
-      if (country != null && country.length() > 0)
-      {
-        builder.append("_");
-        builder.append(locale.getCountry());
-      }
-      if (variant != null && variant.length() > 0)
-      {
-        builder.append("_");
-        builder.append(locale.getVariant());
-      }
-      return builder.toString();
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Collection<ExtensibleIndexer> getIndexers()
-    {
-      if (indexer == null)
-      {
-        // The default implementation contains shared indexer and
-        // doesn't use the config.
-        indexer = new CollationSharedExtensibleIndexer(this);
-      }
-      return Collections.singletonList(indexer);
-    }
-  }
-
-  /**
-   * Collation rule for Equality matching rule.
-   */
-  private final class CollationEqualityMatchingRule
-          extends CollationMatchingRule
-          implements OrderingMatchingRule
-  {
-
-    /**
-     * The serial version identifier required to satisfy the compiler because
-     * this class implements the <CODE>java.io.Serializable</CODE> interface.
-     * This value was generated using the <CODE>serialver</CODE> command-line
-     * utility included with the Java SDK.
-     */
-    private static final long serialVersionUID = 3990778178484159862L;
-
-
-
-    /**
-     * Constructs a new CollationEqualityMatchingRule.
-     *
-     * @param nOID
-     *          OID of the collation matching rule
-     * @param names
-     *          names of this matching rule
-     * @param locale
-     *          Locale of the collation matching rule
-     */
-    private CollationEqualityMatchingRule(String nOID,
-        Collection<String> names, Locale locale)
-    {
-      super(nOID, names, locale);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ByteString normalizeAttributeValue(ByteSequence value)
-        throws DecodeException
-    {
-      CollationKey key = collator.getCollationKey(value.toString());
-      return ByteString.wrap(key.toByteArray());
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ConditionResult valuesMatch(ByteSequence attributeValue,
-        ByteSequence assertionValue)
-    {
-      return ConditionResult.valueOf(assertionValue.equals(attributeValue));
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public <T> T createIndexQuery(ByteSequence assertionValue,
-        IndexQueryFactory<T> factory) throws DecodeException
-    {
-      // Normalize the assertion value.
-      return factory.createExactMatchQuery(indexer
-          .getExtensibleIndexID(), normalizeAttributeValue(assertionValue));
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int compare(byte[] arg0, byte[] arg1)
-    {
-      return StaticUtils.compare(arg0, arg1);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int compareValues(ByteSequence value1, ByteSequence value2)
-    {
-      return value1.compareTo(value2);
-    }
-  }
-
-  /**
-   * Collation rule for Substring matching rule.
-   */
-  private final class CollationSubstringMatchingRule extends
-      CollationMatchingRule
-  {
-    // Substring Indexer associated with this instance.
-    private CollationSubstringExtensibleIndexer subIndexer;
-
-
-
-    /**
-     * Constructs a new CollationSubstringMatchingRule.
-     *
-     * @param nOID
-     *          OID of the collation matching rule
-     * @param names
-     *          names of this matching rule
-     * @param locale
-     *          Locale of the collation matching rule
-     */
-    private CollationSubstringMatchingRule(String nOID,
-        Collection<String> names, Locale locale)
-    {
-      super(nOID, names, locale);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ByteString normalizeAttributeValue(ByteSequence value)
-        throws DecodeException
-    {
-      CollationKey key = collator.getCollationKey(value.toString());
-      return ByteString.wrap(key.toByteArray());
-    }
-
-
-
-    /**
-     * Utility class which abstracts a substring assertion value.
-     */
-    private final class Assertion
-    {
-      // Initial part of the substring filter.
-      private String subInitial;
-
-      // any parts of the substring filter.
-      private List<String> subAny;
-
-      // Final part of the substring filter.
-      private String subFinal;
-
-
-
-      /**
-       * Creates a new instance of Assertion.
-       *
-       * @param subInitial
-       *          Initial part of the filter.
-       * @param subAny
-       *          Any part of the filter.
-       * @param subFinal
-       *          Final part of the filter.
-       */
-      private Assertion(String subInitial, List<String> subAny,
-          String subFinal)
-      {
-        this.subInitial = subInitial;
-        this.subAny = subAny;
-        this.subFinal = subFinal;
-      }
-
-
-
-      /**
-       * Returns the Initial part of the assertion.
-       *
-       * @return Initial part of assertion.
-       */
-      private String getInitial()
-      {
-        return subInitial;
-      }
-
-
-
-      /**
-       * Returns the any part of the assertion.
-       *
-       * @return Any part of the assertion.
-       */
-      private List<String> getAny()
-      {
-        return subAny;
-      }
-
-
-
-      /**
-       * Returns the final part of the assertion.
-       *
-       * @return Final part of the assertion.
-       */
-      private String getFinal()
-      {
-        return subFinal;
-      }
-    }
-
-    private Assertion parseAssertion(ByteSequence value) throws DecodeException
-    {
-      // Get a string representation of the value.
-      String filterString = value.toString();
-      int endPos = filterString.length();
-
-      // Find the locations of all the asterisks in the value. Also,
-      // check to see if there are any escaped values, since they will
-      // need special treatment.
-      boolean hasEscape = false;
-      LinkedList<Integer> asteriskPositions = new LinkedList<Integer>();
-      for (int i = 0; i < endPos; i++)
-      {
-        if (filterString.charAt(i) == 0x2A) // The asterisk.
-        {
-          asteriskPositions.add(i);
-        }
-        else if (filterString.charAt(i) == 0x5C) // The backslash.
-        {
-          hasEscape = true;
-        }
-      }
-
-      // If there were no asterisks, then this isn't a substring filter.
-      if (asteriskPositions.isEmpty())
-      {
-        throw DecodeException.error(
-            ERR_SEARCH_FILTER_SUBSTRING_NO_ASTERISKS.get(filterString, 0, endPos));
-      }
-
-      // If the value starts with an asterisk, then there is no
-      // subInitial component. Otherwise, parse out the subInitial.
-      String subInitial;
-      int firstPos = asteriskPositions.removeFirst();
-      if (firstPos == 0)
-      {
-        subInitial = null;
-      }
-      else
-      {
-        if (hasEscape)
-        {
-          CharBuffer buffer = CharBuffer.allocate(firstPos);
-          for (int i = 0; i < firstPos; i++)
-          {
-            if (filterString.charAt(i) == 0x5C)
-            {
-              char escapeValue = hexToEscapedChar(filterString, i + 1);
-              i += 2; // Move to the next sequence.
-              buffer.put(escapeValue);
-            }
-            else
-            {
-              buffer.put(filterString.charAt(i));
-            }
-          }
-
-          char[] subInitialChars = new char[buffer.position()];
-          buffer.flip();
-          buffer.get(subInitialChars);
-          subInitial = new String(subInitialChars);
-        }
-        else
-        {
-          subInitial = filterString.substring(0, firstPos);
-        }
-      }
-
-      // Next, process through the rest of the asterisks to get the
-      // subAny values.
-      List<String> subAny = new ArrayList<String>();
-      for (int asteriskPos : asteriskPositions)
-      {
-        int length = asteriskPos - firstPos - 1;
-
-        if (hasEscape)
-        {
-          CharBuffer buffer = CharBuffer.allocate(length);
-          for (int i = firstPos + 1; i < asteriskPos; i++)
-          {
-            if (filterString.charAt(i) == 0x5C)
-            {
-              char escapeValue = hexToEscapedChar(filterString, i + 1);
-              i += 2; // Move to the next sequence.
-              buffer.put(escapeValue);
-            }
-            else
-            {
-              buffer.put(filterString.charAt(i));
-            }
-          }
-
-          char[] subAnyChars = new char[buffer.position()];
-          buffer.flip();
-          buffer.get(subAnyChars);
-          subAny.add(new String(subAnyChars));
-        }
-        else
-        {
-          subAny.add(filterString.substring(firstPos + 1, firstPos
-              + length + 1));
-        }
-
-        firstPos = asteriskPos;
-      }
-
-      // Finally, see if there is anything after the last asterisk,
-      // which would be the subFinal value.
-      String subFinal;
-      if (firstPos == (endPos - 1))
-      {
-        subFinal = null;
-      }
-      else
-      {
-        int length = endPos - firstPos - 1;
-
-        if (hasEscape)
-        {
-          CharBuffer buffer = CharBuffer.allocate(length);
-          for (int i = firstPos + 1; i < endPos; i++)
-          {
-            if (filterString.charAt(i) == 0x5C)
-            {
-              char escapeValue = hexToEscapedChar(filterString, i + 1);
-              i += 2; // Move to the next sequence.
-              buffer.put(escapeValue);
-            }
-            else
-            {
-              buffer.put(filterString.charAt(i));
-            }
-          }
-
-          char[] subFinalChars = new char[buffer.position()];
-          buffer.flip();
-          buffer.get(subFinalChars);
-          subFinal = new String(subFinalChars);
-        }
-        else
-        {
-          subFinal =
-              filterString.substring(firstPos + 1, length + firstPos
-                  + 1);
-        }
-      }
-
-      return new Assertion(subInitial, subAny, subFinal);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ByteString normalizeAssertionValue(ByteSequence value)
-        throws DecodeException
-    {
-      Assertion assertion = parseAssertion(value);
-      String subInitial = assertion.getInitial();
-
-      // Normalize the Values in the following format:
-      // initialLength, initial, numberofany, anyLength1, any1,
-      // anyLength2, any2, ..., anyLengthn, anyn, finalLength, final
-      List<Integer> normalizedList = new ArrayList<Integer>();
-
-      if (subInitial == null)
-      {
-        normalizedList.add(0);
-      }
-      else
-      {
-        addLengthAndBytes(subInitial, normalizedList);
-      }
-
-      List<String> subAny = assertion.getAny();
-      if (subAny.isEmpty())
-      {
-        normalizedList.add(0);
-      }
-      else
-      {
-        normalizedList.add(subAny.size());
-        for (String any : subAny)
-        {
-          addLengthAndBytes(any, normalizedList);
-        }
-      }
-
-      String subFinal = assertion.getFinal();
-      if (subFinal == null)
-      {
-        normalizedList.add(0);
-      }
-      else
-      {
-        addLengthAndBytes(subFinal, normalizedList);
-      }
-
-      byte[] normalizedBytes = new byte[normalizedList.size()];
-      for (int i = 0; i < normalizedList.size(); i++)
-      {
-        normalizedBytes[i] = normalizedList.get(i).byteValue();
-      }
-      return ByteString.wrap(normalizedBytes);
-    }
-
-
-
-    private void addLengthAndBytes(String substring,
-        List<Integer> normalizedList)
-    {
-      CollationKey key = collator.getCollationKey(substring);
-      byte[] substrBytes = key.toByteArray();
-
-      // Last 4 bytes are 0s with PRIMARY strength.
-      int length = substrBytes.length - 4;
-      normalizedList.add(length);
-      for (int i = 0; i < length; i++)
-      {
-        normalizedList.add((int) substrBytes[i]);
-      }
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ConditionResult valuesMatch(ByteSequence attributeValue,
-        ByteSequence assertionValue)
-    { // FIXME Code similar to
-      // AbstractSubstringMatchingRuleImpl.DefaultSubstringAssertion.matches()
-      int valueLength = attributeValue.length() - 4;
-      int valuePos = 0; // position in the value bytes array.
-
-      // First byte is the length of subInitial.
-      int subInitialLength = 0xFF & assertionValue.byteAt(0);
-
-      if (subInitialLength != 0)
-      {
-        if (subInitialLength > valueLength)
-        {
-          return ConditionResult.FALSE;
-        }
-
-        for (; valuePos < subInitialLength; valuePos++)
-        {
-          if (attributeValue.byteAt(valuePos) != assertionValue
-              .byteAt(valuePos + 1))
-          {
-            return ConditionResult.FALSE;
-          }
-        }
-      }
-
-      int assertPos = subInitialLength + 1;
-      int anySize = 0xFF & assertionValue.byteAt(assertPos++);
-      if (anySize != 0)
-      {
-        while (anySize-- > 0)
-        {
-          int anyLength = 0xFF & assertionValue.byteAt(assertPos++);
-          int end = valueLength - anyLength;
-          boolean match = false;
-
-          for (; valuePos <= end; valuePos++)
-          {
-            if (assertionValue.byteAt(assertPos) == attributeValue
-                .byteAt(valuePos))
-            {
-              boolean subMatch = true;
-              for (int i = 1; i < anyLength; i++)
-              {
-                if (assertionValue.byteAt(assertPos + i) != attributeValue
-                    .byteAt(valuePos + i))
-                {
-                  subMatch = false;
-                  break;
-                }
-              }
-
-              if (subMatch)
-              {
-                match = subMatch;
-                break;
-              }
-            }
-          }
-
-          if (match)
-          {
-            valuePos += anyLength;
-          }
-          else
-          {
-            return ConditionResult.FALSE;
-          }
-
-          assertPos = assertPos + anyLength;
-        }
-      }
-
-      int finalLength = 0xFF & assertionValue.byteAt(assertPos++);
-      if (finalLength != 0)
-      {
-        if ((valueLength - finalLength) < valuePos)
-        {
-          return ConditionResult.FALSE;
-        }
-
-        if (finalLength != assertionValue.length() - assertPos)
-        {
-          // Some issue with the encoding.
-          return ConditionResult.FALSE;
-        }
-
-        valuePos = valueLength - finalLength;
-        for (int i = 0; i < finalLength; i++, valuePos++)
-        {
-          if (assertionValue.byteAt(assertPos + i) != attributeValue
-              .byteAt(valuePos))
-          {
-            return ConditionResult.FALSE;
-          }
-        }
-      }
-
-      return ConditionResult.TRUE;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public final Collection<ExtensibleIndexer> getIndexers()
-    {
-      List<ExtensibleIndexer> indexers = new ArrayList<ExtensibleIndexer>();
-      if (subIndexer == null)
-      {
-        subIndexer = new CollationSubstringExtensibleIndexer(this);
-      }
-      if (indexer == null)
-      {
-        indexer = new CollationSharedExtensibleIndexer(this);
-      }
-
-      indexers.add(subIndexer);
-      indexers.add(indexer);
-
-      return indexers;
-    }
-
-
-    /**
-     * Makes a byte array representing a substring index key for one
-     * substring of a value.
-     *
-     * @param value
-     *          The String containing the value.
-     * @param pos
-     *          The starting position of the substring.
-     * @param len
-     *          The length of the substring.
-     * @return A byte string containing a substring key.
-     */
-    private ByteString makeSubstringKey(String value, int pos, int len)
-    {
-      String sub = value.substring(pos, pos + len);
-      CollationKey col = collator.getCollationKey(sub);
-      byte[] key = col.toByteArray();
-      // truncate the key
-      return ByteString.wrap(key).subSequence(0, key.length - 4);
-    }
-
-
-
-    /**
-     * Uses an equality index to retrieve the entry IDs that might
-     * contain a given initial substring.
-     *
-     * @param bytes
-     *          A normalized initial substring of an attribute value.
-     * @return The candidate entry IDs.
-     */
-    private <T> T matchInitialSubstring(String value,
-        IndexQueryFactory<T> factory)
-    {
-      // Use the shared equality indexer.
-      return createRangeMatchQuery(value, factory, this.indexer);
-    }
-
-    private <T> T createRangeMatchQuery(String value,
-        IndexQueryFactory<T> factory, ExtensibleIndexer indexer)
-    { // FIXME Code similar to
-      // AbstractSubstringMatchingRuleImpl.DefaultSubstringAssertion.rangeMatch()
-      ByteString lower = makeSubstringKey(value, 0, value.length());
-      ByteStringBuilder upper = new ByteStringBuilder(lower);
-      for (int i = upper.length() - 1; i >= 0; i--)
-      {
-        if (upper.byteAt(i) == 0xFF)
-        {
-          // We have to carry the overflow to the more significant byte.
-          upper.setByte(i, (byte) 0);
-        }
-        else
-        {
-          // No overflow, we can stop.
-          upper.setByte(i, (byte) (upper.byteAt(i) + 1));
-          break;
-        }
-      }
-      // Read the range: lower <= keys < upper.
-      return factory.createRangeMatchQuery(
-          indexer.getExtensibleIndexID(), lower, upper, true, false);
-    }
-
-    /**
-     * Retrieves the Index Records that might contain a given substring.
-     *
-     * @param value
-     *          A String representing the attribute value.
-     * @param factory
-     *          An IndexQueryFactory which issues calls to the backend.
-     * @param substrLength
-     *          The length of the substring.
-     * @return The candidate entry IDs.
-     */
-    private <T> T matchSubstring(String value, IndexQueryFactory<T> factory)
-    { // FIXME Code similar to
-      // AbstractSubstringMatchingRuleImpl.DefaultSubstringAssertion.substringMatch()
-      int substrLength = factory.getIndexingOptions().substringKeySize();
-      if (value.length() < substrLength)
-      {
-        return createRangeMatchQuery(value, factory, subIndexer);
-      }
-
-      List<T> queryList = new ArrayList<T>();
-      Set<ByteString> set = new TreeSet<ByteString>();
-      for (int first = 0, last = substrLength;
-           last <= value.length();
-           first++, last++)
-      {
-        set.add(makeSubstringKey(value, first, substrLength));
-      }
-
-      for (ByteString keyBytes : set)
-      {
-        queryList.add(factory.createExactMatchQuery(
-            subIndexer.getExtensibleIndexID(), keyBytes));
-      }
-      return factory.createIntersectionQuery(queryList);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public <T> T createIndexQuery(ByteSequence assertionValue,
-        IndexQueryFactory<T> factory) throws DecodeException
-    { // FIXME Code similar to
-      // AbstractSubstringMatchingRuleImpl.DefaultSubstringAssertion.createIndexQuery()?
-      Assertion assertion = parseAssertion(assertionValue);
-      String subInitial = assertion.getInitial();
-      List<String> subAny = assertion.getAny();
-      String subFinal = assertion.getFinal();
-      List<T> queries = new ArrayList<T>();
-
-      if (subInitial == null && subAny.isEmpty() && subFinal == null)
-      {
-        // Can happen with a filter like "cn:en.6:=*".
-        // Just return an empty record.
-        return factory.createMatchAllQuery();
-      }
-      List<String> elements = new ArrayList<String>();
-      if (subInitial != null)
-      {
-        // Always use the shared indexer for initial match.
-        queries.add(matchInitialSubstring(subInitial, factory));
-      }
-
-      if (subAny != null && subAny.size() > 0)
-      {
-        elements.addAll(subAny);
-      }
-
-      if (subFinal != null)
-      {
-        elements.add(subFinal);
-      }
-
-      for (String element : elements)
-      {
-        queries.add(matchSubstring(element, factory));
-      }
-      return factory.createIntersectionQuery(queries);
-    }
-  }
-
-  /**
-   * An abstract Collation rule for Ordering matching rule.
-   */
-  private abstract class CollationOrderingMatchingRule
-          extends CollationMatchingRule
-          implements OrderingMatchingRule
-  {
-
-    /**
-     * The serial version identifier required to satisfy the compiler because
-     * this class implements the <CODE>java.io.Serializable</CODE> interface.
-     * This value was generated using the <CODE>serialver</CODE> command-line
-     * utility included with the Java SDK.
-     */
-    private static final long serialVersionUID = 7354051060508436941L;
-
-
-
-    /**
-     * Constructs a new CollationOrderingMatchingRule.
-     *
-     * @param nOID
-     *          OID of the collation matching rule
-     * @param names
-     *          names of this matching rule
-     * @param locale
-     *          Locale of the collation matching rule
-     */
-    private CollationOrderingMatchingRule(String nOID,
-        Collection<String> names, Locale locale)
-    {
-      super(nOID, names, locale);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ByteString normalizeAttributeValue(ByteSequence value)
-        throws DecodeException
-    {
-      CollationKey key = collator.getCollationKey(value.toString());
-      return ByteString.wrap(key.toByteArray());
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int compare(byte[] arg0, byte[] arg1)
-    {
-      return StaticUtils.compare(arg0, arg1);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int compareValues(ByteSequence value1, ByteSequence value2)
-    {
-      return value1.compareTo(value2);
-    }
-  }
-
-  /**
-   * Collation matching rule for Less-than matching rule.
-   */
-  private final class CollationLessThanMatchingRule extends
-      CollationOrderingMatchingRule
-  {
-    /**
-     * The serial version identifier required to satisfy the compiler because
-     * this class implements the <CODE>java.io.Serializable</CODE> interface.
-     * This value was generated using the <CODE>serialver</CODE> command-line
-     * utility included with the Java SDK.
-     */
-    private static final long serialVersionUID = -7578406829946732713L;
-
-
-
-    /**
-     * Constructs a new CollationLessThanMatchingRule.
-     *
-     * @param nOID
-     *          OID of the collation matching rule
-     * @param names
-     *          names of this matching rule
-     * @param locale
-     *          Locale of the collation matching rule
-     */
-    private CollationLessThanMatchingRule(String nOID,
-        Collection<String> names, Locale locale)
-    {
-      super(nOID, names, locale);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ConditionResult valuesMatch(ByteSequence attributeValue,
-        ByteSequence assertionValue)
-    {
-      int ret = attributeValue.compareTo(assertionValue);
-      return ConditionResult.valueOf(ret < 0);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public <T> T createIndexQuery(ByteSequence assertionValue,
-        IndexQueryFactory<T> factory) throws DecodeException
-    {
-      return factory.createRangeMatchQuery(indexer
-          .getExtensibleIndexID(), ByteString.empty(),
-          normalizeAttributeValue(assertionValue), false, false);
-    }
-  }
-
-  /**
-   * Collation rule for less-than-equal-to matching rule.
-   */
-  private final class CollationLessThanOrEqualToMatchingRule extends
-      CollationOrderingMatchingRule
-  {
-    /**
-     * The serial version identifier required to satisfy the compiler because
-     * this class implements the <CODE>java.io.Serializable</CODE> interface.
-     * This value was generated using the <CODE>serialver</CODE> command-line
-     * utility included with the Java SDK.
-     */
-    private static final long serialVersionUID = 7222067708233629974L;
-
-
-
-    /**
-     * Constructs a new CollationLessThanOrEqualToMatchingRule.
-     *
-     * @param nOID
-     *          OID of the collation matching rule
-     * @param names
-     *          names of this matching rule
-     * @param locale
-     *          Locale of the collation matching rule
-     */
-    private CollationLessThanOrEqualToMatchingRule(String nOID,
-        Collection<String> names, Locale locale)
-    {
-      super(nOID, names, locale);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ConditionResult valuesMatch(ByteSequence attributeValue,
-        ByteSequence assertionValue)
-    {
-      int ret = attributeValue.compareTo(assertionValue);
-      return ConditionResult.valueOf(ret <= 0);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public <T> T createIndexQuery(ByteSequence assertionValue,
-        IndexQueryFactory<T> factory) throws DecodeException
-    {
-      // Read the range: lower < keys <= upper.
-      return factory.createRangeMatchQuery(indexer
-          .getExtensibleIndexID(), ByteString.empty(),
-          normalizeAttributeValue(assertionValue), false, true);
-    }
-  }
-
-  /**
-   * Collation rule for greater-than matching rule.
-   */
-  private final class CollationGreaterThanMatchingRule extends
-      CollationOrderingMatchingRule
-  {
-    /**
-     * The serial version identifier required to satisfy the compiler because
-     * this class implements the <CODE>java.io.Serializable</CODE> interface.
-     * This value was generated using the <CODE>serialver</CODE> command-line
-     * utility included with the Java SDK.
-     */
-    private static final long serialVersionUID = 1204368277332957024L;
-
-
-
-    /**
-     * Constructs a new CollationGreaterThanMatchingRule.
-     *
-     * @param nOID
-     *          OID of the collation matching rule
-     * @param names
-     *          names of this matching rule
-     * @param locale
-     *          Locale of the collation matching rule
-     */
-    private CollationGreaterThanMatchingRule(String nOID,
-        Collection<String> names, Locale locale)
-    {
-      super(nOID, names, locale);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ConditionResult valuesMatch(ByteSequence attributeValue,
-        ByteSequence assertionValue)
-    {
-      int ret = attributeValue.compareTo(assertionValue);
-      return ConditionResult.valueOf(ret > 0);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public <T> T createIndexQuery(ByteSequence assertionValue,
-        IndexQueryFactory<T> factory) throws DecodeException
-    {
-      return factory.createRangeMatchQuery(indexer
-          .getExtensibleIndexID(), normalizeAttributeValue(assertionValue),
-          ByteString.empty(), false, false);
-    }
-  }
-
-  /**
-   * Collation rule for greater-than-equal-to matching rule.
-   */
-  private final class CollationGreaterThanOrEqualToMatchingRule extends
-      CollationOrderingMatchingRule
-  {
-    /**
-     * The serial version identifier required to satisfy the compiler because
-     * this class implements the <CODE>java.io.Serializable</CODE> interface.
-     * This value was generated using the <CODE>serialver</CODE> command-line
-     * utility included with the Java SDK.
-     */
-    private static final long serialVersionUID = -5212358378014047933L;
-
-
-
-    /**
-     * Constructs a new CollationGreaterThanOrEqualToMatchingRule.
-     *
-     * @param nOID
-     *          OID of the collation matching rule
-     * @param names
-     *          names of this matching rule
-     * @param locale
-     *          Locale of the collation matching rule
-     */
-    private CollationGreaterThanOrEqualToMatchingRule(String nOID,
-        Collection<String> names, Locale locale)
-    {
-      super(nOID, names, locale);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ConditionResult valuesMatch(ByteSequence attributeValue,
-        ByteSequence assertionValue)
-    {
-      int ret = attributeValue.compareTo(assertionValue);
-      return ConditionResult.valueOf(ret >= 0);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public <T> T createIndexQuery(ByteSequence assertionValue,
-        IndexQueryFactory<T> factory) throws DecodeException
-    {
-      // Read the range: lower <= keys < upper.
-      return factory.createRangeMatchQuery(indexer
-          .getExtensibleIndexID(), normalizeAttributeValue(assertionValue),
-          ByteString.empty(), true, false);
-    }
-  }
-
-  /**
-   * Extensible Indexer class for Collation Matching rules which share
-   * the same index. This Indexer is shared by Equality and Ordering
-   * Collation Matching Rules.
-   */
-  private final class CollationSharedExtensibleIndexer extends
-      ExtensibleIndexer
-  {
-
-    /**
-     * The Extensible Matching Rule.
-     */
-    private final CollationMatchingRule matchingRule;
-
-
-
-    /**
-     * Creates a new instance of CollationSharedExtensibleIndexer.
-     *
-     * @param matchingRule
-     *          The Collation Matching Rule.
-     */
-    private CollationSharedExtensibleIndexer(
-        CollationMatchingRule matchingRule)
-    {
-      this.matchingRule = matchingRule;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getExtensibleIndexID()
-    {
-      return EXTENSIBLE_INDEXER_ID_SHARED;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public final void createKeys(Schema schema, ByteSequence value,
-        IndexingOptions options, Collection<ByteString> keys)
-        throws DecodeException
-    {
-      keys.add(matchingRule.normalizeAttributeValue(value));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String getIndexID()
-    {
-      return matchingRule.getIndexName() + "." + getExtensibleIndexID();
-    }
-  }
-
-  /**
-   * Extensible Indexer class for Collation Substring Matching rules.
-   * This Indexer is used by Substring Collation Matching Rules.
-   */
-  private final class CollationSubstringExtensibleIndexer extends
-      ExtensibleIndexer
-  {
-    private final CollationSubstringMatchingRule matchingRule;
-
-    /**
-     * Creates a new instance of CollationSubstringExtensibleIndexer.
-     *
-     * @param matchingRule
-     *          The CollationSubstringMatching Rule.
-     */
-    private CollationSubstringExtensibleIndexer(
-        CollationSubstringMatchingRule matchingRule)
-    {
-      this.matchingRule = matchingRule;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void createKeys(Schema schema, ByteSequence value,
-        IndexingOptions options, Collection<ByteString> keys)
-    { // TODO merge with AbstractSubstringMatchingRuleImpl.SubstringIndexer.createKeys();
-      String normValue = value.toString();
-      int keyLength = options.substringKeySize();
-      for (int i = 0, remain = normValue.length(); remain > 0; i++, remain--)
-      {
-        int len = Math.min(keyLength, remain);
-        keys.add(matchingRule.makeSubstringKey(normValue, i, len));
-      }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String getIndexID()
-    {
-      return matchingRule.getIndexName() + "." + getExtensibleIndexID();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String getExtensibleIndexID()
-    {
-      return EXTENSIBLE_INDEXER_ID_SUBSTRING;
-    }
-
-  }
-
-  /**
    * A utility class for extracting the OID and Language Tag from the
    * configuration entry.
    */

--
Gitblit v1.10.0