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

matthew_swift
05.42.2009 22094368c2865dcfb6daf8366425212b721a4657
opends/src/dsml/org/opends/dsml/protocol/DSMLAddOperation.java
@@ -32,13 +32,13 @@
import org.opends.messages.Message;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.AddRequestProtocolOp;
import org.opends.server.protocols.ldap.AddResponseProtocolOp;
import org.opends.server.protocols.ldap.LDAPAttribute;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.protocols.ldap.ProtocolOp;
import org.opends.server.tools.LDAPConnection;
import org.opends.server.types.ByteString;
import org.opends.server.types.LDAPException;
import org.opends.server.types.RawAttribute;
@@ -86,17 +86,17 @@
    LDAPResult addResponse = objFactory.createLDAPResult();
    addResponse.setRequestID(addRequest.getRequestID());
    ASN1OctetString dnStr = new ASN1OctetString(addRequest.getDn());
    ByteString dnStr = ByteString.valueOf(addRequest.getDn());
    ArrayList<RawAttribute> attributes = new ArrayList<RawAttribute>();
    List<DsmlAttr> addList = addRequest.getAttr();
    for(DsmlAttr attr : addList)
    {
      ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
      ArrayList<ByteString> values = new ArrayList<ByteString>();
      List<String> vals = attr.getValue();
      for(String val : vals)
      {
        values.add(new ASN1OctetString(val));
        values.add(ByteString.valueOf(val));
      }
      LDAPAttribute ldapAttribute = new LDAPAttribute(attr.getName(), values);
      attributes.add(ldapAttribute);
opends/src/dsml/org/opends/dsml/protocol/DSMLCompareOperation.java
@@ -32,12 +32,12 @@
import org.opends.messages.Message;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.CompareRequestProtocolOp;
import org.opends.server.protocols.ldap.CompareResponseProtocolOp;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.protocols.ldap.ProtocolOp;
import org.opends.server.tools.LDAPConnection;
import org.opends.server.types.ByteString;
import org.opends.server.types.LDAPException;
@@ -87,10 +87,8 @@
    // Read the attribute name and value for the compare request.
    AttributeValueAssertion attrValAssertion = compareRequest.getAssertion();
    String attrName = attrValAssertion.getName();
    ASN1OctetString attrValue =
      new ASN1OctetString(attrValAssertion.getValue());
    ASN1OctetString dnStr = new ASN1OctetString(compareRequest.getDn());
    ByteString attrValue = ByteString.valueOf(attrValAssertion.getValue());
    ByteString dnStr = ByteString.valueOf(compareRequest.getDn());
    // Create and send the LDAP compare request to the server.
    ProtocolOp op = new CompareRequestProtocolOp(dnStr, attrName, attrValue);
opends/src/dsml/org/opends/dsml/protocol/DSMLDeleteOperation.java
@@ -30,12 +30,12 @@
import org.opends.messages.Message;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.DeleteRequestProtocolOp;
import org.opends.server.protocols.ldap.DeleteResponseProtocolOp;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.protocols.ldap.ProtocolOp;
import org.opends.server.tools.LDAPConnection;
import org.opends.server.types.ByteString;
import org.opends.server.types.DN;
import org.opends.server.types.LDAPException;
@@ -88,7 +88,7 @@
    delResponse.setRequestID(deleteRequest.getRequestID());
    // Create and send the LDAP delete request to the server.
    ASN1OctetString dnStr = new ASN1OctetString(deleteRequest.getDn());
    ByteString dnStr = ByteString.valueOf(deleteRequest.getDn());
    ProtocolOp op = new DeleteRequestProtocolOp(dnStr);
    LDAPMessage msg = new LDAPMessage(DSMLServlet.nextMessageID(), op);
    connection.getLDAPWriter().writeMessage(msg);
opends/src/dsml/org/opends/dsml/protocol/DSMLExtendedOperation.java
@@ -32,12 +32,12 @@
import org.opends.messages.Message;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.ExtendedRequestProtocolOp;
import org.opends.server.protocols.ldap.ExtendedResponseProtocolOp;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.protocols.ldap.ProtocolOp;
import org.opends.server.tools.LDAPConnection;
import org.opends.server.types.ByteString;
import org.opends.server.types.LDAPException;
@@ -86,7 +86,7 @@
    String requestName = extendedRequest.getRequestName();
    Object value = extendedRequest.getRequestValue();
    ASN1OctetString asnValue = new ASN1OctetString(value.toString());
    ByteString asnValue = ByteString.valueOf(value.toString());
    // Create and send the LDAP request to the server.
    ProtocolOp op = new ExtendedRequestProtocolOp(requestName, asnValue);
opends/src/dsml/org/opends/dsml/protocol/DSMLModifyDNOperation.java
@@ -33,11 +33,11 @@
import org.opends.messages.Message;
import org.opends.server.tools.LDAPConnection;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.protocols.ldap.ModifyDNRequestProtocolOp;
import org.opends.server.protocols.ldap.ModifyDNResponseProtocolOp;
import org.opends.server.protocols.ldap.ProtocolOp;
import org.opends.server.types.ByteString;
import org.opends.server.types.LDAPException;
@@ -84,22 +84,21 @@
  {
    LDAPResult modDNResponse = objFactory.createLDAPResult();
    modDNResponse.setRequestID(modifyDNRequest.getRequestID());
    ASN1OctetString dnStr = new ASN1OctetString(modifyDNRequest.getDn());
    ByteString dnStr = ByteString.valueOf(modifyDNRequest.getDn());
    ProtocolOp op = null;
    if(modifyDNRequest.getNewSuperior() != null)
    if (modifyDNRequest.getNewSuperior() != null)
    {
      op = new ModifyDNRequestProtocolOp(dnStr,
    new ASN1OctetString(modifyDNRequest.getNewrdn()),
    modifyDNRequest.isDeleteoldrdn(),
    new ASN1OctetString(modifyDNRequest.getNewSuperior()));
    } else
      op = new ModifyDNRequestProtocolOp(dnStr, ByteString
          .valueOf(modifyDNRequest.getNewrdn()), modifyDNRequest
          .isDeleteoldrdn(), ByteString.valueOf(modifyDNRequest
          .getNewSuperior()));
    }
    else
    {
      op = new ModifyDNRequestProtocolOp(dnStr,
    new ASN1OctetString(modifyDNRequest.getNewrdn()),
    modifyDNRequest.isDeleteoldrdn());
      op = new ModifyDNRequestProtocolOp(dnStr, ByteString
          .valueOf(modifyDNRequest.getNewrdn()), modifyDNRequest
          .isDeleteoldrdn());
    }
    // Create and send the LDAP request to the server.
opends/src/dsml/org/opends/dsml/protocol/DSMLModifyOperation.java
@@ -34,7 +34,6 @@
import org.opends.messages.Message;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPAttribute;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.protocols.ldap.LDAPModification;
@@ -42,6 +41,7 @@
import org.opends.server.protocols.ldap.ModifyResponseProtocolOp;
import org.opends.server.protocols.ldap.ProtocolOp;
import org.opends.server.tools.LDAPConnection;
import org.opends.server.types.ByteString;
import org.opends.server.types.LDAPException;
import org.opends.server.types.ModificationType;
import org.opends.server.types.RawModification;
@@ -109,12 +109,12 @@
      // Read the attribute name and values.
      String attrType = attr.getName();
      ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString> ();
      ArrayList<ByteString> values = new ArrayList<ByteString> ();
      List<String> vals = attr.getValue();
      for(String val : vals)
      {
        values.add(new ASN1OctetString(val));
        values.add(ByteString.valueOf(val));
      }
      LDAPAttribute ldapAttr = new LDAPAttribute(attrType, values);
@@ -123,7 +123,7 @@
    }
    ASN1OctetString dnStr = new ASN1OctetString(modifyRequest.getDn());
    ByteString dnStr = ByteString.valueOf(modifyRequest.getDn());
    // Create and send the LDAP request to the server.
    ProtocolOp op = new ModifyRequestProtocolOp(dnStr, modifications);
opends/src/dsml/org/opends/dsml/protocol/DSMLSearchOperation.java
@@ -25,25 +25,26 @@
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.opends.dsml.protocol;
import org.opends.messages.Message;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPAttribute;
import org.opends.server.protocols.ldap.LDAPConstants;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.protocols.ldap.SearchRequestProtocolOp;
import org.opends.server.protocols.ldap.SearchResultEntryProtocolOp;
import org.opends.server.protocols.ldap.SearchResultReferenceProtocolOp;
import org.opends.server.protocols.ldap.SearchResultDoneProtocolOp;
import org.opends.server.tools.LDAPConnection;
import org.opends.server.types.ByteString;
@@ -55,17 +56,21 @@
/**
 * This class provides the functionality for the performing an
 * LDAP SEARCH operation based on the specified DSML request.
 * This class provides the functionality for the performing an LDAP
 * SEARCH operation based on the specified DSML request.
 */
public class DSMLSearchOperation
{
  private LDAPConnection connection;
  /**
   * Create the instance with the specified connection.
   *
   * @param connection    The LDAP connection to send the request on.
   * @param connection
   *          The LDAP connection to send the request on.
   */
  public DSMLSearchOperation(LDAPConnection connection)
@@ -73,301 +78,381 @@
    this.connection = connection;
  }
  /**
   * Returns a new AND search filter with the provided filter components.
   * Returns a new AND search filter with the provided filter
   * components.
   *
   * @param filterSet The filter components for this filter
   *
   * @return a new AND search filter with the provided filter components.
   *
   * @throws LDAPException an LDAPException is thrown if the creation of a
   *                       filter component fails.
   * @param filterSet
   *          The filter components for this filter
   * @return a new AND search filter with the provided filter
   *         components.
   * @throws LDAPException
   *           an LDAPException is thrown if the creation of a filter
   *           component fails.
   */
  private static LDAPFilter createANDFilter(FilterSet filterSet)
          throws LDAPException {
      throws LDAPException
  {
    List<JAXBElement<?>> list = filterSet.getFilterGroup();
    ArrayList<RawFilter> filters = new ArrayList<RawFilter>(list.size());
    for(JAXBElement<?> filter : list) {
    for (JAXBElement<?> filter : list)
    {
      filters.add(createFilter(filter));
    }
    return LDAPFilter.createANDFilter(filters);
  }
  /**
   * Returns a new Approximate search filter with the provided information.
   * Returns a new Approximate search filter with the provided
   * information.
   *
   * @param ava the attribute value assertion for this approximate filter.
   *
   * @return a new Approximate search filter with the provided information.
   * @param ava
   *          the attribute value assertion for this approximate
   *          filter.
   * @return a new Approximate search filter with the provided
   *         information.
   */
  private static LDAPFilter createApproximateFilter(AttributeValueAssertion ava)
  {
    return LDAPFilter.createApproximateFilter(ava.getName(),
                                           new ASN1OctetString(ava.getValue()));
    return LDAPFilter.createApproximateFilter(ava.getName(), ByteString
        .valueOf(ava.getValue()));
  }
  /**
   * Returns a new Equality search filter with the provided information.
   * Returns a new Equality search filter with the provided
   * information.
   *
   * @param ava the attribute value assertion for this Equality filter.
   *
   * @return a new Equality search filter with the provided information.
   * @param ava
   *          the attribute value assertion for this Equality filter.
   * @return a new Equality search filter with the provided
   *         information.
   */
  private static LDAPFilter createEqualityFilter(AttributeValueAssertion ava) {
    return LDAPFilter.createEqualityFilter(ava.getName(),
                                          new ASN1OctetString(ava.getValue()));
  private static LDAPFilter createEqualityFilter(AttributeValueAssertion ava)
  {
    return LDAPFilter.createEqualityFilter(ava.getName(), ByteString
        .valueOf(ava.getValue()));
  }
  /**
   * Returns a new Extensible search filter with the provided information.
   * Returns a new Extensible search filter with the provided
   * information.
   *
   * @param mra the matching rule assertion for this Extensible filter.
   *
   * @return a new Extensible search filter with the provided information.
   * @param mra
   *          the matching rule assertion for this Extensible filter.
   * @return a new Extensible search filter with the provided
   *         information.
   */
  private static LDAPFilter createExtensibleFilter(MatchingRuleAssertion mra) {
    return LDAPFilter.createExtensibleFilter(mra.getMatchingRule(),
                                        mra.getName(),
                                        new ASN1OctetString(mra.getValue()),
                                        mra.isDnAttributes());
  private static LDAPFilter createExtensibleFilter(MatchingRuleAssertion mra)
  {
    return LDAPFilter.createExtensibleFilter(mra.getMatchingRule(), mra
        .getName(), ByteString.valueOf(mra.getValue()), mra.isDnAttributes());
  }
  /**
   * Returns a new GreaterOrEqual search filter with the provided information.
   * Returns a new GreaterOrEqual search filter with the provided
   * information.
   *
   * @param ava the attribute value assertion for this GreaterOrEqual filter.
   *
   * @return a new GreaterOrEqual search filter with the provided information.
   * @param ava
   *          the attribute value assertion for this GreaterOrEqual
   *          filter.
   * @return a new GreaterOrEqual search filter with the provided
   *         information.
   */
  private static LDAPFilter createGreaterOrEqualFilter(
                              AttributeValueAssertion ava) {
    return LDAPFilter.createGreaterOrEqualFilter(ava.getName(),
                                          new ASN1OctetString(ava.getValue()));
      AttributeValueAssertion ava)
  {
    return LDAPFilter.createGreaterOrEqualFilter(ava.getName(), ByteString
        .valueOf(ava.getValue()));
  }
  /**
   * Returns a new LessOrEqual search filter with the provided information.
   * Returns a new LessOrEqual search filter with the provided
   * information.
   *
   * @param ava the attribute value assertion for this LessOrEqual filter.
   *
   * @return a new LessOrEqual search filter with the provided information.
   * @param ava
   *          the attribute value assertion for this LessOrEqual
   *          filter.
   * @return a new LessOrEqual search filter with the provided
   *         information.
   */
  private static LDAPFilter createLessOrEqualFilter(
                              AttributeValueAssertion ava) {
    return LDAPFilter.createLessOrEqualFilter(ava.getName(),
                                          new ASN1OctetString(ava.getValue()));
  private static LDAPFilter createLessOrEqualFilter(AttributeValueAssertion ava)
  {
    return LDAPFilter.createLessOrEqualFilter(ava.getName(), ByteString
        .valueOf(ava.getValue()));
  }
  /**
   * Returns a new NOT search filter with the provided information.
   *
   * @param filter the filter for this NOT filter.
   *
   * @param filter
   *          the filter for this NOT filter.
   * @return a new NOT search filter with the provided information.
   *
   * @throws LDAPException an LDAPException is thrown if the creation of the
   *                       provided filter fails.
   * @throws LDAPException
   *           an LDAPException is thrown if the creation of the
   *           provided filter fails.
   */
  private static LDAPFilter createNOTFilter(Filter filter)
          throws LDAPException {
  private static LDAPFilter createNOTFilter(Filter filter) throws LDAPException
  {
    return LDAPFilter.createNOTFilter(createFilter(filter));
  }
  /**
   * Returns a new OR search filter with the provided filter components.
   * Returns a new OR search filter with the provided filter
   * components.
   *
   * @param filterSet The filter components for this filter
   *
   * @return a new OR search filter with the provided filter components.
   *
   * @throws LDAPException an LDAPException is thrown if the creation of a
   *                       filter component fails.
   * @param filterSet
   *          The filter components for this filter
   * @return a new OR search filter with the provided filter
   *         components.
   * @throws LDAPException
   *           an LDAPException is thrown if the creation of a filter
   *           component fails.
   */
  private static LDAPFilter createORFilter(FilterSet filterSet)
          throws LDAPException {
      throws LDAPException
  {
    List<JAXBElement<?>> list = filterSet.getFilterGroup();
    ArrayList<RawFilter> filters = new ArrayList<RawFilter>(list.size());
    for(JAXBElement<?> filter : list) {
    for (JAXBElement<?> filter : list)
    {
      filters.add(createFilter(filter));
    }
    return LDAPFilter.createORFilter(filters);
  }
  /**
   * Returns a new Present search filter with the provided information.
   * Returns a new Present search filter with the provided
   * information.
   *
   * @param ad the attribute description for this Present filter.
   *
   * @param ad
   *          the attribute description for this Present filter.
   * @returna new Present search filter with the provided information.
   *
   * @throws LDAPException an LDAPException is thrown if the ASN.1 element
   *                       provided by the attribute description cannot be
   *                       decoded as a raw search filter.
   * @throws LDAPException
   *           an LDAPException is thrown if the ASN.1 element
   *           provided by the attribute description cannot be decoded
   *           as a raw search filter.
   */
  private static LDAPFilter createPresentFilter(AttributeDescription ad)
          throws LDAPException {
    return LDAPFilter.decode(
             new StringBuilder(ad.getName()).append("=*").toString());
      throws LDAPException
  {
    return LDAPFilter.decode(new StringBuilder(ad.getName()).append("=*")
        .toString());
  }
  /**
   * Returns a new Substring search filter with the provided information.
   * Returns a new Substring search filter with the provided
   * information.
   *
   * @param sf the substring filter for this Substring filter.
   *
   * @return a new Substring search filter with the provided information.
   * @param sf
   *          the substring filter for this Substring filter.
   * @return a new Substring search filter with the provided
   *         information.
   */
  private static LDAPFilter createSubstringFilter(SubstringFilter sf) {
  private static LDAPFilter createSubstringFilter(SubstringFilter sf)
  {
    List<String> anys = sf.getAny();
    ArrayList<ByteString> subAnyElements =
                                         new ArrayList<ByteString>(anys.size());
    ArrayList<ByteString> subAnyElements = new ArrayList<ByteString>(anys
        .size());
    for(String s : anys) {
      subAnyElements.add(new ASN1OctetString(s));
    for (String s : anys)
    {
      subAnyElements.add(ByteString.valueOf(s));
    }
    return LDAPFilter.createSubstringFilter(sf.getName(),
                                        new ASN1OctetString(sf.getInitial()),
                                        subAnyElements,
                                        new ASN1OctetString(sf.getFinal()));
    return LDAPFilter.createSubstringFilter(sf.getName(), ByteString.valueOf(sf
        .getInitial()), subAnyElements, ByteString.valueOf(sf.getFinal()));
  }
  /**
   * Returns a new LDAPFilter according to the tag name of the provided element
   * that can be "and", "or", "not", "equalityMatch", "substrings",
   * "greaterOrEqual", "lessOrEqual", "present", "approxMatch",
   * "extensibleMatch".
   * Returns a new LDAPFilter according to the tag name of the
   * provided element that can be "and", "or", "not", "equalityMatch",
   * "substrings", "greaterOrEqual", "lessOrEqual", "present",
   * "approxMatch", "extensibleMatch".
   *
   * @param xmlElement a JAXBElement that contains the name of the filter to
   *                   create and the associated argument.
   *
   * @return a new LDAPFilter according to the tag name of the provided element.
   *
   * @throws LDAPException an LDAPException is thrown if the creation of the
   *                       targeted filter fails.
   * @param xmlElement
   *          a JAXBElement that contains the name of the filter to
   *          create and the associated argument.
   * @return a new LDAPFilter according to the tag name of the
   *         provided element.
   * @throws LDAPException
   *           an LDAPException is thrown if the creation of the
   *           targeted filter fails.
   */
  private static LDAPFilter createFilter(JAXBElement<?> xmlElement)
          throws LDAPException {
      throws LDAPException
  {
    LDAPFilter result = null;
    String filterName = xmlElement.getName().getLocalPart();
    if ( "and".equals(filterName) ) {
    if ("and".equals(filterName))
    {
      // <xsd:element name="and" type="FilterSet"/>
      result = createANDFilter((FilterSet)xmlElement.getValue());
      result = createANDFilter((FilterSet) xmlElement.getValue());
    }
    else if ( "or".equals(filterName) ) {
    else if ("or".equals(filterName))
    {
      // <xsd:element name="or" type="FilterSet"/>
      result = createORFilter((FilterSet)xmlElement.getValue());
      result = createORFilter((FilterSet) xmlElement.getValue());
    }
    else if ( "not".equals(filterName) ) {
    else if ("not".equals(filterName))
    {
      // <xsd:element name="not" type="Filter"/>
      result = createNOTFilter((Filter)xmlElement.getValue());
      result = createNOTFilter((Filter) xmlElement.getValue());
    }
    else if ( "equalityMatch".equals(filterName) ) {
      // <xsd:element name="equalityMatch" type="AttributeValueAssertion"/>
      result = createEqualityFilter((AttributeValueAssertion)
                                                         xmlElement.getValue());
    else if ("equalityMatch".equals(filterName))
    {
      // <xsd:element name="equalityMatch"
      // type="AttributeValueAssertion"/>
      result = createEqualityFilter((AttributeValueAssertion) xmlElement
          .getValue());
    }
    else if ( "substrings".equals(filterName) ) {
    else if ("substrings".equals(filterName))
    {
      // <xsd:element name="substrings" type="SubstringFilter"/>
      result = createSubstringFilter((SubstringFilter)xmlElement.getValue());
      result = createSubstringFilter((SubstringFilter) xmlElement.getValue());
    }
    else if ( "greaterOrEqual".equals(filterName) ) {
      // <xsd:element name="greaterOrEqual" type="AttributeValueAssertion"/>
      result = createGreaterOrEqualFilter((AttributeValueAssertion)
                                                         xmlElement.getValue());
    else if ("greaterOrEqual".equals(filterName))
    {
      // <xsd:element name="greaterOrEqual"
      // type="AttributeValueAssertion"/>
      result = createGreaterOrEqualFilter((AttributeValueAssertion) xmlElement
          .getValue());
    }
    else if ( "lessOrEqual".equals(filterName) ) {
      // <xsd:element name="lessOrEqual" type="AttributeValueAssertion"/>
      result = createLessOrEqualFilter((AttributeValueAssertion)
                                                         xmlElement.getValue());
    else if ("lessOrEqual".equals(filterName))
    {
      // <xsd:element name="lessOrEqual"
      // type="AttributeValueAssertion"/>
      result = createLessOrEqualFilter((AttributeValueAssertion) xmlElement
          .getValue());
    }
    else if ( "present".equals(filterName) ) {
    else if ("present".equals(filterName))
    {
      // <xsd:element name="present" type="AttributeDescription"/>
      result = createPresentFilter((AttributeDescription)xmlElement.getValue());
      result =
        createPresentFilter((AttributeDescription) xmlElement.getValue());
    }
    else if ( "approxMatch".equals(filterName) ) {
      // <xsd:element name="approxMatch" type="AttributeValueAssertion"/>
      result = createApproximateFilter((AttributeValueAssertion)
                                                         xmlElement.getValue());
    else if ("approxMatch".equals(filterName))
    {
      // <xsd:element name="approxMatch"
      // type="AttributeValueAssertion"/>
      result = createApproximateFilter((AttributeValueAssertion) xmlElement
          .getValue());
    }
    else if ( "extensibleMatch".equals(filterName) ) {
      // <xsd:element name="extensibleMatch" type="MatchingRuleAssertion"/>
      result = createExtensibleFilter((MatchingRuleAssertion)
                                                         xmlElement.getValue());
    else if ("extensibleMatch".equals(filterName))
    {
      // <xsd:element name="extensibleMatch"
      // type="MatchingRuleAssertion"/>
      result = createExtensibleFilter((MatchingRuleAssertion) xmlElement
          .getValue());
    }
    return result;
  }
  /**
   * Returns a new LDAPFilter according to the filter assigned to the provided
   * filter.
   * Returns a new LDAPFilter according to the filter assigned to the
   * provided filter.
   *
   * @param filter a filter that contains the object filter to create.
   *
   * @return a new LDAPFilter according to the filter assigned to the provided
   *         filter.
   *
   * @throws LDAPException an LDAPException is thrown if the creation of the
   *                       targeted filter fails.
   * @param filter
   *          a filter that contains the object filter to create.
   * @return a new LDAPFilter according to the filter assigned to the
   *         provided filter.
   * @throws LDAPException
   *           an LDAPException is thrown if the creation of the
   *           targeted filter fails.
   */
  private static LDAPFilter createFilter(Filter filter)
          throws LDAPException {
  private static LDAPFilter createFilter(Filter filter) throws LDAPException
  {
    LDAPFilter result = null;
    if ( filter.getAnd() != null ) {
    if (filter.getAnd() != null)
    {
      result = createANDFilter(filter.getAnd());
    }
    else if ( filter.getApproxMatch() != null ) {
    else if (filter.getApproxMatch() != null)
    {
      result = createApproximateFilter(filter.getApproxMatch());
    }
    else if ( filter.getEqualityMatch() != null ) {
    else if (filter.getEqualityMatch() != null)
    {
      result = createEqualityFilter(filter.getEqualityMatch());
    }
    else if ( filter.getExtensibleMatch() != null ) {
    else if (filter.getExtensibleMatch() != null)
    {
      result = createExtensibleFilter(filter.getExtensibleMatch());
    }
    else if ( filter.getGreaterOrEqual() != null ) {
    else if (filter.getGreaterOrEqual() != null)
    {
      result = createGreaterOrEqualFilter(filter.getGreaterOrEqual());
    }
    else if ( filter.getLessOrEqual() != null ) {
    else if (filter.getLessOrEqual() != null)
    {
      result = createLessOrEqualFilter(filter.getLessOrEqual());
    }
    else if ( filter.getNot() != null ) {
    else if (filter.getNot() != null)
    {
      result = createNOTFilter(filter.getNot());
    }
    else if ( filter.getOr() != null ) {
    else if (filter.getOr() != null)
    {
      result = createORFilter(filter.getOr());
    }
    else if ( filter.getPresent() != null ) {
    else if (filter.getPresent() != null)
    {
      result = createPresentFilter(filter.getPresent());
    }
    else if ( filter.getSubstrings() != null ) {
    else if (filter.getSubstrings() != null)
    {
      result = createSubstringFilter(filter.getSubstrings());
    }
    return result;
  }
  /**
   * Perform the LDAP SEARCH operation and send the result back to the
   * client.
   *
   * @param  objFactory     The object factory for this operation.
   * @param  searchRequest  The search request for this operation.
   *
   * @return  The result of the add operation.
   *
   * @throws  IOException  If an I/O problem occurs.
   *
   * @throws  LDAPException  If an error occurs while interacting with an LDAP
   *                         element.
   * @param objFactory
   *          The object factory for this operation.
   * @param searchRequest
   *          The search request for this operation.
   * @return The result of the add operation.
   * @throws IOException
   *           If an I/O problem occurs.
   * @throws LDAPException
   *           If an error occurs while interacting with an LDAP
   *           element.
   */
  public SearchResponse doSearch(ObjectFactory objFactory,
         SearchRequest searchRequest)
         throws IOException, LDAPException
      SearchRequest searchRequest) throws IOException, LDAPException
  {
    SearchResponse searchResponse = objFactory.createSearchResponse();
    searchResponse.setRequestID(searchRequest.getRequestID());
@@ -391,10 +476,11 @@
    SearchScope scope = SearchScope.WHOLE_SUBTREE;
    String scopeStr = searchRequest.getScope().toLowerCase();
    if(scopeStr.equals("singlelevel") || scopeStr.equals("one"))
    if (scopeStr.equals("singlelevel") || scopeStr.equals("one"))
    {
      scope = SearchScope.SINGLE_LEVEL;
    } else if(scopeStr.equals("baseobject") || scopeStr.equals("base"))
    }
    else if (scopeStr.equals("baseobject") || scopeStr.equals("base"))
    {
      scope = SearchScope.BASE_OBJECT;
    }
@@ -402,25 +488,23 @@
    LinkedHashSet<String> attributes = new LinkedHashSet<String>();
    // Get the list of attributes.
    AttributeDescriptions attrDescriptions = searchRequest.getAttributes();
    if(attrDescriptions != null)
    if (attrDescriptions != null)
    {
      List<AttributeDescription> attrDesc = attrDescriptions.getAttribute();
      for(AttributeDescription desc : attrDesc)
      for (AttributeDescription desc : attrDesc)
      {
        attributes.add(desc.getName());
      }
    }
    SearchRequestProtocolOp protocolOp = new SearchRequestProtocolOp(
        new ASN1OctetString(searchRequest.getDn()),
        scope, derefPolicy,
                (int) searchRequest.getSizeLimit(),
        (int) searchRequest.getTimeLimit(),
    SearchRequestProtocolOp protocolOp = new SearchRequestProtocolOp(ByteString
        .valueOf(searchRequest.getDn()), scope, derefPolicy,
        (int) searchRequest.getSizeLimit(), (int) searchRequest.getTimeLimit(),
        searchRequest.isTypesOnly(), filter, attributes);
    try
    {
      LDAPMessage msg = new LDAPMessage(DSMLServlet.nextMessageID(),
                                        protocolOp);
      LDAPMessage msg =
        new LDAPMessage(DSMLServlet.nextMessageID(), protocolOp);
      connection.getLDAPWriter().writeMessage(msg);
      byte opType;
@@ -428,68 +512,68 @@
      {
        int resultCode = 0;
        Message errorMessage = null;
        LDAPMessage responseMessage =
             connection.getLDAPReader().readMessage();
        LDAPMessage responseMessage = connection.getLDAPReader().readMessage();
        opType = responseMessage.getProtocolOpType();
        switch(opType)
        switch (opType)
        {
          case LDAPConstants.OP_TYPE_SEARCH_RESULT_ENTRY:
            SearchResultEntryProtocolOp searchEntryOp =
              responseMessage.getSearchResultEntryProtocolOp();
        case LDAPConstants.OP_TYPE_SEARCH_RESULT_ENTRY:
          SearchResultEntryProtocolOp searchEntryOp = responseMessage
              .getSearchResultEntryProtocolOp();
            SearchResultEntry entry = objFactory.createSearchResultEntry();
            java.util.List<DsmlAttr> attrList = entry.getAttr();
          SearchResultEntry entry = objFactory.createSearchResultEntry();
          java.util.List<DsmlAttr> attrList = entry.getAttr();
            LinkedList<LDAPAttribute> attrs = searchEntryOp.getAttributes();
          LinkedList<LDAPAttribute> attrs = searchEntryOp.getAttributes();
            for(LDAPAttribute attr : attrs)
          for (LDAPAttribute attr : attrs)
          {
            String nm = attr.getAttributeType();
            DsmlAttr dsmlAttr = objFactory.createDsmlAttr();
            dsmlAttr.setName(nm);
            List<String> dsmlAttrVal = dsmlAttr.getValue();
            ArrayList<ByteString> vals = attr.getValues();
            for (ByteString val : vals)
            {
              String nm = attr.getAttributeType();
              DsmlAttr dsmlAttr = objFactory.createDsmlAttr();
              dsmlAttr.setName(nm);
              List<String> dsmlAttrVal = dsmlAttr.getValue();
              ArrayList<ASN1OctetString> vals = attr.getValues();
              for(ASN1OctetString val : vals)
              {
                dsmlAttrVal.add(val.toString());
              }
              attrList.add(dsmlAttr);
              dsmlAttrVal.add(val.toString());
            }
            attrList.add(dsmlAttr);
          }
            entry.setDn(searchEntryOp.getDN().toString());
            searchResponse.getSearchResultEntry().add(entry);
            break;
          entry.setDn(searchEntryOp.getDN().toString());
          searchResponse.getSearchResultEntry().add(entry);
          break;
          case LDAPConstants.OP_TYPE_SEARCH_RESULT_REFERENCE:
            SearchResultReferenceProtocolOp searchRefOp =
              responseMessage.getSearchResultReferenceProtocolOp();
            break;
        case LDAPConstants.OP_TYPE_SEARCH_RESULT_REFERENCE:
          responseMessage.getSearchResultReferenceProtocolOp();
          break;
          case LDAPConstants.OP_TYPE_SEARCH_RESULT_DONE:
            SearchResultDoneProtocolOp searchOp =
              responseMessage.getSearchResultDoneProtocolOp();
            resultCode = searchOp.getResultCode();
            errorMessage = searchOp.getErrorMessage();
            LDAPResult result = objFactory.createLDAPResult();
            ResultCode code = objFactory.createResultCode();
            code.setCode(resultCode);
            result.setResultCode(code);
            result.setErrorMessage(
                    errorMessage != null ? errorMessage.toString() : null);
            if(searchOp.getMatchedDN() != null)
            {
               result.setMatchedDN(searchOp.getMatchedDN().toString());
            }
            searchResponse.setSearchResultDone(result);
            break;
          default:
             throw new RuntimeException("Invalid protocol operation:" + opType);
         }
      } while(opType != LDAPConstants.OP_TYPE_SEARCH_RESULT_DONE);
        case LDAPConstants.OP_TYPE_SEARCH_RESULT_DONE:
          SearchResultDoneProtocolOp searchOp = responseMessage
              .getSearchResultDoneProtocolOp();
          resultCode = searchOp.getResultCode();
          errorMessage = searchOp.getErrorMessage();
          LDAPResult result = objFactory.createLDAPResult();
          ResultCode code = objFactory.createResultCode();
          code.setCode(resultCode);
          result.setResultCode(code);
          result.setErrorMessage(errorMessage != null ? errorMessage.toString()
              : null);
          if (searchOp.getMatchedDN() != null)
          {
            result.setMatchedDN(searchOp.getMatchedDN().toString());
          }
          searchResponse.setSearchResultDone(result);
          break;
        default:
          throw new RuntimeException("Invalid protocol operation:" + opType);
        }
      }
      while (opType != LDAPConstants.OP_TYPE_SEARCH_RESULT_DONE);
    } catch(ASN1Exception ae)
    }
    catch (ASN1Exception ae)
    {
      ae.printStackTrace();
      throw new IOException(ae.getMessage());
@@ -498,4 +582,3 @@
    return searchResponse;
  }
}
opends/src/guitools/org/opends/guitools/controlpanel/task/ModifyEntryTask.java
@@ -62,16 +62,7 @@
import org.opends.messages.AdminToolMessages;
import org.opends.messages.Message;
import org.opends.server.config.ConfigConstants;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
import org.opends.server.types.ByteStringFactory;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.OpenDsException;
import org.opends.server.types.RDN;
import org.opends.server.types.Schema;
import org.opends.server.types.*;
/**
 * The task that is called when we must modify an entry.
@@ -691,7 +682,7 @@
    Attribute attribute = new BasicAttribute(attrName);
    for (AttributeValue value : values)
    {
      attribute.add(value.getValue().value());
      attribute.add(value.getValue().toByteArray());
    }
    return attribute;
  }
@@ -709,17 +700,17 @@
    ByteString v;
    if (value instanceof String)
    {
      v = ByteStringFactory.create((String)value);
      v = ByteString.valueOf((String)value);
    }
    else if (value instanceof byte[])
    {
      v = ByteStringFactory.create((byte[])value);
      v = ByteString.wrap((byte[])value);
    }
    else
    {
      v = ByteStringFactory.create(String.valueOf(value));
      v = ByteString.valueOf(String.valueOf(value));
    }
    return new AttributeValue(attrType, v);
    return AttributeValues.create(attrType, v);
  }
  /**
opends/src/guitools/org/opends/guitools/controlpanel/task/NewEntryTask.java
@@ -224,7 +224,7 @@
        BasicAttribute a = new BasicAttribute(attrName);
        for (AttributeValue value : values)
        {
          a.add(value.getValueBytes());
          a.add(value.getValue().toByteArray());
        }
        attrs.put(a);
      }
opends/src/guitools/org/opends/guitools/controlpanel/task/Task.java
@@ -54,7 +54,6 @@
import org.opends.guitools.controlpanel.util.Utilities;
import org.opends.messages.Message;
import org.opends.server.types.ByteString;
import org.opends.server.types.ByteStringFactory;
import org.opends.server.types.DN;
import org.opends.server.types.Schema;
import org.opends.server.util.Base64;
@@ -473,8 +472,8 @@
          else
          {
            // Get the String value
            ByteString v = ByteStringFactory.create(bytes);
            return v.stringValue();
            ByteString v = ByteString.wrap(bytes);
            return v.toString();
          }
        }
      }
opends/src/guitools/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java
@@ -99,12 +99,7 @@
import org.opends.quicksetup.util.UIKeyStore;
import org.opends.quicksetup.util.Utils;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.LDAPException;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.*;
/**
 * The abstract class used to refactor some code.  The classes that extend this
@@ -821,7 +816,7 @@
                attr.toString().toLowerCase());
          LDAPFilter ldapFilter =
            new LDAPFilter(SearchFilter.createEqualityFilter(
              attrType, new AttributeValue(attrType, s)));
              attrType, AttributeValues.create(attrType, s)));
          returnValue = ldapFilter.toString();
        }
      }
opends/src/guitools/org/opends/guitools/controlpanel/ui/JavaPropertiesPanel.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 */
package org.opends.guitools.controlpanel.ui;
@@ -174,6 +174,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public Message getTitle()
  {
    return INFO_CTRL_PANEL_JAVA_PROPERTIES_TITLE.get();
@@ -182,6 +183,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public Component getPreferredFocusComponent()
  {
    return javaHome;
@@ -190,6 +192,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean requiresScroll()
  {
    return false;
@@ -198,6 +201,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void setInfo(ControlPanelInfo info)
  {
    super.setInfo(info);
@@ -425,6 +429,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void toBeDisplayed(boolean visible)
  {
    if (visible && (firstDisplay || !updatedByUser()))
@@ -557,6 +562,7 @@
      /**
       * {@inheritDoc}
       */
      @Override
      public Void processBackgroundTask() throws Throwable
      {
        String propertiesFile = getPropertiesFile();
@@ -623,6 +629,7 @@
      /**
       * {@inheritDoc}
       */
      @Override
      public void backgroundTaskCompleted(Void returnValue,
          Throwable t)
      {
@@ -701,6 +708,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void okClicked()
  {
    editor.stopCellEditing();
@@ -748,6 +756,7 @@
          new BackgroundTask<Set<String>>()
        {
          private String jvm;
          @Override
          public Set<String> processBackgroundTask() throws Throwable
          {
            Set<String> notWorkingArgs = new HashSet<String>();
@@ -776,6 +785,7 @@
          /**
           * {@inheritDoc}
           */
          @Override
          public void backgroundTaskCompleted(Set<String> returnValue,
              Throwable t)
          {
@@ -949,6 +959,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode()
    {
      return hashCode;
@@ -957,6 +968,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public String toString()
    {
      return toString;
@@ -965,6 +977,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object o)
    {
      boolean equals = o == this;
@@ -1055,6 +1068,7 @@
     * Updates the table model contents and sorts its contents depending on the
     * sort options set by the user.
     */
    @Override
    public void forceResort()
    {
      updateDataArray();
@@ -1090,6 +1104,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public String getColumnName(int col) {
      return COLUMN_NAMES[col];
    }
@@ -1110,6 +1125,7 @@
     * @return <CODE>true</CODE> if the sort is ascending and <CODE>false</CODE>
     * otherwise.
     */
    @Override
    public boolean isSortAscending()
    {
      return sortAscending;
@@ -1119,6 +1135,7 @@
     * Sets whether to sort ascending of descending.
     * @param sortAscending whether to sort ascending or descending.
     */
    @Override
    public void setSortAscending(boolean sortAscending)
    {
      this.sortAscending = sortAscending;
@@ -1128,6 +1145,7 @@
     * Returns the column index used to sort.
     * @return the column index used to sort.
     */
    @Override
    public int getSortColumn()
    {
      return sortColumn;
@@ -1137,6 +1155,7 @@
     * Sets the column index used to sort.
     * @param sortColumn column index used to sort..
     */
    @Override
    public void setSortColumn(int sortColumn)
    {
      this.sortColumn = sortColumn;
@@ -1145,6 +1164,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isCellEditable(int row, int col) {
      if (col == 0)
      {
@@ -1158,6 +1178,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public void setValueAt(Object value, int row, int col)
    {
      dataArray.get(row)[col] = (String)value;
@@ -1248,6 +1269,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public Type getType()
    {
      return Type.JAVA_SETTINGS_UPDATE;
@@ -1256,6 +1278,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public Set<String> getBackends()
    {
      return backendSet;
@@ -1264,6 +1287,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public Message getTaskDescription()
    {
      return INFO_CTRL_PANEL_UPDATE_JAVA_SETTINGS_TASK_DESCRIPTION.get();
@@ -1272,6 +1296,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean canLaunch(Task taskToBeLaunched,
        Collection<Message> incompatibilityReasons)
    {
@@ -1300,6 +1325,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    protected String getCommandLinePath()
    {
      return null;
@@ -1308,6 +1334,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    protected ArrayList<String> getCommandLineArguments()
    {
      return new ArrayList<String>();
@@ -1316,6 +1343,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public void runTask()
    {
      state = State.RUNNING;
opends/src/guitools/org/opends/guitools/controlpanel/ui/NewBaseDNPanel.java
@@ -1293,7 +1293,7 @@
          while (it.hasNext())
          {
            oc.add(it.next().getStringValue());
            oc.add(it.next().getValue().toString());
          }
          attrs.put(oc);
@@ -1306,7 +1306,7 @@
            it = odsAttr.iterator();
            while (it.hasNext())
            {
              attr.add(it.next().getStringValue());
              attr.add(it.next().getValue().toString());
            }
            attrs.put(attr);
@@ -1315,7 +1315,7 @@
              args.add("--index-name");
              AttributeValue value =
                odsAttr.iterator().next();
              args.add(value.getStringValue());
              args.add(value.getValue().toString());
            }
            else if (attrName.equalsIgnoreCase("ds-cfg-index-type"))
            {
@@ -1323,7 +1323,7 @@
              while (it.hasNext())
              {
                args.add("--set");
                args.add("index-type:"+it.next().getStringValue());
                args.add("index-type:"+it.next().getValue().toString());
              }
            }
          }
opends/src/guitools/org/opends/guitools/controlpanel/ui/NewIndexPanel.java
@@ -635,7 +635,7 @@
          indexEntry.getObjectClassAttribute().iterator();
        while (it.hasNext())
        {
          oc.add(it.next().getStringValue());
          oc.add(it.next().getValue().toString());
        }
        attrs.put(oc);
@@ -647,7 +647,7 @@
          it = odsAttr.iterator();
          while (it.hasNext())
          {
            attr.add(it.next().getStringValue());
            attr.add(it.next().getValue().toString());
          }
          attrs.put(attr);
        }
opends/src/guitools/org/opends/guitools/controlpanel/ui/NewVLVIndexPanel.java
@@ -91,6 +91,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public Message getTitle()
  {
    return INFO_CTRL_PANEL_NEW_VLV_INDEX_TITLE.get();
@@ -99,6 +100,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public Component getPreferredFocusComponent()
  {
    return name;
@@ -129,6 +131,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void okClicked()
  {
    List<Message> errors = checkErrors(true);
@@ -211,6 +214,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public Type getType()
    {
      return Type.NEW_INDEX;
@@ -219,6 +223,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public Set<String> getBackends()
    {
      return backendSet;
@@ -227,6 +232,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public Message getTaskDescription()
    {
      return INFO_CTRL_PANEL_NEW_VLV_INDEX_TASK_DESCRIPTION.get(
@@ -236,6 +242,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean canLaunch(Task taskToBeLaunched,
        Collection<Message> incompatibilityReasons)
    {
@@ -420,6 +427,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    protected String getCommandLinePath()
    {
      return null;
@@ -428,6 +436,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    protected ArrayList<String> getCommandLineArguments()
    {
      return new ArrayList<String>();
@@ -448,6 +457,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public void runTask()
    {
      state = State.RUNNING;
@@ -481,6 +491,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public void postOperation()
    {
      if ((lastException == null) && (state == State.FINISHED_SUCCESSFULLY) &&
opends/src/guitools/org/opends/guitools/controlpanel/ui/SimplifiedViewEntryPanel.java
@@ -90,15 +90,7 @@
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import org.opends.server.schema.SchemaConstants;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.OpenDsException;
import org.opends.server.types.RDN;
import org.opends.server.types.Schema;
import org.opends.server.types.*;
import org.opends.server.util.Base64;
import org.opends.server.util.LDIFReader;
import org.opends.server.util.ServerConstants;
@@ -1610,7 +1602,7 @@
          String attrName = rdn.getAttributeName(i);
          AttributeValue value = rdn.getAttributeValue(i);
          String sValue = value.getStringValue();
          String sValue = value.getValue().toString();
          Set<String> values = getDisplayedStringValues(attrName);
          if (!values.contains(sValue))
@@ -1632,7 +1624,8 @@
                AttributeType attr = rdn.getAttributeType(i);
                attributeTypes.add(attr);
                attributeNames.add(rdn.getAttributeName(i));
                attributeValues.add(new AttributeValue(attr, firstNonEmpty));
                attributeValues.add(AttributeValues.create(
                    attr, firstNonEmpty));
              }
            }
          }
@@ -1671,7 +1664,8 @@
                  {
                    attributeTypes.add(attr);
                    attributeNames.add(attrName);
                    attributeValues.add(new AttributeValue(attr, (String)o));
                    attributeValues.add(
                        AttributeValues.create(attr, (String)o));
                  }
                  break;
                }
opends/src/guitools/org/opends/guitools/controlpanel/ui/TableViewEntryPanel.java
@@ -64,15 +64,7 @@
import org.opends.guitools.controlpanel.ui.renderer.LDAPEntryTableCellRenderer;
import org.opends.guitools.controlpanel.util.Utilities;
import org.opends.messages.Message;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.OpenDsException;
import org.opends.server.types.RDN;
import org.opends.server.types.Schema;
import org.opends.server.types.*;
import org.opends.server.util.LDIFReader;
import org.opends.server.util.ServerConstants;
@@ -314,7 +306,7 @@
          String attrName = rdn.getAttributeName(i);
          AttributeValue value = rdn.getAttributeValue(i);
          String sValue = value.getStringValue();
          String sValue = value.getValue().toString();
          Set<String> values = getDisplayedStringValues(attrName);
          if (!values.contains(sValue))
@@ -336,7 +328,8 @@
                AttributeType attr = rdn.getAttributeType(i);
                attributeTypes.add(attr);
                attributeNames.add(rdn.getAttributeName(i));
                attributeValues.add(new AttributeValue(attr, firstNonEmpty));
                attributeValues.add(AttributeValues.create(
                    attr, firstNonEmpty));
              }
            }
          }
@@ -375,7 +368,8 @@
                {
                  attributeTypes.add(attr);
                  attributeNames.add(attrName);
                  attributeValues.add(new AttributeValue(attr, (String)o));
                  attributeValues.add(AttributeValues.create(
                      attr, (String)o));
                }
                break;
              }
opends/src/guitools/org/opends/guitools/controlpanel/ui/nodes/BasicNode.java
@@ -389,7 +389,7 @@
          }
          else
          {
            result = rdn.getAttributeValue(0).getStringValue();
            result = rdn.getAttributeValue(0).getValue().toString();
          }
        }
        else {
opends/src/guitools/org/opends/guitools/controlpanel/util/Utilities.java
@@ -104,13 +104,7 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.LockFileManager;
import org.opends.server.schema.SchemaConstants;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DN;
import org.opends.server.types.OpenDsException;
import org.opends.server.types.RDN;
import org.opends.server.types.Schema;
import org.opends.server.types.SchemaFileElement;
import org.opends.server.types.*;
import org.opends.server.util.ServerConstants;
import org.opends.server.util.StaticUtils;
@@ -1255,7 +1249,8 @@
  public static String getRDNString(String attrName, String attrValue)
  {
    AttributeType attrType = DirectoryServer.getDefaultAttributeType(attrName);
    AttributeValue value = new AttributeValue(attrType, attrValue);
    AttributeValue value =
        AttributeValues.create(attrType, attrValue);
    RDN rdn = new RDN(attrType, attrName, value);
    return rdn.toString();
  }
opends/src/messages/messages/extension.properties
@@ -347,34 +347,6 @@
INFO_FILE_TRUSTMANAGER_UPDATED_PIN_109=The PIN to use to access the \
 file-based trust manager has been updated.  The new value will take effect \
 the next time the trust manager is accessed
SEVERE_ERR_NULL_SECURITY_PROVIDER_READ_ERROR_110=An unexpected error occurred \
 while attempting to read data from the client using the null connection \
 security provider:  %s
SEVERE_ERR_NULL_SECURITY_PROVIDER_WRITE_ERROR_111=An unexpected error \
 occurred while attempting to write data to the client using the null \
 connection security provider:  %s
SEVERE_ERR_TLS_SECURITY_PROVIDER_CANNOT_INITIALIZE_112=An error occurred \
 while attempting to initialize the SSL context for use in the TLS connection \
 security provider:  %s
SEVERE_ERR_TLS_SECURITY_PROVIDER_UNEXPECTED_UNWRAP_STATUS_113=An unexpected \
 status result was returned to the TLS connection security provider when \
 attempting to unwrap encrypted data read from the client:  %s
SEVERE_ERR_TLS_SECURITY_PROVIDER_READ_ERROR_114=An unexpected error occurred \
 while attempting to read data from the client using the TLS connection \
 security provider:  %s
SEVERE_ERR_TLS_SECURITY_PROVIDER_WRITE_NEEDS_UNWRAP_115=An attempt was made \
 to write data to a client through the TLS connection security provider, but \
 the SSL indicated that it was necessary to read data from the client in order \
 to perform the SSL negotiation, but no data was available for reading.  This \
 is an unexpected condition, and it is not possible to continue processing on \
 this client connection without the potential for blocking other client \
 connections, so connection will be closed
SEVERE_ERR_TLS_SECURITY_PROVIDER_UNEXPECTED_WRAP_STATUS_116=An unexpected \
 status result was returned to the TLS connection security provider when \
 attempting to wrap clear-text data for writing to the client:  %s
SEVERE_ERR_TLS_SECURITY_PROVIDER_WRITE_ERROR_117=An unexpected error occurred \
 while attempting to write data to the client using the TLS connection \
 security provider:  %s
MILD_ERR_SEDCM_NO_PEER_CERTIFICATE_118=Could not map the provided certificate \
 chain to a user entry because no peer certificate was available
MILD_ERR_SEDCM_PEER_CERT_NOT_X509_119=Could not map the provided certificate \
opends/src/messages/messages/jeb.properties
@@ -215,7 +215,7 @@
NOTICE_JEB_REFERRAL_RESULT_MESSAGE_112=A referral entry %s indicates that the \
 operation must be processed at a different server
INFO_JEB_IMPORT_ENVIRONMENT_CONFIG_119=Database environment properties: %s
SEVERE_ERR_JEB_INCOMPATIBLE_ENTRY_VERSION_126=Entry record with ID %s is not \
SEVERE_ERR_JEB_INCOMPATIBLE_ENTRY_VERSION_126=Entry record is not \
 compatible with this version of the backend database. Entry version: %x
NOTICE_JEB_LOOKTHROUGH_LIMIT_EXCEEDED_127=This search operation has checked the \
 maximum of %d entries for matches
opends/src/messages/messages/protocol.properties
@@ -47,118 +47,46 @@
#
# ORDINAL is an integer unique among other ordinals in this file
#
MILD_ERR_ASN1_NULL_ELEMENT_1=Cannot decode the provided byte array as an \
 ASN.1 element because the array was null
MILD_ERR_ASN1_SHORT_ELEMENT_2=Cannot decode the provided byte array as an \
 ASN.1 element because the length of the array (%d bytes) is less than the \
 minimum required for an ASN.1 element (2 bytes)
MILD_ERR_ASN1_INVALID_NUM_LENGTH_BYTES_3=Cannot decode the provided byte \
 array as an ASN.1 element because it contained a multi-byte length with an \
 invalid number of bytes (%d)
MILD_ERR_ASN1_TRUNCATED_LENGTH_4=Cannot decode the provided byte array as an \
 ASN.1 element because it contained a multi-byte length of %d bytes but the \
 array was too short to contain the entire length
MILD_ERR_ASN1_LENGTH_MISMATCH_5=Cannot decode the provided byte array as an \
 ASN.1 element because the decoded value length (%d bytes) does not equal the \
 number of bytes remaining in the provided array (%d)
MILD_ERR_ASN1_ELEMENT_SET_NULL_6=Cannot decode the provided byte array as a \
 set of ASN.1 elements because the array was null
MILD_ERR_ASN1_ELEMENT_SET_NO_LENGTH_7=Cannot decode the provided byte array \
 as a set of ASN.1 elements because the end of the array was reached after \
 having read the BER type but none of the value for an element
MILD_ERR_ASN1_ELEMENT_SET_INVALID_NUM_LENGTH_BYTES_8=Cannot decode the \
 provided byte array as a set of ASN.1 elements because it contained a \
 multi-byte length with an invalid number of bytes (%d)
MILD_ERR_ASN1_ELEMENT_SET_TRUNCATED_LENGTH_9=Cannot decode the provided byte \
 array as a set of ASN.1 elements because it contained a multi-byte length of \
 %d bytes but the array was too short to contain the entire length
MILD_ERR_ASN1_ELEMENT_SET_TRUNCATED_VALUE_10=Cannot decode the provided byte \
 array as a set of ASN.1 elements because the decoded length of an element \
 (%d) is more than the number of bytes remaining (%d)
MILD_ERR_ASN1_BOOLEAN_SET_VALUE_NULL_11=Cannot decode the provided byte array \
 as the value of an ASN.1 Boolean element because the array was null
MILD_ERR_ASN1_BOOLEAN_SET_VALUE_INVALID_LENGTH_12=Cannot decode the provided \
 byte array as the value of an ASN.1 Boolean element because the array did not \
 have a length of exactly one byte (provided length was %d)
MILD_ERR_ASN1_BOOLEAN_DECODE_ELEMENT_NULL_13=Cannot decode the provided ASN.1 \
 element as a Boolean element because the provided element was null
MILD_ERR_ASN1_BOOLEAN_DECODE_ELEMENT_INVALID_LENGTH_14=Cannot decode the \
 provided ASN.1 element as a Boolean element because the length of the element \
 value was not exactly one byte (actual length was %d)
MILD_ERR_ASN1_BOOLEAN_DECODE_ARRAY_NULL_15=Cannot decode the provided byte \
 array as an ASN.1 Boolean element because the array was null
MILD_ERR_ASN1_BOOLEAN_SHORT_ELEMENT_16=Cannot decode the provided byte array \
 as an ASN.1 Boolean element because the length of the array (%d bytes) is \
 less than the minimum required for a Boolean element (3 bytes)
MILD_ERR_ASN1_BOOLEAN_DECODE_ARRAY_INVALID_LENGTH_17=Cannot decode the \
 provided byte array as an ASN.1 Boolean element because the decoded value \
 length was not exactly one byte (decoded length was %d)
MILD_ERR_ASN1_NULL_SET_VALUE_INVALID_LENGTH_18=Cannot decode the provided \
 byte array as the value of an ASN.1 null element because the array did not \
 have a length of exactly zero byte (provided length was %d)
MILD_ERR_ASN1_NULL_DECODE_ELEMENT_NULL_19=Cannot decode the provided ASN.1 \
 element as a null element because the provided element was null
MILD_ERR_ASN1_NULL_DECODE_ELEMENT_INVALID_LENGTH_20=Cannot decode the \
 provided ASN.1 element as a null element because the length of the element \
 value was not exactly zero bytes (actual length was %d)
MILD_ERR_ASN1_NULL_DECODE_ARRAY_NULL_21=Cannot decode the provided byte array \
 as an ASN.1 null element because the array was null
MILD_ERR_ASN1_NULL_DECODE_ARRAY_INVALID_LENGTH_22=Cannot decode the provided \
 byte array as an ASN.1 null element because the decoded value length was not \
 exactly zero bytes (decoded length was %d)
MILD_ERR_ASN1_OCTET_STRING_DECODE_ELEMENT_NULL_23=Cannot decode the provided \
 ASN.1 element as an octet string element because the provided element was \
 null
MILD_ERR_ASN1_OCTET_STRING_DECODE_ARRAY_NULL_24=Cannot decode the provided \
 byte array as an ASN.1 octet string element because the array was null
MILD_ERR_ASN1_INTEGER_SET_VALUE_NULL_25=Cannot decode the provided byte array \
 as the value of an ASN.1 integer element because the array was null
MILD_ERR_ASN1_INTEGER_SET_VALUE_INVALID_LENGTH_26=Cannot decode the provided \
 byte array as the value of an ASN.1 integer element because the array did not \
 have a length between 1 and 4 bytes (provided length was %d)
MILD_ERR_ASN1_INTEGER_DECODE_ELEMENT_NULL_27=Cannot decode the provided ASN.1 \
 element as an integer element because the provided element was null
MILD_ERR_ASN1_INTEGER_DECODE_ELEMENT_INVALID_LENGTH_28=Cannot decode the \
 provided ASN.1 element as an integer element because the length of the \
MILD_ERR_ASN1_TRUCATED_TYPE_BYTE_1=Cannot decode the ASN.1 element because an \
 unexpected end of file was reached while reading the type byte
MILD_ERR_ASN1_TRUNCATED_LENGTH_BYTE_2=Cannot decode the ASN.1 element because \
 an unexpected end of file was reached while reading the first length byte
MILD_ERR_ASN1_INVALID_NUM_LENGTH_BYTES_3=Cannot decode the ASN.1 element \
 because it contained a multi-byte length with an invalid number of bytes (%d)
MILD_ERR_ASN1_TRUNCATED_LENGTH_BYTES_4=Cannot decode the ASN.1 element because \
 an unexpected end of file was reached while reading a multi-byte length of \
 %d bytes
MILD_ERR_ASN1_BOOLEAN_TRUNCATED_VALUE_5=Cannot decode the ASN.1 boolean \
 element of because an unexpected end of file was reached while reading value \
 bytes (%d)
MILD_ERR_ASN1_BOOLEAN_INVALID_LENGTH_6=Cannot decode the ASN.1 \
 boolean element because the decoded value length was not exactly one byte \
 (decoded length was %d)
MILD_ERR_ASN1_NULL_TRUNCATED_VALUE_7=Cannot decode the ASN.1 null \
 element of because an unexpected end of file was reached while reading value \
 bytes (%d)
MILD_ERR_ASN1_NULL_INVALID_LENGTH_8=Cannot decode the ASN.1 null element \
 because the decoded value length was not exactly zero bytes \
 (decoded length was %d)
MILD_ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE_9=Cannot decode the ASN.1 octet \
 string element of because an unexpected end of file was reached while reading \
 value bytes (%d)
MILD_ERR_ASN1_INTEGER_TRUNCATED_VALUE_10=Cannot decode the ASN.1 integer \
 element of because an unexpected end of file was reached while reading \
 value bytes (%d)
MILD_ERR_ASN1_INTEGER_INVALID_LENGTH_11=Cannot decode the \
 provided ASN.1 integer element because the length of the \
 element value was not between one and four bytes (actual length was %d)
MILD_ERR_ASN1_INTEGER_DECODE_ARRAY_NULL_29=Cannot decode the provided byte \
 array as an ASN.1 integer element because the array was null
MILD_ERR_ASN1_INTEGER_SHORT_ELEMENT_30=Cannot decode the provided byte array \
 as an ASN.1 integer element because the length of the array (%d bytes) is \
 less than the minimum required for an integer element (3 bytes)
MILD_ERR_ASN1_INTEGER_DECODE_ARRAY_INVALID_LENGTH_31=Cannot decode the \
 provided byte array as an ASN.1 integer element because the decoded value \
 length was not between 1 and 4 bytes (decoded length was %d)
MILD_ERR_ASN1_ENUMERATED_SET_VALUE_NULL_32=Cannot decode the provided byte \
 array as the value of an ASN.1 enumerated element because the array was null
MILD_ERR_ASN1_ENUMERATED_SET_VALUE_INVALID_LENGTH_33=Cannot decode the \
 provided byte array as the value of an ASN.1 enumerated element because the \
 array did not have a length between 1 and 4 bytes (provided length was %d)
MILD_ERR_ASN1_ENUMERATED_DECODE_ELEMENT_NULL_34=Cannot decode the provided \
 ASN.1 element as an enumerated element because the provided element was null
MILD_ERR_ASN1_ENUMERATED_DECODE_ELEMENT_INVALID_LENGTH_35=Cannot decode the \
 provided ASN.1 element as an enumerated element because the length of the \
 element value was not between one and four bytes (actual length was %d)
MILD_ERR_ASN1_ENUMERATED_DECODE_ARRAY_NULL_36=Cannot decode the provided byte \
 array as an ASN.1 enumerated element because the array was null
MILD_ERR_ASN1_ENUMERATED_SHORT_ELEMENT_37=Cannot decode the provided byte \
 array as an ASN.1 enumerated element because the length of the array (%d \
 bytes) is less than the minimum required for an enumerated element (3 bytes)
MILD_ERR_ASN1_ENUMERATED_DECODE_ARRAY_INVALID_LENGTH_38=Cannot decode the \
 provided byte array as an ASN.1 enumerated element because the decoded value \
 length was not between 1 and 4 bytes (decoded length was %d)
MILD_ERR_ASN1_SEQUENCE_SET_VALUE_NULL_39=Cannot decode the provided byte \
 array as the value of an ASN.1 sequence element because the array was null
MILD_ERR_ASN1_SEQUENCE_DECODE_ELEMENT_NULL_40=Cannot decode the provided \
 ASN.1 element as a sequence element because the provided element was null
MILD_ERR_ASN1_SEQUENCE_DECODE_ARRAY_NULL_41=Cannot decode the provided byte \
 array as an ASN.1 sequence element because the array was null
MILD_ERR_ASN1_SET_SET_VALUE_NULL_42=Cannot decode the provided byte array as \
 the value of an ASN.1 set element because the array was null
MILD_ERR_ASN1_SET_DECODE_ELEMENT_NULL_43=Cannot decode the provided ASN.1 \
 element as a set element because the provided element was null
MILD_ERR_ASN1_SET_DECODE_ARRAY_NULL_44=Cannot decode the provided byte array \
 as an ASN.1 set element because the array was null
MILD_ERR_ASN1_SEQUENCE_READ_NOT_STARTED_12=Cannot decode the end of the ASN.1 \
 sequence or set because the start of the sequence was not read
MILD_ERR_ASN1_SEQUENCE_READ_NOT_ENDED_13=Cannot decode the end of the ASN.1 \
 sequence or set because %d bytes are not read from the sequence of %d bytes \
 in length
MILD_ERR_ASN1_SKIP_TRUNCATED_VALUE_14=Cannot skip the ASN.1 element of because \
 an unexpected end of file was reached while reading value bytes (%d)
MILD_ERR_ASN1_SEQUENCE_SET_TRUNCATED_VALUE_15=Cannot decode the ASN.1 sequence \
 or set element of because an unexpected end of file was reached while reading \
 value bytes (%d)
MILD_ERR_LDAP_MESSAGE_DECODE_NULL_45=Cannot decode the provided ASN.1 \
 sequence as an LDAP message because the sequence was null
MILD_ERR_LDAP_MESSAGE_DECODE_INVALID_ELEMENT_COUNT_46=Cannot decode the \
@@ -1465,4 +1393,13 @@
 Please check the configuration attributes
SEVERE_ERR_SNMP_CONNHANDLER_NO_VALID_TRAP_DESTINATIONS_1466=No valid trap \
 destinations has been found. No trap will be sent
SEVERE_ERR_ASN1_READ_ERROR_1500=An error occured while accessing the \
 underlying data source: %s
SEVERE_ERR_ASN1_EOF_ERROR_1501=An unexpected end of file reached while trying \
 to read %d bytes from the underlying data source
SEVERE_ERR_ASN1_INVALID_STATE_1502=Invalid reader state: %d
SEVERE_ERR_SUBTREE_DELETE_INVALID_CONTROL_VALUE_1503=Cannot decode the provided \
 subtree delete control because it contains a value
 SEVERE_ERR_CONNHANDLER_SSL_CANNOT_INITIALIZE_1504=An error occurred \
 while attempting to initialize the SSL context for use in the LDAP \
 Connection Handler:  %s
opends/src/messages/src/org/opends/messages/MessageBuilder.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2007-2008 Sun Microsystems, Inc.
 *      Copyright 2007-2009 Sun Microsystems, Inc.
 */
package org.opends.messages;
@@ -270,19 +270,20 @@
   * @return Message raw message representing builder content
   */
  public Message toMessage() {
    if(messages.isEmpty())
    {
      return Message.EMPTY;
    }
    StringBuffer fmtString = new StringBuffer();
    for (int i = 0; i < messages.size(); i++) {
      fmtString.append("%s");
    }
    if (messages.isEmpty()) {
      return Message.raw(fmtString, messages.toArray());
    } else {
      // Inherit the category and severity of the first message.
      MessageDescriptor md = messages.get(0).getDescriptor();
      return Message.raw(md.getCategory(), md.getSeverity(), fmtString,
          messages.toArray());
    }
    // Inherit the category and severity of the first message.
    MessageDescriptor md = messages.get(0).getDescriptor();
    return Message.raw(md.getCategory(), md.getSeverity(), fmtString,
        messages.toArray());
  }
  /**
opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.installer.ui;
@@ -129,6 +129,7 @@
    addWindowListener(new WindowAdapter()
    {
      @Override
      public void windowClosing(WindowEvent e)
      {
        cancelClicked();
@@ -664,6 +665,7 @@
  {
    BackgroundTask worker = new BackgroundTask()
    {
      @Override
      public Object processBackgroundTask()
      {
        ArrayList<Message> errorMsgs = new ArrayList<Message>();
@@ -675,6 +677,7 @@
        return errorMsgs;
      }
      @Override
      public void backgroundTaskCompleted(Object returnValue,
          Throwable throwable)
      {
opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.ui;
@@ -142,6 +142,7 @@
    addWindowListener(new WindowAdapter()
    {
      @Override
      public void windowClosing(WindowEvent e)
      {
        doNotAccept();
opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.ui;
@@ -1287,6 +1287,7 @@
      col.setHeaderRenderer(headerRenderer);
    }
    MouseAdapter listMouseListener = new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent e) {
        TableColumnModel columnModel = table.getColumnModel();
        int viewColumn = columnModel.getColumnIndexAtX(e.getX());
@@ -1754,6 +1755,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    setText((String)value);
@@ -1818,6 +1820,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void setText(String text)
  {
    // Scroll can be null in constructor
@@ -1841,6 +1844,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void scrollRectToVisible(Rectangle rect)
  {
    if (!ignoreScrollToVisible)
opends/src/quicksetup/org/opends/quicksetup/util/InProcessServerController.java
@@ -42,7 +42,6 @@
import org.opends.server.loggers.AccessLogger;
import org.opends.server.types.Modification;
import org.opends.server.types.ResultCode;
import org.opends.server.types.ByteStringFactory;
import org.opends.server.types.ByteString;
import org.opends.server.types.InitializationException;
import org.opends.server.types.Attribute;
@@ -60,7 +59,6 @@
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPAttribute;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.AddOperation;
@@ -411,7 +409,7 @@
    InternalClientConnection cc =
            InternalClientConnection.getRootConnection();
    ByteString dnByteString =
            ByteStringFactory.create(
        ByteString.valueOf(
                    cre.getDN().toString());
    ResultCode rc;
    switch (cre.getChangeOperationType()) {
@@ -467,8 +465,8 @@
          // can ignore this add.
          boolean ignore = true;
          for (RawAttribute attr : rawAttrs) {
            ArrayList<ASN1OctetString> values = attr.getValues();
            for (ASN1OctetString value : values) {
            ArrayList<ByteString> values = attr.getValues();
            for (ByteString value : values) {
              CompareOperation compOp =
                cc.processCompare(dnByteString, attr.getAttributeType(), value);
              if (ResultCode.ASSERTION_FAILED.equals(compOp.getResultCode())) {
opends/src/server/org/opends/server/admin/ACIPropertyDefinition.java
@@ -30,8 +30,8 @@
import org.opends.server.authorization.dseecompat.Aci;
import org.opends.server.authorization.dseecompat.AciException;
import org.opends.server.types.DN;
import org.opends.server.types.ByteString;
import static org.opends.server.util.Validator.ensureNotNull;
import org.opends.server.protocols.asn1.ASN1OctetString;
import java.util.EnumSet;
@@ -116,7 +116,7 @@
    ensureNotNull(value);
    try {
      return Aci.decode(new ASN1OctetString(value), DN.NULL_DN);
      return Aci.decode(ByteString.valueOf(value), DN.NULL_DN);
    } catch (AciException e) {
      // TODO: it would be nice to throw the cause.
      throw new IllegalPropertyValueStringException(this, value);
opends/src/server/org/opends/server/admin/AdministrationConnector.java
@@ -73,11 +73,12 @@
/**
 * This class is a wrapper on top of LDAPConnectionHandler to manage
 * the administration connector, which is an LDAPConnectionHandler with specific
 * (limited) configuration properties.
 * the administration connector, which is an LDAPConnectionHandler
 * with specific (limited) configuration properties.
 */
public final class AdministrationConnector
  implements ConfigurationChangeListener<AdministrationConnectorCfg> {
public final class AdministrationConnector implements
    ConfigurationChangeListener<AdministrationConnectorCfg>
{
  /**
   * Default Administration Connector port.
@@ -89,44 +90,68 @@
   */
  public static final int ADMIN_CERT_VALIDITY = 2 * 365;
 // Friendly name of the administration connector
  // Friendly name of the administration connector
  private static final String FRIENDLY_NAME = "Administration Connector";
  // The tracer object for the debug logger.
  private static final DebugTracer TRACER = getTracer();
  private LDAPConnectionHandler adminConnectionHandler;
  private AdministrationConnectorCfg config;  //
  private AdministrationConnectorCfg config; //
  // Predefined values for Administration Connector configuration
  //
  private static final String ADMIN_CLASS_NAME =
    "org.opends.server.protocols.ldap.LDAPConnectionHandler";
  private static final boolean ADMIN_ALLOW_LDAP_V2 = true;
  private static final boolean ADMIN_ALLOW_START_TLS = false;
  private static final SortedSet<AddressMask> ADMIN_ALLOWED_CLIENT =
    new TreeSet<AddressMask>();
  private static final SortedSet<AddressMask> ADMIN_DENIED_CLIENT =
    new TreeSet<AddressMask>();
  private static final boolean ADMIN_ENABLED = true;
  private static final boolean ADMIN_KEEP_STATS = true;
  private static final boolean ADMIN_USE_SSL = true;
  private static final int ADMIN_ACCEPT_BACKLOG = 128;
  private static final boolean ADMIN_ALLOW_TCP_REUSE_ADDRESS = true;
  private static final long ADMIN_MAX_BLOCKED_WRITE_TIME_LIMIT = 120000; // 2mn
  private static final int ADMIN_MAX_REQUEST_SIZE = 5000000; // 5 Mb
  private static final int ADMIN_NUM_REQUEST_HANDLERS = 1;
  private static final boolean ADMIN_SEND_REJECTION_NOTICE = true;
  private static final boolean ADMIN_USE_TCP_KEEP_ALIVE = true;
  private static final boolean ADMIN_USE_TCP_NO_DELAY = true;
  private static final SSLClientAuthPolicy ADMIN_SSL_CLIENT_AUTH_POLICY =
    SSLClientAuthPolicy.DISABLED;
  private static final SortedSet<String> ADMIN_SSL_CIPHER_SUITE =
    new TreeSet<String>();
  private static final SortedSet<String> ADMIN_SSL_PROTOCOL =
    new TreeSet<String>();
  /**
   * Initializes this administration connector provider based on the
   * information in the provided administration connector configuration.
   * information in the provided administration connector
   * configuration.
   *
   * @param configuration
   *          The connection handler configuration that contains the
@@ -141,8 +166,9 @@
   *           related to the server configuration.
   */
  public void initializeAdministrationConnector(
    AdministrationConnectorCfg configuration)
    throws ConfigException, InitializationException {
      AdministrationConnectorCfg configuration) throws ConfigException,
      InitializationException
  {
    this.config = configuration;
@@ -152,364 +178,495 @@
    createSelfSignedCertifIfNeeded();
    // Administration Connector uses the LDAP connection handler implementation
    adminConnectionHandler =
      new LDAPConnectionHandler(new SynchronousStrategy(), FRIENDLY_NAME);
    adminConnectionHandler.
      initializeConnectionHandler(ldapConnectionHandlerCfg);
    // Administration Connector uses the LDAP connection handler
    // implementation
    adminConnectionHandler = new LDAPConnectionHandler(
        new SynchronousStrategy(), FRIENDLY_NAME);
    adminConnectionHandler
        .initializeConnectionHandler(ldapConnectionHandlerCfg);
    adminConnectionHandler.setAdminConnectionHandler();
    // Register this as a change listener.
    config.addChangeListener(this);
  }
  /**
   * Create an instance of the administration connector.
   */
  public AdministrationConnector() {
  public AdministrationConnector()
  {
    // Do nothing.
  }
  /**
   * Retrieves the connection handler linked to this administration connector.
   * Retrieves the connection handler linked to this administration
   * connector.
   *
   * @return The connection handler linked to this administration connector.
   * @return The connection handler linked to this administration
   *         connector.
   */
  public LDAPConnectionHandler getConnectionHandler() {
  public LDAPConnectionHandler getConnectionHandler()
  {
    return adminConnectionHandler;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isConfigurationChangeAcceptable(
    AdministrationConnectorCfg configuration,
    List<Message> unacceptableReasons) {
    LDAPConnectionHandlerCfg cfg =
      new FakeLDAPConnectionHandlerCfg(configuration);
    return adminConnectionHandler.isConfigurationAcceptable(
      cfg, unacceptableReasons);
      AdministrationConnectorCfg configuration,
      List<Message> unacceptableReasons)
  {
    LDAPConnectionHandlerCfg cfg = new FakeLDAPConnectionHandlerCfg(
        configuration);
    return adminConnectionHandler.isConfigurationAcceptable(cfg,
        unacceptableReasons);
  }
  /**
   * {@inheritDoc}
   */
  public ConfigChangeResult applyConfigurationChange(
    AdministrationConnectorCfg configuration) {
    return new ConfigChangeResult(
      ResultCode.SUCCESS, true, new ArrayList<Message>());
      AdministrationConnectorCfg configuration)
  {
    return new ConfigChangeResult(ResultCode.SUCCESS, true,
        new ArrayList<Message>());
  }
  /**
   * This private class implements a fake LDAP connection Handler configuration.
   * This allows to re-use the LDAPConnectionHandler as it is.
   *
   * This private class implements a fake LDAP connection Handler
   * configuration. This allows to re-use the LDAPConnectionHandler as
   * it is.
   */
  private static class FakeLDAPConnectionHandlerCfg
    implements LDAPConnectionHandlerCfg {
  private static class FakeLDAPConnectionHandlerCfg implements
      LDAPConnectionHandlerCfg
  {
    private final AdministrationConnectorCfg config;
    public FakeLDAPConnectionHandlerCfg(AdministrationConnectorCfg config) {
    public FakeLDAPConnectionHandlerCfg(AdministrationConnectorCfg config)
    {
      this.config = config;
    }
    /**
     * {@inheritDoc}
     */
    public Class<? extends LDAPConnectionHandlerCfg> configurationClass() {
    public Class<? extends LDAPConnectionHandlerCfg> configurationClass()
    {
      return LDAPConnectionHandlerCfg.class;
    }
    /**
     * {@inheritDoc}
     */
    public void addLDAPChangeListener(
      ConfigurationChangeListener<LDAPConnectionHandlerCfg> listener) {
        ConfigurationChangeListener<LDAPConnectionHandlerCfg> listener)
    {
      // do nothing. change listener already added.
    }
    /**
     * {@inheritDoc}
     */
    public void removeLDAPChangeListener(
      ConfigurationChangeListener<LDAPConnectionHandlerCfg> listener) {
        ConfigurationChangeListener<LDAPConnectionHandlerCfg> listener)
    {
      // do nothing. change listener already added.
    }
    /**
     * {@inheritDoc}
     */
    public int getAcceptBacklog() {
    public int getAcceptBacklog()
    {
      return ADMIN_ACCEPT_BACKLOG;
    }
    /**
     * {@inheritDoc}
     */
    public boolean isAllowLDAPV2() {
    public boolean isAllowLDAPV2()
    {
      return ADMIN_ALLOW_LDAP_V2;
    }
    /**
     * {@inheritDoc}
     */
    public boolean isAllowStartTLS() {
    public boolean isAllowStartTLS()
    {
      return ADMIN_ALLOW_START_TLS;
    }
    /**
     * {@inheritDoc}
     */
    public boolean isAllowTCPReuseAddress() {
    public boolean isAllowTCPReuseAddress()
    {
      return ADMIN_ALLOW_TCP_REUSE_ADDRESS;
    }
    /**
     * {@inheritDoc}
     */
    public String getJavaClass() {
    public String getJavaClass()
    {
      return ADMIN_CLASS_NAME;
    }
    /**
     * {@inheritDoc}
     */
    public boolean isKeepStats() {
    public boolean isKeepStats()
    {
      return ADMIN_KEEP_STATS;
    }
    /**
     * {@inheritDoc}
     */
    public String getKeyManagerProvider() {
    public String getKeyManagerProvider()
    {
      return config.getKeyManagerProvider();
    }
    /**
     * {@inheritDoc}
     */
    public DN getKeyManagerProviderDN() {
    public DN getKeyManagerProviderDN()
    {
      return config.getKeyManagerProviderDN();
    }
    /**
     * {@inheritDoc}
     */
    public SortedSet<InetAddress> getListenAddress() {
    public SortedSet<InetAddress> getListenAddress()
    {
      return config.getListenAddress();
    }
    /**
     * {@inheritDoc}
     */
    public int getListenPort() {
    public int getListenPort()
    {
      return config.getListenPort();
    }
    /**
     * {@inheritDoc}
     */
    public long getMaxBlockedWriteTimeLimit() {
    public long getMaxBlockedWriteTimeLimit()
    {
      return ADMIN_MAX_BLOCKED_WRITE_TIME_LIMIT;
    }
    /**
     * {@inheritDoc}
     */
    public long getMaxRequestSize() {
    public long getMaxRequestSize()
    {
      return ADMIN_MAX_REQUEST_SIZE;
    }
    /**
     * {@inheritDoc}
     */
    public int getNumRequestHandlers() {
    public int getNumRequestHandlers()
    {
      return ADMIN_NUM_REQUEST_HANDLERS;
    }
    /**
     * {@inheritDoc}
     */
    public boolean isSendRejectionNotice() {
    public boolean isSendRejectionNotice()
    {
      return ADMIN_SEND_REJECTION_NOTICE;
    }
    /**
     * {@inheritDoc}
     */
    public String getSSLCertNickname() {
    public String getSSLCertNickname()
    {
      return config.getSSLCertNickname();
    }
    /**
     * {@inheritDoc}
     */
    public SortedSet<String> getSSLCipherSuite() {
    public SortedSet<String> getSSLCipherSuite()
    {
      return ADMIN_SSL_CIPHER_SUITE;
    }
    /**
     * {@inheritDoc}
     */
    public SSLClientAuthPolicy getSSLClientAuthPolicy() {
    public SSLClientAuthPolicy getSSLClientAuthPolicy()
    {
      return ADMIN_SSL_CLIENT_AUTH_POLICY;
    }
    /**
     * {@inheritDoc}
     */
    public SortedSet<String> getSSLProtocol() {
    public SortedSet<String> getSSLProtocol()
    {
      return ADMIN_SSL_PROTOCOL;
    }
    /**
     * {@inheritDoc}
     */
    public String getTrustManagerProvider() {
    public String getTrustManagerProvider()
    {
      return config.getTrustManagerProvider();
    }
    /**
     * {@inheritDoc}
     */
    public DN getTrustManagerProviderDN() {
    public DN getTrustManagerProviderDN()
    {
      return config.getTrustManagerProviderDN();
    }
    /**
     * {@inheritDoc}
     */
    public boolean isUseSSL() {
    public boolean isUseSSL()
    {
      return ADMIN_USE_SSL;
    }
    /**
     * {@inheritDoc}
     */
    public boolean isUseTCPKeepAlive() {
      return ADMIN_USE_TCP_KEEP_ALIVE;
    }
    /**
     * {@inheritDoc}
     */
    public boolean isUseTCPNoDelay() {
    public boolean isUseTCPKeepAlive()
    {
      return ADMIN_USE_TCP_KEEP_ALIVE;
    }
    /**
     * {@inheritDoc}
     */
    public boolean isUseTCPNoDelay()
    {
      return ADMIN_USE_TCP_NO_DELAY;
    }
    /**
     * {@inheritDoc}
     */
    public void addChangeListener(
      ConfigurationChangeListener<ConnectionHandlerCfg> listener) {
        ConfigurationChangeListener<ConnectionHandlerCfg> listener)
    {
      // do nothing. change listener already added.
    }
    /**
     * {@inheritDoc}
     */
    public void removeChangeListener(
      ConfigurationChangeListener<ConnectionHandlerCfg> listener) {
        ConfigurationChangeListener<ConnectionHandlerCfg> listener)
    {
      // do nothing. change listener already added.
    }
    /**
     * {@inheritDoc}
     */
    public SortedSet<AddressMask> getAllowedClient() {
    public SortedSet<AddressMask> getAllowedClient()
    {
      return ADMIN_ALLOWED_CLIENT;
    }
    /**
     * {@inheritDoc}
     */
    public SortedSet<AddressMask> getDeniedClient() {
    public SortedSet<AddressMask> getDeniedClient()
    {
      return ADMIN_DENIED_CLIENT;
    }
    /**
     * {@inheritDoc}
     */
    public boolean isEnabled() {
      return ADMIN_ENABLED;
    }
    /**
     * {@inheritDoc}
     */
    public DN dn() {
    public boolean isEnabled()
    {
      return ADMIN_ENABLED;
    }
    /**
     * {@inheritDoc}
     */
    public DN dn()
    {
      return config.dn();
    }
  }
  /**
   * Creates a self-signed JKS certificate if needed.
   */
  private void createSelfSignedCertifIfNeeded()
    throws InitializationException {
  private void createSelfSignedCertifIfNeeded() throws InitializationException
  {
    try {
    try
    {
      // Check if certificate generation is needed
      String certAlias = config.getSSLCertNickname();
      KeyManagerProviderCfg keyMgrConfig =
        getAdminConnectorKeyManagerConfig(config.getKeyManagerProvider());
      TrustManagerProviderCfg trustMgrConfig =
        getAdminConnectorTrustManagerConfig(config.getTrustManagerProvider());
      if (!(keyMgrConfig instanceof FileBasedKeyManagerProviderCfg) ||
        !(trustMgrConfig instanceof FileBasedTrustManagerProviderCfg)) {
      if (!(keyMgrConfig instanceof FileBasedKeyManagerProviderCfg)
          || !(trustMgrConfig instanceof FileBasedTrustManagerProviderCfg))
      {
        // The default config has been changed, nothing to do
        return;
      }
      FileBasedKeyManagerProviderCfg fbKeyManagerConfig =
        (FileBasedKeyManagerProviderCfg) keyMgrConfig;
      String keystorePath =
        getFullPath(fbKeyManagerConfig.getKeyStoreFile());
      String keystorePath = getFullPath(fbKeyManagerConfig.getKeyStoreFile());
      FileBasedTrustManagerProviderCfg fbTrustManagerConfig =
        (FileBasedTrustManagerProviderCfg) trustMgrConfig;
      String truststorePath =
        getFullPath(fbTrustManagerConfig.getTrustStoreFile());
      String truststorePath = getFullPath(fbTrustManagerConfig
          .getTrustStoreFile());
      String pinFilePath = getFullPath(fbKeyManagerConfig.getKeyStorePinFile());
      // Check that either we do not have any file,
      // or we have the 3 required files (keystore, truststore, pin file)
      // or we have the 3 required files (keystore, truststore, pin
      // file)
      boolean keystore = false;
      boolean truststore = false;
      boolean pinFile = false;
      int nbFiles = 0;
      if (new File(keystorePath).exists()) {
      if (new File(keystorePath).exists())
      {
        keystore = true;
        nbFiles++;
      }
      if (new File(truststorePath).exists()) {
      if (new File(truststorePath).exists())
      {
        truststore = true;
        nbFiles++;
      }
      if (new File(pinFilePath).exists()) {
      if (new File(pinFilePath).exists())
      {
        pinFile = true;
        nbFiles++;
      }
      if (nbFiles == 3) {
      if (nbFiles == 3)
      {
        // nothing to do
        return;
      }
      if (nbFiles != 0) {
      if (nbFiles != 0)
      {
        // 1 or 2 files are missing : error
        String err = "";
        if (!keystore) {
        if (!keystore)
        {
          err += keystorePath + " ";
        }
        if (!truststore) {
        if (!truststore)
        {
          err += truststorePath + " ";
        }
        if (!pinFile) {
        if (!pinFile)
        {
          err += pinFilePath + " ";
        }
        Message message =
          ERR_ADMIN_CERTIFICATE_GENERATION_MISSING_FILES.get(err);
        Message message = ERR_ADMIN_CERTIFICATE_GENERATION_MISSING_FILES
            .get(err);
        logError(message);
        throw new InitializationException(message);
      }
@@ -519,30 +676,28 @@
      // Generate a self-signed certificate
      CertificateManager certManager = new CertificateManager(
        getFullPath(fbKeyManagerConfig.getKeyStoreFile()),
        fbKeyManagerConfig.getKeyStoreType(),
        pwd);
      String subjectDN = "cn=" +
        Rdn.escapeValue(InetAddress.getLocalHost().getHostName()) +
        ",O=" + FRIENDLY_NAME + " Self-Signed Certificate";
      certManager.generateSelfSignedCertificate(
        certAlias, subjectDN, ADMIN_CERT_VALIDITY);
          getFullPath(fbKeyManagerConfig.getKeyStoreFile()), fbKeyManagerConfig
              .getKeyStoreType(), pwd);
      String subjectDN = "cn="
          + Rdn.escapeValue(InetAddress.getLocalHost().getHostName()) + ",O="
          + FRIENDLY_NAME + " Self-Signed Certificate";
      certManager.generateSelfSignedCertificate(certAlias, subjectDN,
          ADMIN_CERT_VALIDITY);
      // Export the certificate
      String tempCertPath = getFullPath("config" + File.separator +
        "admin-cert.txt");
      SetupUtils.exportCertificate(certManager, certAlias,
        tempCertPath);
      String tempCertPath = getFullPath("config" + File.separator
          + "admin-cert.txt");
      SetupUtils.exportCertificate(certManager, certAlias, tempCertPath);
      // Create a new trust store and import the server certificate into it
      CertificateManager trustManager = new CertificateManager(
        truststorePath,
        CertificateManager.KEY_STORE_TYPE_JKS,
        pwd);
      // Create a new trust store and import the server certificate
      // into it
      CertificateManager trustManager = new CertificateManager(truststorePath,
          CertificateManager.KEY_STORE_TYPE_JKS, pwd);
      trustManager.addCertificate(certAlias, new File(tempCertPath));
      // Generate a password file
      if (!new File(pinFilePath).exists()) {
      if (!new File(pinFilePath).exists())
      {
        FileWriter file = new FileWriter(pinFilePath);
        PrintWriter out = new PrintWriter(file);
        out.println(pwd);
@@ -552,16 +707,21 @@
      }
      // Change the password file permission if possible
      if (FilePermission.canSetPermissions()) {
        try {
      if (FilePermission.canSetPermissions())
      {
        try
        {
          if (!FilePermission.setPermissions(new File(pinFilePath),
            new FilePermission(0600))) {
              new FilePermission(0600)))
          {
            // Log a warning that the permissions were not set.
            Message message =
              WARN_ADMIN_SET_PERMISSIONS_FAILED.get(pinFilePath);
            Message message = WARN_ADMIN_SET_PERMISSIONS_FAILED
                .get(pinFilePath);
            ErrorLogger.logError(message);
          }
        } catch (DirectoryException e) {
        }
        catch (DirectoryException e)
        {
          // Log a warning that the permissions were not set.
          Message message = WARN_ADMIN_SET_PERMISSIONS_FAILED.get(pinFilePath);
          ErrorLogger.logError(message);
@@ -571,21 +731,32 @@
      // Delete the exported certificate
      File f = new File(tempCertPath);
      f.delete();
    } catch (ConfigException e) {
    }
    catch (ConfigException e)
    {
      handleCertifExceptions(e);
    } catch (KeyStoreException e) {
    }
    catch (KeyStoreException e)
    {
      handleCertifExceptions(e);
    } catch (IOException e) {
    }
    catch (IOException e)
    {
      handleCertifExceptions(e);
    } catch (CertificateEncodingException e) {
    }
    catch (CertificateEncodingException e)
    {
      handleCertifExceptions(e);
    }
  }
  private void handleCertifExceptions(Exception e) throws
    InitializationException {
    if (debugEnabled()) {
  private void handleCertifExceptions(Exception e)
      throws InitializationException
  {
    if (debugEnabled())
    {
      TRACER.debugCaught(DebugLogLevel.ERROR, e);
    }
    Message message = ERR_ADMIN_CERTIFICATE_GENERATION.get(e.getMessage());
@@ -593,23 +764,31 @@
    throw new InitializationException(message);
  }
  private KeyManagerProviderCfg getAdminConnectorKeyManagerConfig(String name)
    throws ConfigException {
      throws ConfigException
  {
    RootCfg root = ServerManagementContext.getInstance().getRootConfiguration();
    return root.getKeyManagerProvider(name);
  }
  private TrustManagerProviderCfg getAdminConnectorTrustManagerConfig(
    String name)
    throws ConfigException {
    RootCfg root =
      ServerManagementContext.getInstance().getRootConfiguration();
      String name) throws ConfigException
  {
    RootCfg root = ServerManagementContext.getInstance().getRootConfiguration();
    return root.getTrustManagerProvider(name);
  }
  private static String getFullPath(String path) {
  private static String getFullPath(String path)
  {
    File file = new File(path);
    if (!file.isAbsolute()) {
    if (!file.isAbsolute())
    {
      path = DirectoryServer.getInstanceRoot() + File.separator + path;
    }
opends/src/server/org/opends/server/admin/AdministrationDataSync.java
@@ -27,12 +27,12 @@
package org.opends.server.admin;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPFilter;
@@ -40,6 +40,7 @@
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.Attributes;
import org.opends.server.types.ByteString;
import org.opends.server.types.DN;
import org.opends.server.types.DereferencePolicy;
import org.opends.server.types.DirectoryException;
@@ -52,10 +53,11 @@
import org.opends.server.types.SearchScope;
/**
 * Check if information found in "cn=admin data" is coherent with
 * cn=config. If and inconsistancy is detected, we log a warning message
 * and update "cn=admin data"
 * cn=config. If and inconsistency is detected, we log a warning
 * message and update "cn=admin data"
 */
public final class AdministrationDataSync
{
@@ -66,25 +68,31 @@
  private InternalClientConnection internalConnection;
  /**
   * The attribute name used to store the port.
   * TODO Use the default one.
   * The attribute name used to store the port. TODO Use the default
   * one.
   */
  private static final String LDAP_PORT = "ds-cfg-listen-port";
  /**
   * Create an object that will syncrhonize configuration and the admin data.
   * Create an object that will syncrhonize configuration and the
   * admin data.
   *
   * @param internalConnection The root connection.
   * @param internalConnection
   *          The root connection.
   */
  public AdministrationDataSync(InternalClientConnection internalConnection)
  {
    this.internalConnection = internalConnection ;
    this.internalConnection = internalConnection;
  }
  /**
   * Check if information found in "cn=admin data" is coherent with
   * cn=config. If and inconsistancy is detected, we log a warning message
   * and update "cn=admin data"
   * cn=config. If and inconsistancy is detected, we log a warning
   * message and update "cn=admin data"
   */
  public void synchronize()
  {
@@ -92,9 +100,11 @@
    checkAdminConnector();
  }
  /**
   * Check if the admin connector is in sync. The desynchronization could
   * occurs after the upgrade from 1.0.
   * Check if the admin connector is in sync. The desynchronization
   * could occurs after the upgrade from 1.0.
   */
  private void checkAdminConnector()
  {
@@ -107,25 +117,25 @@
    }
    // Get the admin port
    String adminPort =
      getAttr("cn=Administration Connector,cn=config", LDAP_PORT);
    String adminPort = getAttr("cn=Administration Connector,cn=config",
        LDAP_PORT);
    if (adminPort == null)
    {
      // best effort.
      return ;
      return;
    }
    LinkedList<Modification> mods = new LinkedList<Modification>();
    // adminport
    String attName = "adminport";
    AttributeType attrType =
    DirectoryServer.getAttributeType(attName.toLowerCase());
    AttributeType attrType = DirectoryServer.getAttributeType(attName
        .toLowerCase());
    if (attrType == null)
    {
      attrType = DirectoryServer.getDefaultAttributeType(attName.toLowerCase());
    }
    mods.add(new Modification(ModificationType.REPLACE, Attributes
        .create(attrType, adminPort)));
    mods.add(new Modification(ModificationType.REPLACE, Attributes.create(
        attrType, adminPort)));
    // adminEnabled
    attName = "adminEnabled";
@@ -134,16 +144,18 @@
    {
      attrType = DirectoryServer.getDefaultAttributeType(attName.toLowerCase());
    }
    mods.add(new Modification(ModificationType.REPLACE, Attributes
        .create(attrType, "true")));
    mods.add(new Modification(ModificationType.REPLACE, Attributes.create(
        attrType, "true")));
    // Process modification
    internalConnection.processModify(serverEntryDN,mods);
    internalConnection.processModify(serverEntryDN, mods);
  }
  /**
   * Look for the DN of the local register server.
   * Assumption: default Connection Handler naming is used.
   * Look for the DN of the local register server. Assumption: default
   * Connection Handler naming is used.
   *
   * @return The DN of the local register server or null.
   */
@@ -152,16 +164,16 @@
    DN returnDN = null;
    // Get the LDAP and LDAPS port
    String ldapPort =
      getAttr("cn=LDAP Connection Handler,cn=Connection Handlers,cn=config",
          LDAP_PORT);
    String ldapsPort =
      getAttr("cn=LDAPS Connection Handler,cn=Connection Handlers,cn=config",
          LDAP_PORT);
    String ldapPort = getAttr(
        "cn=LDAP Connection Handler,cn=Connection Handlers,cn=config",
        LDAP_PORT);
    String ldapsPort = getAttr(
        "cn=LDAPS Connection Handler,cn=Connection Handlers,cn=config",
        LDAP_PORT);
    boolean ldapsPortEnable = false;
    String val =
      getAttr("cn=LDAPS Connection Handler,cn=Connection Handlers,cn=config",
          "ds-cfg-enabled");
    String val = getAttr(
        "cn=LDAPS Connection Handler,cn=Connection Handlers,cn=config",
        "ds-cfg-enabled");
    if (val != null)
    {
      ldapsPortEnable = val.toLowerCase().equals("true");
@@ -169,7 +181,7 @@
    if ((ldapPort == null) && (ldapsPort == null))
    {
      // best effort (see assumption)
      return null ;
      return null;
    }
    // Get the IP address of the local host.
@@ -180,7 +192,7 @@
    }
    catch (Throwable t)
    {
     // best effort.
      // best effort.
      return null;
    }
@@ -198,7 +210,7 @@
          SearchScope.SINGLE_LEVEL, "objectclass=*");
      if (op.getResultCode() == ResultCode.SUCCESS)
      {
        Entry entry =  null;
        Entry entry = null;
        for (Entry currentEntry : op.getSearchEntries())
        {
          String currentHostname = currentEntry.getAttributeValue(hostnameType,
@@ -211,8 +223,8 @@
            {
              // Check if one of the port match
              attrName = "ldapport";
              AttributeType portType =
                DirectoryServer.getAttributeType(attrName);
              AttributeType portType = DirectoryServer
                  .getAttributeType(attrName);
              if (portType == null)
              {
                portType = DirectoryServer.getDefaultAttributeType(attrName);
@@ -221,8 +233,8 @@
                  DirectoryStringSyntax.DECODER);
              if (currentport.equals(ldapPort))
              {
                entry = currentEntry ;
                break ;
                entry = currentEntry;
                break;
              }
              if (ldapsPortEnable)
              {
@@ -242,7 +254,7 @@
              }
            }
          }
          catch(Exception e)
          catch (Exception e)
          {
            // best effort.
            continue;
@@ -255,7 +267,8 @@
        }
      }
    } catch (DirectoryException e)
    }
    catch (DirectoryException e)
    {
      // never happens because the filter is always valid.
      return null;
@@ -263,17 +276,21 @@
    return returnDN;
  }
  /**
   * get an attribute from and entry.
   * @param DN the DN of the entry.
   * @param attrName the attribute name.
   * @return The Administration connector port.
   * Gets an attribute value from an entry.
   *
   * @param DN
   *          The DN of the entry.
   * @param attrName
   *          The attribute name.
   * @return The attribute value or {@code null} if the value could
   *         not be retrieved.
   */
  private String getAttr(String baseDN, String attrName)
  {
    String value = null  ;
    //
    // prepare the ldap search
    // Prepare the ldap search
    LDAPFilter filter;
    try
    {
@@ -287,14 +304,11 @@
      return null;
    }
    ASN1OctetString asn1BaseDn = new ASN1OctetString(baseDN);
    LinkedHashSet<String> attributes = new LinkedHashSet<String>(1);
    attributes.add(attrName);
    InternalSearchOperation search = internalConnection.processSearch(
        asn1BaseDn,
        SearchScope.BASE_OBJECT,
        DereferencePolicy.DEREF_ALWAYS, 0, 0, false,
        filter,attributes);
        ByteString.valueOf(baseDN), SearchScope.BASE_OBJECT,
        DereferencePolicy.DEREF_ALWAYS, 0, 0, false, filter, attributes);
    if ((search.getResultCode() != ResultCode.SUCCESS))
    {
@@ -305,6 +319,7 @@
    }
    SearchResultEntry adminConnectorEntry = null;
    /*
     * Read the port from the PORT attribute
     */
@@ -331,8 +346,7 @@
    }
    // Get the attribute value
    value = attrs.get(0).iterator().next().getStringValue();
    return value;
    return attrs.get(0).iterator().next().toString();
  }
}
opends/src/server/org/opends/server/admin/ManagedObjectPath.java
@@ -39,12 +39,7 @@
import org.opends.server.admin.std.meta.RootCfgDefn;
import org.opends.server.admin.std.server.RootCfg;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.RDN;
import org.opends.server.types.*;
/**
@@ -162,7 +157,7 @@
      String type = profile.getRelationChildRDNType(r);
      AttributeType atype = DirectoryServer.getAttributeType(
          type.toLowerCase(), true);
      AttributeValue avalue = new AttributeValue(atype, name);
      AttributeValue avalue = AttributeValues.create(atype, name);
      dn = dn.concat(RDN.create(atype, avalue));
    }
@@ -182,7 +177,7 @@
      String type = profile.getRelationChildRDNType(r);
      AttributeType atype = DirectoryServer.getAttributeType(
          type.toLowerCase(), true);
      AttributeValue avalue = new AttributeValue(atype, d.getName());
      AttributeValue avalue = AttributeValues.create(atype, d.getName());
      dn = dn.concat(RDN.create(atype, avalue));
    }
opends/src/server/org/opends/server/admin/Reference.java
@@ -104,7 +104,7 @@
          + s + "\"");
    }
    String name = av.getStringValue();
    String name = av.getValue().toString();
    // Check that the DN was valid.
    DN expected = p.child(rd, name).toDN();
opends/src/server/org/opends/server/admin/server/ConfigAddListenerAdaptor.java
@@ -216,7 +216,7 @@
      MessageBuilder unacceptableReason) {
    DN dn = configEntry.getDN();
    AttributeValue av = dn.getRDN().getAttributeValue(0);
    String name = av.getStringValue().trim();
    String name = av.getValue().toString().trim();
    try {
      ManagedObjectPath<?, ? extends S> childPath;
opends/src/server/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java
@@ -217,7 +217,7 @@
      MessageBuilder unacceptableReason) {
    DN dn = configEntry.getDN();
    AttributeValue av = dn.getRDN().getAttributeValue(0);
    String name = av.getStringValue().trim();
    String name = av.getValue().toString().trim();
    try {
      ManagedObjectPath<?, ? extends S> childPath;
opends/src/server/org/opends/server/admin/server/ServerManagementContext.java
@@ -352,7 +352,7 @@
     */
    public static <PD> PD decode(PropertyDefinition<PD> pd,
        AttributeValue value) throws IllegalPropertyValueStringException {
      String s = value.getStringValue();
      String s = value.getValue().toString();
      return pd.castValue(pd.accept(new ValueDecoder(), s));
    }
@@ -664,7 +664,7 @@
    for (DN child : children) {
      // Assume that RDNs are single-valued and can be trimmed.
      AttributeValue av = child.getRDN().getAttributeValue(0);
      names.add(av.getStringValue().trim());
      names.add(av.getValue().toString().trim());
    }
    return names.toArray(new String[names.size()]);
@@ -716,7 +716,7 @@
    for (DN child : children) {
      // Assume that RDNs are single-valued and can be trimmed.
      AttributeValue av = child.getRDN().getAttributeValue(0);
      names.add(av.getStringValue().trim());
      names.add(av.toString().trim());
    }
    return names.toArray(new String[names.size()]);
opends/src/server/org/opends/server/api/AccessControlHandler.java
@@ -22,13 +22,14 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.api;
import org.opends.messages.Message;
import java.util.List;
import org.opends.server.admin.std.server.AccessControlHandlerCfg;
@@ -40,13 +41,14 @@
/**
 * This class defines the set of methods and structures that must be
 * implemented by a Directory Server access control handler.  All
 * implemented by a Directory Server access control handler. All
 * methods in this class should take the entire request into account
 * when making the determination, including any request controls that
 * might have been provided.
 *
 * @param  <T>  The type of access control configuration handled by
 *              this access control provider implementation.
 * @param <T>
 *          The type of access control configuration handled by this
 *          access control provider implementation.
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.VOLATILE,
@@ -60,53 +62,48 @@
   * Initializes the access control handler implementation based on
   * the information in the provided configuration entry.
   *
   * @param  configuration  The configuration object that contains the
   *                        information to use to initialize this
   *                        access control handler.
   *
   * @throws  ConfigException  If an unrecoverable problem arises in
   *                           the process of performing the
   *                           initialization.
   *
   * @throws  InitializationException  If a problem occurs during
   *                                   initialization that is not
   *                                   related to the server
   *                                   configuration.
   * @param configuration
   *          The configuration object that contains the information
   *          to use to initialize this access control handler.
   * @throws ConfigException
   *           If an unrecoverable problem arises in the process of
   *           performing the initialization.
   * @throws InitializationException
   *           If a problem occurs during initialization that is not
   *           related to the server configuration.
   */
  public abstract void initializeAccessControlHandler(T configuration)
         throws ConfigException, InitializationException;
  throws ConfigException, InitializationException;
  /**
   * Indicates whether the provided configuration is acceptable for
   * this access control handler.  It should be possible to call this
   * this access control handler. It should be possible to call this
   * method on an uninitialized access control handler instance in
   * order to determine whether the handler would be able to use the
   * provided configuration.
   * <BR><BR>
   * provided configuration. <BR>
   * <BR>
   * Note that implementations which use a subclass of the provided
   * configuration class will likely need to cast the configuration
   * to the appropriate subclass type.
   * configuration class will likely need to cast the configuration to
   * the appropriate subclass type.
   *
   * @param  configuration        The access control handler
   *                              configuration for which to make the
   *                              determination.
   * @param  unacceptableReasons  A list that may be used to hold the
   *                              reasons that the provided
   *                              configuration is not acceptable.
   *
   * @return  {@code true} if the provided configuration is acceptable
   *          for this access control handler, or {@code false} if
   *          not.
   * @param configuration
   *          The access control handler configuration for which to
   *          make the determination.
   * @param unacceptableReasons
   *          A list that may be used to hold the reasons that the
   *          provided configuration is not acceptable.
   * @return {@code true} if the provided configuration is acceptable
   *         for this access control handler, or {@code false} if not.
   */
  public boolean isConfigurationAcceptable(
                      AccessControlHandlerCfg configuration,
                      List<Message> unacceptableReasons)
      AccessControlHandlerCfg configuration,
      List<Message> unacceptableReasons)
  {
    // This default implementation does not perform any special
    // validation.  It should be overridden by access control handler
    // validation. It should be overridden by access control handler
    // implementations that wish to perform more detailed validation.
    return true;
  }
@@ -125,152 +122,143 @@
  /**
   * Indicates whether the provided add operation is allowed based on
   * the access control configuration.  This method should not alter
   * the access control configuration. This method should not alter
   * the provided add operation in any way.
   *
   * @param  addOperation  The operation for which to make the
   *                       determination.
   *
   * @return  {@code true} if the operation should be allowed by the
   *          access control configuration, or {@code false} if not.
   * @param addOperation
   *          The operation for which to make the determination.
   * @return {@code true} if the operation should be allowed by the
   *         access control configuration, or {@code false} if not.
   */
  public abstract boolean isAllowed(LocalBackendAddOperation
                                         addOperation);
  public abstract boolean isAllowed(
      LocalBackendAddOperation addOperation);
  /**
   * Indicates whether the provided control is allowed based on
   * the access control configuration and the specified
   * operation. This method should not alter the provided
   * operation in any way.
   * Indicates whether the provided control is allowed based on the
   * access control configuration and the specified operation. This
   * method should not alter the provided operation in any way.
   *
   * @param  dn  A DN that can be used in the access determination.
   *
   * @param  op  The operation to use in the
   *                       determination.
   *
   * @param control The control for which to make the determination.
   *
   * @return  {@code true} if the control should be allowed by the
   *          access control configuration, or {@code false} if not.
   * @param dn
   *          A DN that can be used in the access determination.
   * @param op
   *          The operation to use in the determination.
   * @param control
   *          The control for which to make the determination.
   * @return {@code true} if the control should be allowed by the
   *         access control configuration, or {@code false} if not.
   */
  public abstract boolean isAllowed(DN dn, Operation  op,
  public abstract boolean isAllowed(DN dn, Operation op,
                                    Control control);
  /**
   * Indicates whether the provided bind operation is allowed based on
   * the access control configuration.  This method should not alter
   * the access control configuration. This method should not alter
   * the provided bind operation in any way.
   *
   * @param  bindOperation  The operation for which to make the
   *                        determination.
   *
   * @return  {@code true} if the operation should be allowed by the
   *          access control configuration, or {@code false} if not.
   * @param bindOperation
   *          The operation for which to make the determination.
   * @return {@code true} if the operation should be allowed by the
   *         access control configuration, or {@code false} if not.
   */
  public abstract boolean isAllowed(LocalBackendBindOperation
                                         bindOperation);
  public abstract boolean isAllowed(
      LocalBackendBindOperation bindOperation);
  /**
   * Indicates whether the provided compare operation is allowed based
   * on the access control configuration.  This method should not
   * alter the provided compare operation in any way.
   * on the access control configuration. This method should not alter
   * the provided compare operation in any way.
   *
   * @param  compareOperation  The operation for which to make the
   *                           determination.
   *
   * @return  {@code true} if the operation should be allowed by the
   *          access control configuration, or {@code false} if not.
   * @param compareOperation
   *          The operation for which to make the determination.
   * @return {@code true} if the operation should be allowed by the
   *         access control configuration, or {@code false} if not.
   */
  public abstract boolean isAllowed(LocalBackendCompareOperation
      compareOperation);
  public abstract boolean isAllowed(
      LocalBackendCompareOperation compareOperation);
  /**
   * Indicates whether the provided delete operation is allowed based
   * on the access control configuration.  This method should not
   * alter the provided delete operation in any way.
   * on the access control configuration. This method should not alter
   * the provided delete operation in any way.
   *
   * @param  deleteOperation  The operation for which to make the
   *                          determination.
   *
   * @return  {@code true} if the operation should be allowed by the
   *          access control configuration, or {@code false} if not.
   * @param deleteOperation
   *          The operation for which to make the determination.
   * @return {@code true} if the operation should be allowed by the
   *         access control configuration, or {@code false} if not.
   */
  public abstract boolean isAllowed(LocalBackendDeleteOperation
                                         deleteOperation);
  public abstract boolean isAllowed(
      LocalBackendDeleteOperation deleteOperation);
  /**
   * Indicates whether the provided extended operation is allowed
   * based on the access control configuration.  This method should
   * not alter the provided extended operation in any way.
   * based on the access control configuration. This method should not
   * alter the provided extended operation in any way.
   *
   * @param  extendedOperation  The operation for which to make the
   *                            determination.
   *
   * @return  {@code true} if the operation should be allowed by the
   *          access control configuration, or {@code false} if not.
   * @param extendedOperation
   *          The operation for which to make the determination.
   * @return {@code true} if the operation should be allowed by the
   *         access control configuration, or {@code false} if not.
   */
  public abstract boolean isAllowed(ExtendedOperation
                                         extendedOperation);
  public abstract boolean isAllowed(
      ExtendedOperation extendedOperation);
  /**
   * Indicates whether the provided modify operation is allowed based
   * on the access control configuration.  This method should not
   * alter the provided modify operation in any way.
   * on the access control configuration. This method should not alter
   * the provided modify operation in any way.
   *
   * @param  modifyOperation  The operation for which to make the
   *                          determination.
   *
   * @return  {@code true} if the operation should be allowed by the
   *          access control configuration, or {@code false} if not.
   * @param modifyOperation
   *          The operation for which to make the determination.
   * @return {@code true} if the operation should be allowed by the
   *         access control configuration, or {@code false} if not.
   */
  public abstract boolean isAllowed(LocalBackendModifyOperation
                                         modifyOperation);
  public abstract boolean isAllowed(
      LocalBackendModifyOperation modifyOperation);
  /**
   * Indicates whether the provided modify DN operation is allowed
   * based on the access control configuration.  This method should
   * not alter the provided modify DN operation in any way.
   * based on the access control configuration. This method should not
   * alter the provided modify DN operation in any way.
   *
   * @param  modifyDNOperation  The operation for which to make the
   *                            determination.
   *
   * @return  {@code true} if the operation should be allowed by the
   *          access control configuration, or {@code false} if not.
   * @param modifyDNOperation
   *          The operation for which to make the determination.
   * @return {@code true} if the operation should be allowed by the
   *         access control configuration, or {@code false} if not.
   */
  public abstract boolean isAllowed(LocalBackendModifyDNOperation
                                         modifyDNOperation);
  public abstract boolean isAllowed(
      LocalBackendModifyDNOperation modifyDNOperation);
  /**
   * Indicates whether the provided search operation is allowed based
   * on the access control configuration.  This method may only alter
   * on the access control configuration. This method may only alter
   * the provided search operation in order to add an opaque block of
   * data to it that will be made available for use in determining
   * whether matching search result entries or search result
   * references may be allowed.
   *
   * @param  searchOperation  The operation for which to make the
   *                          determination.
   *
   * @return  {@code true} if the operation should be allowed by the
   *          access control configuration, or {@code false} if not.
   * @param searchOperation
   *          The operation for which to make the determination.
   * @return {@code true} if the operation should be allowed by the
   *         access control configuration, or {@code false} if not.
   */
  public abstract boolean isAllowed(LocalBackendSearchOperation
                                         searchOperation);
  public abstract boolean isAllowed(
      LocalBackendSearchOperation searchOperation);
@@ -279,17 +267,18 @@
   * the client. Implementations <b>must not under any
   * circumstances</b> modify the search entry in any way.
   *
   * @param  searchOperation  The search operation with which the
   *                          provided entry is associated.
   * @param  searchEntry      The search result entry for which to
   *                          make the determination.
   *
   * @return  {@code true} if the access control configuration allows
   *          the entry to be returned to the client, or {@code false}
   *          if not.
   * @param searchOperation
   *          The search operation with which the provided entry is
   *          associated.
   * @param searchEntry
   *          The search result entry for which to make the
   *          determination.
   * @return {@code true} if the access control configuration allows
   *         the entry to be returned to the client, or {@code false}
   *         if not.
   */
  public abstract boolean maySend(SearchOperation searchOperation,
                                  SearchResultEntry searchEntry);
      SearchResultEntry searchEntry);
@@ -298,16 +287,16 @@
   * contains any attributes or values that the client is not
   * permitted to access.
   *
   * @param searchOperation The search operation with which the
   *                        provided entry is associated.
   * @param searchEntry     The search result entry to be filtered.
   *
   * @return  Returns the entry with filtered attributes and values
   *          removed.
   * @param searchOperation
   *          The search operation with which the provided entry is
   *          associated.
   * @param searchEntry
   *          The search result entry to be filtered.
   * @return Returns the entry with filtered attributes and values
   *         removed.
   */
  public abstract SearchResultEntry
                       filterEntry(SearchOperation searchOperation,
                                   SearchResultEntry searchEntry);
  public abstract SearchResultEntry filterEntry(
      SearchOperation searchOperation, SearchResultEntry searchEntry);
@@ -315,38 +304,40 @@
   * Indicates whether the provided search result reference may be
   * sent to the client based on the access control configuration.
   *
   * @param  dn         A DN that can be used in the access
   *                    determination.
   *
   * @param  searchOperation  The search operation with which the
   *                          provided reference is associated.
   * @param  searchReference  The search result reference for which to
   *                          make the determination.
   *
   * @return  {@code true} if the access control configuration allows
   *          the reference to be returned to the client, or
   *          {@code false} if not.
   * @param dn
   *          A DN that can be used in the access determination.
   * @param searchOperation
   *          The search operation with which the provided reference
   *          is associated.
   * @param searchReference
   *          The search result reference for which to make the
   *          determination.
   * @return {@code true} if the access control configuration allows
   *         the reference to be returned to the client, or {@code
   *         false} if not.
   */
  public abstract boolean maySend(DN dn,
                             SearchOperation searchOperation,
                             SearchResultReference searchReference);
                               SearchOperation searchOperation,
                               SearchResultReference searchReference);
  /**
   * Indicates if the specified proxy user entry can proxy, or act on
   * the behalf of the specified proxied user entry. The operation
   * parameter is used in the evaluation.
   *
   * @param proxyUser The entry to use as the proxy user.
   * @param proxiedUser The entry to be proxied by the proxy user.
   * @param operation The operation to use in the evaluation.
   *
   * @return  {@code true} if the access control configuration allows
   *          the proxy user to proxy the proxied user, or
   *          {@code false} if not.
   * @param proxyUser
   *          The entry to use as the proxy user.
   * @param proxiedUser
   *          The entry to be proxied by the proxy user.
   * @param operation
   *          The operation to use in the evaluation.
   * @return {@code true} if the access control configuration allows
   *         the proxy user to proxy the proxied user, or {@code
   *         false} if not.
   */
  public abstract boolean mayProxy(Entry proxyUser,
                                   Entry proxiedUser,
                                   Operation operation);
  public abstract boolean mayProxy(Entry proxyUser, Entry proxiedUser,
      Operation operation);
}
opends/src/server/org/opends/server/api/ApproximateMatchingRule.java
@@ -28,9 +28,8 @@
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ByteSequence;
/**
@@ -58,8 +57,8 @@
   * @return  {@code true} if the provided values are approximately
   *          equal, or {@code false} if not.
   */
  public abstract boolean approximatelyMatch(ByteString value1,
                                             ByteString value2);
  public abstract boolean approximatelyMatch(ByteSequence value1,
                                             ByteSequence value2);
@@ -82,8 +81,8 @@
   *          if it does not match, or {@code UNDEFINED} if the result
   *          is undefined.
   */
  public ConditionResult valuesMatch(ByteString attributeValue,
                                     ByteString assertionValue)
  public ConditionResult valuesMatch(ByteSequence attributeValue,
                                     ByteSequence assertionValue)
  {
    if (approximatelyMatch(attributeValue, assertionValue))
    {
opends/src/server/org/opends/server/api/AttributeSyntax.java
@@ -33,8 +33,8 @@
import org.opends.server.admin.std.server.AttributeSyntaxCfg;
import org.opends.server.config.ConfigException;
import org.opends.server.types.ByteString;
import org.opends.server.types.InitializationException;
import org.opends.server.types.ByteSequence;
import org.opends.messages.MessageBuilder;
@@ -209,7 +209,7 @@
   * @return  {@code true} if the provided value is acceptable for use
   *          with this syntax, or {@code false} if not.
   */
  public abstract boolean valueIsAcceptable(ByteString value,
  public abstract boolean valueIsAcceptable(ByteSequence value,
                               MessageBuilder invalidReason);
opends/src/server/org/opends/server/api/ClientConnection.java
@@ -448,45 +448,6 @@
  public abstract boolean isSecure();
  /**
   * Retrieves the connection security provider for this client
   * connection.
   *
   * @return  The connection security provider for this client
   *          connection.
   */
  public abstract ConnectionSecurityProvider
                       getConnectionSecurityProvider();
  /**
   * Specifies the connection security provider for this client
   * connection.
   *
   * @param  securityProvider  The connection security provider to use
   *                           for communication on this client
   *                           connection.
   */
  public abstract void setConnectionSecurityProvider(
                            ConnectionSecurityProvider
                                 securityProvider);
  /**
   * Retrieves the human-readable name of the security mechanism that
   * is used to protect communication with this client.
   *
   * @return  The human-readable name of the security mechanism that
   *          is used to protect communication with this client, or
   *          {@code null} if no security is in place.
   */
  public abstract String getSecurityMechanism();
  /**
   * Retrieves a {@code Selector} that may be used to ensure that
   * write  operations complete in a timely manner, or terminate the
@@ -1333,7 +1294,7 @@
      {
        for (AttributeValue v : a)
        {
          String privName = toLowerCase(v.getStringValue());
          String privName = toLowerCase(v.getValue().toString());
          // If the name of the privilege is prefixed with a minus
          // sign, then we will take away that privilege from the
@@ -1836,5 +1797,12 @@
  {
    return 0L;
  }
  /**
   * Return the Security Strength Factor of a client connection.
   *
   * @return An integer representing the SSF value of a connection.
   */
  public abstract int getSSF();
}
opends/src/server/org/opends/server/api/CompressedSchema.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Copyright 2009 Sun Microsystems, Inc.
 */
package org.opends.server.api;
@@ -30,10 +30,7 @@
import java.util.Map;
import org.opends.server.types.Attribute;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.*;
/**
@@ -52,28 +49,27 @@
   * the same set had been previously encoded, then the cached value
   * will be used.  Otherwise, a new value will be created.
   *
   * @param  objectClasses  The set of object classes for which to
   *                        retrieve the corresponding byte array
   *                        token.
   *
   * @return  A byte array containing the identifier assigned to the
   *          object class set.
   * @param  entryBuffer   The buffer to encode the object classes to.
   * @param  objectClasses The set of object classes for which to
   *                       retrieve the corresponding byte array
   *                       token.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to determine the appropriate
   *                              identifier.
   */
  public abstract byte[]
         encodeObjectClasses(Map<ObjectClass,String> objectClasses)
  public abstract void
         encodeObjectClasses(ByteStringBuilder entryBuffer,
                             Map<ObjectClass,String> objectClasses)
         throws DirectoryException;
  /**
   * Decodes an object class set from the provided byte array.
   * Decodes an object class set from the provided byte string.
   *
   * @param  encodedObjectClasses  The byte array containing the
   *                               object class set identifier.
   * @param  entryBuffer         The byte string containing the
   *                             object class set identifier.
   *
   * @return  The decoded object class set.
   *
@@ -81,7 +77,7 @@
   *                              decoded as an object class set.
   */
  public abstract Map<ObjectClass,String>
         decodeObjectClasses(byte[] encodedObjectClasses)
         decodeObjectClasses(ByteSequenceReader entryBuffer)
         throws DirectoryException;
@@ -90,36 +86,32 @@
   * Encodes the information in the provided attribute to a byte
   * array.
   *
   * @param  attribute  The attribute to be encoded.
   *
   * @return  An encoded representation of the provided attribute.
   * @param  entryBuffer The buffer to encode the attribute to.
   * @param  attribute   The attribute to be encoded.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to determine the appropriate
   *                              identifier.
   */
  public abstract byte[] encodeAttribute(Attribute attribute)
  public abstract void encodeAttribute(ByteStringBuilder entryBuffer,
                                       Attribute attribute)
         throws DirectoryException;
  /**
   * Decodes the contents of the provided array as an attribute.
   * Decodes the contents of the provided array as an attribute at the
   * current position.
   *
   * @param  encodedEntry  The byte array containing the encoded
   * @param  entryBuffer   The byte array containing the encoded
   *                       entry.
   * @param  startPos      The position within the array of the first
   *                       byte for the attribute to decode.
   * @param  length        The number of bytes contained in the
   *                       encoded attribute.
   *
   * @return  The decoded attribute.
   *
   * @throws  DirectoryException  If the attribute could not be
   *                              decoded properly for some reason.
   */
  public abstract Attribute decodeAttribute(byte[] encodedEntry,
                                            int startPos, int length)
          throws DirectoryException;
  public abstract Attribute decodeAttribute(
      ByteSequenceReader entryBuffer) throws DirectoryException;
}
opends/src/server/org/opends/server/api/ConnectionSecurityProvider.java
File was deleted
opends/src/server/org/opends/server/api/DebugLogPublisher.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Copyright 2009 Sun Microsystems, Inc.
 */
package org.opends.server.api;
import org.opends.messages.Message;
@@ -595,7 +595,8 @@
   * @param  settings        The current trace settings in effect.
   * @param  signature       The method signature.
   * @param  sourceLocation  The location of the method in the source.
   * @param  element         The protocol element to dump.
   * @param  decodedForm     The string reprentation of the protocol
   *                         element.
   * @param  stackTrace      The stack trace at the time the protocol
   *                         element is logged or null if its not
   *                         available.
@@ -604,7 +605,7 @@
                                            TraceSettings settings,
                                            String signature,
                                            String sourceLocation,
                                            ProtocolElement element,
                                            String decodedForm,
                                      StackTraceElement[] stackTrace);
  /**
opends/src/server/org/opends/server/api/DirectoryThread.java
@@ -34,9 +34,6 @@
import org.opends.server.backends.task.Task;
import org.opends.server.core.DirectoryServer;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
opends/src/server/org/opends/server/api/EqualityMatchingRule.java
@@ -28,13 +28,7 @@
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.DebugLogLevel;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.types.*;
@@ -51,11 +45,6 @@
public abstract class EqualityMatchingRule extends MatchingRule
{
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
  /**
   * Indicates whether the two provided normalized values are equal to
   * each other.
   *
@@ -67,10 +56,10 @@
   * @return  {@code true} if the provided values are equal, or
   *          {@code false} if not.
   */
  public abstract boolean areEqual(ByteString value1,
                                   ByteString value2);
  public boolean areEqual(ByteSequence value1, ByteSequence value2)
  {
    return value1.equals(value2);
  }
  /**
   * Indicates whether the provided attribute value should be
@@ -90,8 +79,9 @@
   *          a match for the provided assertion value, or
   *          {@code false} if not.
   */
  public ConditionResult valuesMatch(ByteString attributeValue,
                                     ByteString assertionValue)
  @Override
  public ConditionResult valuesMatch(ByteSequence attributeValue,
                                     ByteSequence assertionValue)
  {
    if (areEqual(attributeValue, assertionValue))
    {
@@ -122,33 +112,9 @@
   * @return  The hash code generated for the provided attribute
   *          value.
   */
  public int generateHashCode(AttributeValue attributeValue)
  public int generateHashCode(ByteSequence attributeValue)
  {
    try
    {
      return attributeValue.getNormalizedValue().hashCode();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      try
      {
        return attributeValue.getValue().hashCode();
      }
      catch (Exception e2)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e2);
        }
        return 0;
      }
    }
    return attributeValue.hashCode();
  }
}
opends/src/server/org/opends/server/api/ExtensibleIndexer.java
@@ -26,20 +26,25 @@
 */
package org.opends.server.api;
import java.util.Map;
import java.util.Set;
import org.opends.server.types.AttributeValue;
/**
 * This class is  registered with a Backend  and it provides call-
 * backs for indexing attribute values. An index implementation will
 * use this interface to create the keys for an attribute value.
 * This class is registered with a Backend and it provides call- backs
 * for indexing attribute values. An index implementation will use
 * this interface to create the keys for an attribute value.
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.VOLATILE,
     mayInstantiate=false,
     mayExtend=true,
     mayInvoke=false)
    stability = org.opends.server.types.StabilityLevel.VOLATILE,
    mayInstantiate = false,
    mayExtend = true,
    mayInvoke = false)
public abstract class ExtensibleIndexer
{
  /**
@@ -47,46 +52,57 @@
   * appended with the identifier returned from
   * {@link #getExtensibleIndexID()} will be used as the index
   * database name.
   * @return  The name of the index for this indexer.
   *
   * @return The name of the index for this indexer.
   */
  public abstract String getPreferredIndexName();
  /**
   * Returns an index identifier associated with this indexer. An
   * identifier should be selected based on the matching rule type.
   * A unique identifier will map to  a unique index database in
   * the backend implementation. If multiple matching rules
   * need to share the index database, the corresponding indexers
   * should always use the same identifier.
   * @return index ID A String containing the ID associated with
   *                          this indexer.
   * identifier should be selected based on the matching rule type. A
   * unique identifier will map to a unique index database in the
   * backend implementation. If multiple matching rules need to share
   * the index database, the corresponding indexers should always use
   * the same identifier.
   *
   * @return index ID A String containing the ID associated with this
   *         indexer.
   */
  public abstract String getExtensibleIndexID();
  /**
   * Generates the set of index keys for an attribute.
   * @param value The attribute value  for which  keys are required.
   * @param keys The set into which the generated keys will be
   *                          inserted.
   *
   * @param value
   *          The attribute value for which keys are required.
   * @param keys
   *          The set into which the generated keys will be inserted.
   */
  public abstract void getKeys(AttributeValue value,
                                                  Set<byte[]> keys);
      Set<byte[]> keys);
  /**
   * Generates a map of index keys and a boolean flag indicating
   * whether the corresponding key will be inserted or deleted.
   * @param value The attribute for which keys are required.
   * @param modifiedKeys A map containing the keys and a boolean.
   *              Keys corresponding to the boolean value <code>true
   *              </code> should be inserted and <code>false</code>
   *              should be deleted.
   * @param insert <code>true</code> if generated keys should
   *            be inserted or <code>false</code> otherwise.
   *
   * @param value
   *          The attribute for which keys are required.
   * @param modifiedKeys
   *          A map containing the keys and a boolean. Keys
   *          corresponding to the boolean value <code>true
   *              </code>
   *          should be inserted and <code>false</code> should be
   *          deleted.
   * @param insert
   *          <code>true</code> if generated keys should be inserted
   *          or <code>false</code> otherwise.
   */
  public abstract void getKeys(AttributeValue value,
                                  Map<byte[], Boolean> modifiedKeys,
                                  Boolean insert);
      Map<byte[], Boolean> modifiedKeys, Boolean insert);
}
opends/src/server/org/opends/server/api/ExtensibleMatchingRule.java
@@ -26,51 +26,59 @@
 */
package org.opends.server.api;
import java.util.Collection;
import org.opends.server.types.ByteString;
import org.opends.server.types.ByteSequence;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.IndexConfig;
/**
 * This class defines the set of methods and structures that must be
 * implemented by a Directory Server module that implements an
 * Extensible matching rule.
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.VOLATILE,
     mayInstantiate=false,
     mayExtend=true,
     mayInvoke=false)
    stability = org.opends.server.types.StabilityLevel.VOLATILE,
    mayInstantiate = false,
    mayExtend = true,
    mayInvoke = false)
public abstract class ExtensibleMatchingRule extends MatchingRule
{
  /**
  * Returns a collection of extensible indexers associated with this
  * matching rule.
  * @param config The index configuration to be used by this
  *                      matching rule.
  * @return ExtensibleIndexer associated with this matching rule.
  */
  public  abstract Collection<ExtensibleIndexer> getIndexers(
          IndexConfig config);
   * Returns a collection of extensible indexers associated with this
   * matching rule.
   *
   * @param config
   *          The index configuration to be used by this matching
   *          rule.
   * @return The collection of extensible indexers associated with
   *         this matching rule.
   */
  public abstract Collection<ExtensibleIndexer> getIndexers(
      IndexConfig config);
  /**
   * Queries the index using factory of type T and returns
   * a query of type T for the provided assertion value.
   * @param  <T>  The type of IndexQueryFactory.
   * @param  assertionValue  An assertion value which needs to be
   *                                               queried.
   * @param factory  An IndexQueryFactory which will be used for
   *                                creating  queries.
   * @return T  The generated index query.
   * @throws DirectoryException  If an  error occurs while generating
   *                the query.
   * Returns an index query appropriate for the provided attribute
   * value assertion.
   *
   * @param <T>
   *          The type of index query created by the {@code factory}.
   * @param assertionValue
   *          The attribute value assertion.
   * @param factory
   *          The index query factory which should be used to
   *          construct the index query.
   * @return The index query appropriate for the provided attribute
   *         value assertion.
   * @throws DirectoryException
   *           If an error occurs while generating the index query.
   */
  public  abstract <T> T createIndexQuery(
                   ByteString assertionValue,
                   IndexQueryFactory<T> factory)
                                          throws DirectoryException;
  public abstract <T> T createIndexQuery(ByteSequence assertionValue,
      IndexQueryFactory<T> factory) throws DirectoryException;
}
opends/src/server/org/opends/server/api/IndexQueryFactory.java
@@ -26,39 +26,50 @@
 */
package org.opends.server.api;
import java.util.Collection;
import org.opends.server.types.ByteSequence;
/**
 * This class acts as a factory for creating index queries. This
 * A factory for creating arbitrarily complex index queries. This
 * interface is implemented by the underlying backend implementation
 * and passed to extensible matching rules so that they can construct
 * arbitrarily complex index queries.
 *
 * @param  <T>  The type of Results  returned by the factory.
 * @param <T>
 *          The type of query created by this factory.
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.VOLATILE,
     mayInstantiate=false,
     mayExtend=true,
     mayInvoke=false)
    stability = org.opends.server.types.StabilityLevel.VOLATILE,
    mayInstantiate = false,
    mayExtend = true,
    mayInvoke = false)
public interface IndexQueryFactory<T>
{
  /**
   * Returns a query requesting an index record matching the
   * provided key.
   * @param indexID An identifier of the index type.
   * @param key A byte array containing the key.
   * Returns a query requesting an index record matching the provided
   * key.
   *
   * @param indexID
   *          An identifier of the index type.
   * @param key
   *          A byte sequence containing the key.
   * @return A query requesting the index record matching the key.
   */
  T createExactMatchQuery(String indexID,byte[] key);
  T createExactMatchQuery(String indexID, ByteSequence key);
  /**
   * Returns a query requesting all  index records. A backend
   * implementation may choose to return all or no records as
   * part of the optimization.
   * Returns a query requesting all index records. A backend
   * implementation may choose to return all or no records as part of
   * the optimization.
   *
   * @return A query requesting all index records.
   */
  T createMatchAllQuery();
@@ -66,53 +77,59 @@
  /**
   * Rreturns a query requesting all index records in the specified
   * Returns a query requesting all index records in the specified
   * range.
   * @param indexID An identifier of the index type.
   * @param lower  The lower bound of the range.   A 0 length byte
   *                      array indicates  no lower bound and the
   *                      range will start from the smallest key.
   * @param upper The upper bound of the range. A 0 length byte array
   *                      indicates no upper bound and the range will
   *                      end at  the largest key.
   * @param lowerIncluded true if a key exactly matching the lower
   *                       bound is included in the range, false if
   *                       only keys strictly greater than the lower
   *                       bound are included.This value is ignored if
   *                       the lower bound is not specified.
   * @param upperIncluded true if a key exactly matching the upper
   *                      bound is included in the range, false if
   *                      only keys strictly less than the upper
   *                      bound are included. This value is ignored if
   *                      the upper bound is not specified.
   *
   * @param indexID
   *          An identifier of the index type.
   * @param lower
   *          The lower bound of the range. A 0 length byte array
   *          indicates no lower bound and the range will start from
   *          the smallest key.
   * @param upper
   *          The upper bound of the range. A 0 length byte array
   *          indicates no upper bound and the range will end at the
   *          largest key.
   * @param lowerIncluded
   *          true if a key exactly matching the lower bound is
   *          included in the range, false if only keys strictly
   *          greater than the lower bound are included.This value
   *          is ignored if the lower bound is not specified.
   * @param upperIncluded
   *          true if a key exactly matching the upper bound is
   *          included in the range, false if only keys strictly
   *          less than the upper bound are included. This value is
   *          ignored if the upper bound is not specified.
   * @return A query requesting all index records in the specified
   * range.
   *         range.
   */
  T createRangeMatchQuery(
                              String indexID,
                              byte[]  lower,
                              byte[] upper,
                              boolean lowerIncluded,
                              boolean upperIncluded);
  T createRangeMatchQuery(String indexID, ByteSequence lower,
      ByteSequence upper, boolean lowerIncluded,
      boolean upperIncluded);
  /**
   * Returns a query requesting  intersection from a Collection of
   * Returns a query which returns the intersection of a collection of
   * sub-queries.
   *@param  subquery  A Collection of sub-queries.
   *@return A query requesting intersection of  the records.
   *
   * @param subquery
   *          A collection of sub-queries.
   * @return A query which returns the intersection of a collection of
   *         sub-queries.
   */
  T createIntersectionQuery(Collection<T> subquery);
  /**
   * Returns a query requesting union from a Collection of
   * Returns a query which combines the results of a collection of
   * sub-queries.
   * @param  subquery  A Collection of sub-queries.
   * @return A query requesting union of the records.
   *
   * @param subquery
   *          A collection of sub-queries.
   * @return A query which combines the results of a collection of
   *         sub-queries.
   */
  T createUnionQuery(Collection<T> subquery);
}
opends/src/server/org/opends/server/api/MatchingRule.java
@@ -26,7 +26,11 @@
 */
package org.opends.server.api;
import java.util.Collection;
import org.opends.server.types.ByteSequence;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.DirectoryException;
@@ -39,17 +43,17 @@
 * rule.
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.VOLATILE,
     mayInstantiate=false,
     mayExtend=true,
     mayInvoke=false)
    stability = org.opends.server.types.StabilityLevel.VOLATILE,
    mayInstantiate = false,
    mayExtend = true,
    mayInvoke = false)
public abstract class MatchingRule
{
  /**
   * Retrieves the common name for this matching rule.
   *
   * @return  The common name for this matching rule, or {@code null}
   *          if it does not have a name.
   * @return The common name for this matching rule, or {@code null}
   *         if it does not have a name.
   */
  public abstract String getName();
@@ -58,7 +62,7 @@
  /**
   * Retrieves all names for this matching rule.
   *
   * @return  All names for this matching rule.
   * @return All names for this matching rule.
   */
  public abstract Collection<String> getAllNames();
@@ -67,40 +71,39 @@
  /**
   * Retrieves the OID for this matching rule.
   *
   * @return  The OID for this matching rule.
   * @return The OID for this matching rule.
   */
  public abstract String getOID();
 /**
  /**
   * Retrieves the normalized form of the provided assertion value,
   * which is best suite for efficiently performing matching
   * operations on that value.
   *
   * @param  value  The assertion value to be normalized.
   *
   * @return  The normalized version of the provided value.
   *
   * @throws  DirectoryException  If the provided value is invalid
   *                              according to the associated
   *                              attribute syntax.
   * @param value
   *          The assertion value to be normalized.
   * @return The normalized version of the provided value.
   * @throws DirectoryException
   *           If the provided value is invalid according to the
   *           associated attribute syntax.
   */
  public ByteString normalizeAssertionValue(ByteString value)
         throws DirectoryException
  public ByteString normalizeAssertionValue(ByteSequence value)
      throws DirectoryException
  {
    // Default implementation is to use attribute value normalization.
     return normalizeValue(value);
    return normalizeValue(value);
  }
  /**
   * Retrieves the name or OID for this matching rule.  If it has a
   * name, then it will be returned.  Otherwise, the OID will be
   * Retrieves the name or OID for this matching rule. If it has a
   * name, then it will be returned. Otherwise, the OID will be
   * returned.
   *
   * @return  The name or OID for this matching rule.
   * @return The name or OID for this matching rule.
   */
  public final String getNameOrOID()
  {
@@ -120,8 +123,8 @@
  /**
   * Retrieves the description for this matching rule.
   *
   * @return  The description for this matching rule, or {@code null}
   *          if there is none.
   * @return The description for this matching rule, or {@code null}
   *         if there is none.
   */
  public abstract String getDescription();
@@ -131,22 +134,22 @@
   * Retrieves the OID of the syntax with which this matching rule is
   * associated.
   *
   * @return  The OID of the syntax with which this matching rule is
   *          associated.
   * @return The OID of the syntax with which this matching rule is
   *         associated.
   */
  public abstract String getSyntaxOID();
  /**
   * Indicates whether this matching rule is declared "OBSOLETE".
   * The default implementation will always return {@code false}.  If
   * that is not acceptable for a particular matching rule
   * implementation, then it should override this method and perform
   * the appropriate processing to return the correct value.
   * Indicates whether this matching rule is declared "OBSOLETE". The
   * default implementation will always return {@code false}. If that
   * is not acceptable for a particular matching rule implementation,
   * then it should override this method and perform the appropriate
   * processing to return the correct value.
   *
   * @return  {@code true} if this matching rule is declared
   *          "OBSOLETE", or {@code false} if not.
   * @return {@code true} if this matching rule is declared
   *         "OBSOLETE", or {@code false} if not.
   */
  public boolean isObsolete()
  {
@@ -157,60 +160,58 @@
  /**
   * Retrieves the normalized form of the provided value, which is
   * best suite for efficiently performing matching operations on that
   * value.
   * best suite for efficiently performing matching operations on
   * that value.
   *
   * @param  value  The value to be normalized.
   *
   * @return  The normalized version of the provided value.
   *
   * @throws  DirectoryException  If the provided value is invalid
   *                              according to the associated
   *                              attribute syntax.
   * @param value
   *          The value to be normalized.
   * @return The normalized version of the provided value.
   * @throws DirectoryException
   *           If the provided value is invalid according to the
   *           associated attribute syntax.
   */
  public abstract ByteString normalizeValue(ByteString value)
         throws DirectoryException;
  public abstract ByteString normalizeValue(ByteSequence value)
      throws DirectoryException;
  /**
   * Indicates whether the provided attribute value should be
   * considered a match for the given assertion value.  This will only
   * be used for the purpose of extensible matching.  Subclasses
   * considered a match for the given assertion value. This will only
   * be used for the purpose of extensible matching. Subclasses
   * should define more specific methods that are appropriate to the
   * matching rule type.
   *
   * @param  attributeValue  The attribute value in a form that has
   *                         been normalized according to this
   *                         matching rule.
   * @param  assertionValue  The assertion value in a form that has
   *                         been normalized according to this
   *                         matching rule.
   *
   * @return  {@code TRUE} if the attribute value should be considered
   *          a match for the provided assertion value, {@code FALSE}
   *          if it does not match, or {@code UNDEFINED} if the result
   *          is undefined.
   * @param attributeValue
   *          The attribute value in a form that has been normalized
   *          according to this matching rule.
   * @param assertionValue
   *          The assertion value in a form that has been normalized
   *          according to this matching rule.
   * @return {@code TRUE} if the attribute value should be considered
   *         a match for the provided assertion value, {@code FALSE}
   *         if it does not match, or {@code UNDEFINED} if the result
   *         is undefined.
   */
  public abstract ConditionResult
                       valuesMatch(ByteString attributeValue,
                                   ByteString assertionValue);
  public abstract ConditionResult valuesMatch(
      ByteSequence attributeValue, ByteSequence assertionValue);
  /**
   * Retrieves the hash code for this matching rule.  It will be
   * Retrieves the hash code for this matching rule. It will be
   * calculated as the sum of the characters in the OID.
   *
   * @return  The hash code for this matching rule.
   * @return The hash code for this matching rule.
   */
  @Override
  public final int hashCode()
  {
    int hashCode = 0;
    String oidString = getOID();
    int    oidLength = oidString.length();
    for (int i=0; i < oidLength; i++)
    int oidLength = oidString.length();
    for (int i = 0; i < oidLength; i++)
    {
      hashCode += oidString.charAt(i);
    }
@@ -222,14 +223,15 @@
  /**
   * Indicates whether the provided object is equal to this matching
   * rule.  The provided object will be considered equal to this
   * rule. The provided object will be considered equal to this
   * matching rule only if it is a matching rule with the same OID.
   *
   * @param  o  The object for which to make the determination.
   *
   * @return  {@code true} if the provided object is equal to this
   *          matching rule, or {@code false} if it is not.
   * @param o
   *          The object for which to make the determination.
   * @return {@code true} if the provided object is equal to this
   *         matching rule, or {@code false} if it is not.
   */
  @Override
  public final boolean equals(Object o)
  {
    if (o == null)
@@ -242,7 +244,7 @@
      return true;
    }
    if (! (o instanceof MatchingRule))
    if (!(o instanceof MatchingRule))
    {
      return false;
    }
@@ -256,9 +258,10 @@
   * Retrieves a string representation of this matching rule in the
   * format defined in RFC 2252.
   *
   * @return  A string representation of this matching rule in the
   *          format defined in RFC 2252.
   * @return A string representation of this matching rule in the
   *         format defined in RFC 2252.
   */
  @Override
  public final String toString()
  {
    StringBuilder buffer = new StringBuilder();
@@ -272,15 +275,15 @@
   * Appends a string representation of this matching rule in the
   * format defined in RFC 2252 to the provided buffer.
   *
   * @param  buffer  The buffer to which the information should be
   *                 appended.
   * @param buffer
   *          The buffer to which the information should be appended.
   */
  public final void toString(StringBuilder buffer)
  {
    buffer.append("( ");
    buffer.append(getOID());
    buffer.append(" NAME '");
      buffer.append(getName());
    buffer.append(getName());
    String description = getDescription();
    if ((description != null) && (description.length() > 0))
@@ -302,4 +305,3 @@
    buffer.append(" )");
  }
}
opends/src/server/org/opends/server/api/OrderingMatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.api;
@@ -31,9 +31,8 @@
import java.io.Serializable;
import java.util.Comparator;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ByteSequence;
/**
@@ -76,8 +75,8 @@
   *          ascending order, or zero if there is no difference
   *          between the values with regard to ordering.
   */
  public abstract int compareValues(ByteString value1,
                                    ByteString value2);
  public abstract int compareValues(ByteSequence value1,
                                    ByteSequence value2);
@@ -103,8 +102,8 @@
   *          a match for the provided assertion value, or
   *          {@code false} if not.
   */
  public ConditionResult valuesMatch(ByteString attributeValue,
                                     ByteString assertionValue)
  public ConditionResult valuesMatch(ByteSequence attributeValue,
                                     ByteSequence assertionValue)
  {
    return ConditionResult.UNDEFINED;
  }
opends/src/server/org/opends/server/api/PasswordGenerator.java
@@ -33,11 +33,7 @@
import org.opends.server.admin.std.server.PasswordGeneratorCfg;
import org.opends.server.config.ConfigException;
import org.opends.server.types.ByteString;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.InitializationException;
import org.opends.server.types.*;
/**
opends/src/server/org/opends/server/api/PasswordStorageScheme.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.api;
import org.opends.messages.Message;
@@ -33,10 +33,7 @@
import org.opends.server.admin.std.server.PasswordStorageSchemeCfg;
import org.opends.server.config.ConfigException;
import org.opends.server.types.ByteString;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
import org.opends.server.types.*;
/**
@@ -151,7 +148,7 @@
   * @throws  DirectoryException  If a problem occurs while
   *                              processing.
   */
  public abstract ByteString encodePassword(ByteString plaintext)
  public abstract ByteString encodePassword(ByteSequence plaintext)
         throws DirectoryException;
@@ -170,7 +167,7 @@
   *                              processing.
   */
  public abstract ByteString encodePasswordWithScheme(
                                  ByteString plaintext)
                                  ByteSequence plaintext)
         throws DirectoryException;
@@ -190,8 +187,8 @@
   *          the provided stored password, or {@code false} if not.
   */
  public abstract boolean passwordMatches(
                               ByteString plaintextPassword,
                               ByteString storedPassword);
                               ByteSequence plaintextPassword,
                               ByteSequence storedPassword);
@@ -242,8 +239,8 @@
   *                              support the authentication password
   *                              syntax.
   */
  public abstract ByteString encodeAuthPassword(ByteString plaintext)
         throws DirectoryException;
  public abstract ByteString encodeAuthPassword(
      ByteSequence plaintext) throws DirectoryException;
@@ -268,7 +265,7 @@
   *          password syntax.
   */
  public abstract boolean authPasswordMatches(
                               ByteString plaintextPassword,
                               ByteSequence plaintextPassword,
                               String authInfo, String authValue);
@@ -301,7 +298,7 @@
   *                              stored password.
   */
  public abstract ByteString getPlaintextValue(
                                  ByteString storedPassword)
                                  ByteSequence storedPassword)
         throws DirectoryException;
opends/src/server/org/opends/server/api/PasswordValidator.java
@@ -34,10 +34,7 @@
import org.opends.server.admin.std.server.PasswordValidatorCfg;
import org.opends.server.config.ConfigException;
import org.opends.server.types.ByteString;
import org.opends.server.types.Entry;
import org.opends.server.types.InitializationException;
import org.opends.server.types.Operation;
import org.opends.server.types.*;
import org.opends.messages.MessageBuilder;
opends/src/server/org/opends/server/api/SubstringMatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.api;
@@ -30,10 +30,7 @@
import java.util.List;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.*;
/**
@@ -60,8 +57,8 @@
   *                              not acceptable according to the
   *                              associated syntax.
   */
  public abstract ByteString normalizeSubstring(ByteString substring)
         throws DirectoryException;
  public abstract ByteString normalizeSubstring(
      ByteSequence substring) throws DirectoryException;
@@ -86,11 +83,97 @@
   * @return  {@code true} if the provided value does match the given
   *          substring components, or {@code false} if not.
   */
  public abstract boolean valueMatchesSubstring(
                               ByteString value,
                               ByteString subInitial,
                               List<ByteString> subAnyElements,
                               ByteString subFinal);
  public boolean valueMatchesSubstring(ByteSequence value,
                                    ByteSequence subInitial,
                                    List<ByteSequence> subAnyElements,
                                    ByteSequence subFinal)
  {
    int valueLength = value.length();
    int pos = 0;
    if (subInitial != null)
    {
      int initialLength = subInitial.length();
      if (initialLength > valueLength)
      {
        return false;
      }
      for (; pos < initialLength; pos++)
      {
        if (subInitial.byteAt(pos) != value.byteAt(pos))
        {
          return false;
        }
      }
    }
    if ((subAnyElements != null) && (! subAnyElements.isEmpty()))
    {
      for (ByteSequence element : subAnyElements)
      {
        int anyLength = element.length();
        if(anyLength == 0)
            continue;
        int end = valueLength - anyLength;
        boolean match = false;
        for (; pos <= end; pos++)
        {
          if (element.byteAt(0) == value.byteAt(pos))
          {
            boolean subMatch = true;
            for (int i=1; i < anyLength; i++)
            {
              if (element.byteAt(i) != value.byteAt(pos+i))
              {
                subMatch = false;
                break;
              }
            }
            if (subMatch)
            {
              match = subMatch;
              break;
            }
          }
        }
        if (match)
        {
          pos += anyLength;
        }
        else
        {
          return false;
        }
      }
    }
    if (subFinal != null)
    {
      int finalLength = subFinal.length();
      if ((valueLength - finalLength) < pos)
      {
        return false;
      }
      pos = valueLength - finalLength;
      for (int i=0; i < finalLength; i++,pos++)
      {
        if (subFinal.byteAt(i) != value.byteAt(pos))
        {
          return false;
        }
      }
    }
    return true;
  }
@@ -116,8 +199,9 @@
   *          a match for the provided assertion value, or
   *          {@code false} if not.
   */
  public ConditionResult valuesMatch(ByteString attributeValue,
                                     ByteString assertionValue)
  @Override
  public ConditionResult valuesMatch(ByteSequence attributeValue,
                                     ByteSequence assertionValue)
  {
    return ConditionResult.UNDEFINED;
  }
opends/src/server/org/opends/server/api/VirtualAttributeProvider.java
@@ -37,13 +37,7 @@
import org.opends.server.admin.std.server.VirtualAttributeCfg;
import org.opends.server.config.ConfigException;
import org.opends.server.core.SearchOperation;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.Entry;
import org.opends.server.types.InitializationException;
import org.opends.server.types.VirtualAttributeRule;
import org.opends.server.types.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
@@ -317,7 +311,7 @@
    }
    ArrayList<ByteString> normalizedSubAny;
    ArrayList<ByteSequence> normalizedSubAny;
    if (subAny == null)
    {
      normalizedSubAny = null;
@@ -325,7 +319,7 @@
    else
    {
      normalizedSubAny =
           new ArrayList<ByteString>(subAny.size());
           new ArrayList<ByteSequence>(subAny.size());
      for (ByteString subAnyElement : subAny)
      {
        try
opends/src/server/org/opends/server/authorization/dseecompat/Aci.java
@@ -28,8 +28,8 @@
package org.opends.server.authorization.dseecompat;
import org.opends.messages.Message;
import org.opends.server.types.ByteString;
import org.opends.server.types.DN;
import org.opends.server.types.ByteSequence;
import static org.opends.messages.AccessControlMessages.*;
import static org.opends.server.util.StaticUtils.isDigit;
@@ -362,9 +362,9 @@
     * @return  Returns a decoded ACI representing the string argument.
     * @throws AciException If the parsing of the ACI string fails.
     */
    public static Aci decode (ByteString byteString, DN dn)
    public static Aci decode (ByteSequence byteString, DN dn)
    throws AciException {
        String input=byteString.stringValue();
        String input=byteString.toString();
        //Perform a quick pattern check against the string to catch any
        //obvious syntax errors.
        if (!Pattern.matches(aciRegex, input)) {
@@ -387,7 +387,7 @@
     * @return A string representation of the ACI.
     */
    public String toString() {
        return new String(aciString);
        return aciString;
    }
    /**
opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java
@@ -27,22 +27,22 @@
package org.opends.server.authorization.dseecompat;
import org.opends.server.protocols.ldap.LDAPClientConnection;
import org.opends.server.types.*;
import org.opends.server.api.ClientConnection;
import org.opends.server.api.Group;
import org.opends.server.core.AddOperationBasis;
import org.opends.server.api.ConnectionSecurityProvider;
import org.opends.server.core.SearchOperation;
import org.opends.server.extensions.TLSConnectionSecurityProvider;
import org.opends.server.types.Operation;
import java.net.InetAddress;
import java.security.cert.Certificate;
import java.util.LinkedList;
import java.util.List;
import java.util.HashMap;
import static org.opends.server.authorization.dseecompat.Aci.*;
import static org.opends.server.authorization.dseecompat.AciHandler.*;
import org.opends.server.controls.GetEffectiveRights;
import org.opends.server.controls.GetEffectiveRightsRequestControl;
import static org.opends.server.util.ServerConstants.OID_GET_EFFECTIVE_RIGHTS;
/**
@@ -287,8 +287,8 @@
      if(operation instanceof SearchOperation && (rights == ACI_READ)) {
        //Checks if a geteffectiverights control was sent and
        //sets up the structures needed.
        GetEffectiveRights getEffectiveRightsControl =
              (GetEffectiveRights)
        GetEffectiveRightsRequestControl getEffectiveRightsControl =
              (GetEffectiveRightsRequestControl)
                      operation.getAttachment(OID_GET_EFFECTIVE_RIGHTS);
        if(getEffectiveRightsControl != null) {
          hasGetEffectiveRightsControl=true;
@@ -835,15 +835,14 @@
             */
            if (authInfo.hasAuthenticationType(AuthenticationType.SASL) &&
                 authInfo.hasSASLMechanism(saslMech)) {
              ConnectionSecurityProvider provider =
                    clientConnection.getConnectionSecurityProvider();
              if (provider instanceof TLSConnectionSecurityProvider) {
                TLSConnectionSecurityProvider tlsProvider =
                      (TLSConnectionSecurityProvider) provider;
                 if (tlsProvider.getClientCertificateChain() != null) {
                   matched = EnumEvalResult.TRUE;
                 }
              }
                if(clientConnection instanceof LDAPClientConnection) {
                    LDAPClientConnection lc =
                                       (LDAPClientConnection) clientConnection;
                    Certificate[] certChain = lc.getClientCertificateChain();
                    if(certChain.length != 0)
                        matched = EnumEvalResult.TRUE;
                }
            }
          } else {
            // A particular SASL mechanism.
@@ -985,6 +984,6 @@
   * {@inheritDoc}
   */
  public int getCurrentSSF() {
      return clientConnection.getConnectionSecurityProvider().getSSF();
      return clientConnection.getSSF();
  }
}
opends/src/server/org/opends/server/authorization/dseecompat/AciEffectiveRights.java
@@ -29,7 +29,6 @@
import static org.opends.server.authorization.dseecompat.Aci.*;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.*;
import java.util.LinkedHashSet;
@@ -326,15 +325,15 @@
      //Write right is more complicated. Create a dummy value and set that as
      //the attribute's value. Call the special writeRightsString method, rather
      //than rightsString.
      AttributeValue val=new AttributeValue(a, "dum###Val");
      AttributeValue val= AttributeValues.create(a, "dum###Val");
      container.setCurrentAttributeValue(val);
      evalInfo.append(attributeLevelWriteRights(container, handler, skipCheck));
      addAttrLevelRightsInfo(container, mask, a, retEntry, "write");
      evalInfo.append(',');
      //Perform both selfwrite_add and selfwrite_delete and append results.
      ByteString clientDNStr=
              new ASN1OctetString(container.getClientDN().toString());
      AttributeValue val1=new AttributeValue(a, clientDNStr);
      AttributeValue val1=
          AttributeValues.create(a,
              container.getClientDN().toString());
      if(!specificAttr)
        container.setCurrentAttributeType(dnAttributeType);
      container.setCurrentAttributeValue(val1);
opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -47,9 +47,10 @@
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPControl;
import org.opends.server.types.*;
import org.opends.server.workflowelement.localbackend.*;
import org.opends.server.controls.GetEffectiveRights;
import org.opends.server.controls.GetEffectiveRightsRequestControl;
import org.opends.server.backends.jeb.EntryContainer;
@@ -568,7 +569,8 @@
           (isAttributeDN(container.getCurrentAttributeType())))  {
          String DNString=null;
          try {
           DNString  =  container.getCurrentAttributeValue().getStringValue();
            DNString =
                container.getCurrentAttributeValue().getValue().toString();
            DN tmpDN = DN.decode(DNString);
            //Have a valid DN, compare to clientDN to see if the ACI_SELF
            //right should be set.
@@ -911,7 +913,8 @@
           DirectoryServer.getAttributeType(baseName)) == null)
           attributeType = DirectoryServer.getDefaultAttributeType(baseName);
       AttributeValue attributeValue =
           new AttributeValue(attributeType, operation.getAssertionValue());
           AttributeValues.create(attributeType,
               operation.getAssertionValue());
       operationContainer.setCurrentAttributeType(attributeType);
       operationContainer.setCurrentAttributeValue(attributeValue);
       return isAllowed(operationContainer, operation);
@@ -1186,12 +1189,20 @@
      op.setAttachment(ORIG_AUTH_ENTRY, op.getAuthorizationEntry());
    else if(control.getOID().equals(OID_GET_EFFECTIVE_RIGHTS)) {
      try {
        GetEffectiveRights getEffectiveRightsControl =
                GetEffectiveRights.decodeControl(control);
        GetEffectiveRightsRequestControl getEffectiveRightsControl;
        if(control instanceof LDAPControl)
        {
          getEffectiveRightsControl = GetEffectiveRightsRequestControl.DECODER
              .decode(control.isCritical(), ((LDAPControl) control).getValue());
        }
        else
        {
          getEffectiveRightsControl = (GetEffectiveRightsRequestControl)control;
        }
        op.setAttachment(OID_GET_EFFECTIVE_RIGHTS, getEffectiveRightsControl);
      } catch  (LDAPException le)  {
      } catch  (DirectoryException de)  {
        Message message =
            WARN_ACI_SYNTAX_DECODE_EFFECTIVERIGHTS_FAIL.get(le.getMessage());
            WARN_ACI_SYNTAX_DECODE_EFFECTIVERIGHTS_FAIL.get(de.getMessage());
        logError(message);
        ret=false;
      }
@@ -1231,7 +1242,7 @@
      // Load the values, a bind rule might want to evaluate them.
      for (String URLString : URLStrings) {
        builder.add(new AttributeValue(refAttrType, URLString));
        builder.add(AttributeValues.create(refAttrType, URLString));
      }
      e.addAttribute(builder.toAttribute(),null);
opends/src/server/org/opends/server/authorization/dseecompat/AciList.java
@@ -394,7 +394,7 @@
        for(Aci aci : hashEntry.getValue()) {
          try {
             Aci newAci =
               Aci.decode(ByteStringFactory.create(aci.toString()), relocateDN);
               Aci.decode(ByteString.valueOf(aci.toString()), relocateDN);
             acis.add(newAci);
          } catch (AciException ex) {
            //This should never happen since only a copy of the
opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java
@@ -39,6 +39,7 @@
import org.opends.server.types.operation.PostResponseModifyDNOperation;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPControl;
import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
@@ -240,10 +241,11 @@
      //Add manageDsaIT control so any ACIs in referral entries will be
      //picked up.
      ArrayList<Control> controls = new ArrayList<Control>(1);
      controls.add(new Control(OID_MANAGE_DSAIT_CONTROL, true));
      controls.add(new LDAPControl(OID_MANAGE_DSAIT_CONTROL, true));
      //Add group membership control to let a backend look for it and
      //decide if it would abort searches.
      controls.add(new Control(OID_INTERNAL_GROUP_MEMBERSHIP_UPDATE ,false));
      controls.add(new LDAPControl(
          OID_INTERNAL_GROUP_MEMBERSHIP_UPDATE ,false));
      for (DN baseDN : backend.getBaseDNs()) {
        try {
          if (! backend.entryExists(baseDN))  {
opends/src/server/org/opends/server/authorization/dseecompat/GroupDN.java
@@ -148,7 +148,7 @@
        List<Attribute> attrs = e.getAttribute(attributeType);
        for(AttributeValue v : attrs.get(0)) {
            try {
                DN groupDN=DN.decode(v.getStringValue());
                DN groupDN=DN.decode(v.getValue().toString());
                if(suffixDN != null &&
                   !groupDN.isDescendantOf(suffixDN))
                        continue;
opends/src/server/org/opends/server/authorization/dseecompat/PatternDN.java
@@ -31,7 +31,6 @@
import org.opends.server.types.*;
import static org.opends.messages.SchemaMessages.*;
import static org.opends.messages.AccessControlMessages.*;
import org.opends.server.protocols.asn1.ASN1OctetString;
import static org.opends.server.util.StaticUtils.isDigit;
import static org.opends.server.util.StaticUtils.isHexDigit;
import static org.opends.server.util.StaticUtils.hexStringToByteArray;
@@ -448,7 +447,7 @@
      if (pos >= length)
      {
        ArrayList<ByteString> arrayList = new ArrayList<ByteString>(1);
        arrayList.add(new ASN1OctetString());
        arrayList.add(ByteString.empty());
        rdnComponents.add(new PatternRDN(name, arrayList, dnString));
        break;
      }
@@ -583,7 +582,7 @@
        if (pos >= length)
        {
          ArrayList<ByteString> arrayList = new ArrayList<ByteString>(1);
          arrayList.add(new ASN1OctetString());
          arrayList.add(ByteString.empty());
          rdn.addValue(name, arrayList, dnString);
          rdnComponents.add(rdn);
          break;
@@ -1198,7 +1197,7 @@
      try
      {
        byte[] bytes = hexStringToByteArray(hexString.toString());
        attributeValues.add(new ASN1OctetString(bytes));
        attributeValues.add(ByteString.wrap(bytes));
        return pos;
      }
      catch (Exception e)
@@ -1262,7 +1261,7 @@
        }
      }
      attributeValues.add(new ASN1OctetString(valueString.toString()));
      attributeValues.add(ByteString.valueOf(valueString.toString()));
      return pos;
    }
@@ -1281,7 +1280,7 @@
      else if (c == '*')
      {
        escaped = false;
        attributeValues.add(new ASN1OctetString(valueString.toString()));
        attributeValues.add(ByteString.valueOf(valueString.toString()));
      }
      else
      {
@@ -1379,7 +1378,7 @@
            throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
                                         message);
          }
          attributeValues.add(new ASN1OctetString(valueString.toString()));
          attributeValues.add(ByteString.valueOf(valueString.toString()));
          valueString = new StringBuilder();
          hexChars = new StringBuilder();
        }
@@ -1412,7 +1411,7 @@
      }
      attributeValues.add(new ASN1OctetString(valueString.toString()));
      attributeValues.add(ByteString.valueOf(valueString.toString()));
      return pos;
    }
  }
opends/src/server/org/opends/server/authorization/dseecompat/PatternRDN.java
@@ -273,13 +273,13 @@
        // Handle this just like a substring filter.
        ByteString subInitial = pattern.get(0);
        if (subInitial.value().length == 0)
        if (subInitial.length() == 0)
        {
          subInitial = null;
        }
        ByteString subFinal = pattern.get(pattern.size() - 1);
        if (subFinal.value().length == 0)
        if (subFinal.length() == 0)
        {
          subFinal = null;
        }
@@ -308,7 +308,8 @@
      }
      else
      {
        ByteString thisNormValue = type.normalize(pattern.get(0));
        ByteString thisNormValue =
            type.getEqualityMatchingRule().normalizeValue(pattern.get(0));
        ByteString thatNormValue = value.getNormalizedValue();
        EqualityMatchingRule mr = type.getEqualityMatchingRule();
        return mr.areEqual(thisNormValue, thatNormValue);
opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java
@@ -221,7 +221,7 @@
                        filter, null);
        LinkedList<SearchResultEntry> result = op.getSearchEntries();
        if (!result.isEmpty()) {
            AttributeValue val=new AttributeValue(attrType, attrVal);
            AttributeValue val= AttributeValues.create(attrType, attrVal);
            SearchResultEntry resultEntry = result.getFirst();
            if(resultEntry.hasValue(attrType, null, val)) {
                Entry e=evalCtx.getResourceEntry();
@@ -284,7 +284,7 @@
        if(!attrs.isEmpty()) {
            for(Attribute a : attrs) {
                for(AttributeValue v : a) {
                    String urlStr=v.getStringValue();
                    String urlStr=v.getValue().toString();
                    LDAPURL url;
                    try {
                       url=LDAPURL.decode(urlStr, true);
opends/src/server/org/opends/server/authorization/dseecompat/UserDN.java
@@ -361,7 +361,7 @@
        List<Attribute> attrs =  e.getAttribute(attrType);
        for(AttributeValue v : attrs.get(0)) {
            try {
                DN dn=DN.decode(v.getStringValue());
                DN dn=DN.decode(v.getValue().toString());
                if(dn.equals(clientDN)) {
                    matched=EnumEvalResult.TRUE;
                    break;
opends/src/server/org/opends/server/backends/BackupBackend.java
@@ -44,32 +44,7 @@
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.Attributes;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.BackupInfo;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LDIFImportResult;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.RDN;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
import org.opends.server.types.*;
import org.opends.server.schema.BooleanSyntax;
import org.opends.server.schema.GeneralizedTimeSyntax;
import org.opends.server.util.Validator;
@@ -446,7 +421,7 @@
          {
            BackupDirectory backupDirectory =
                BackupDirectory.readBackupDirectoryDescriptor(
                    v.getStringValue());
                    v.getValue().toString());
            count += backupDirectory.getBackups().keySet().size();
          }
          catch (Exception e)
@@ -555,7 +530,8 @@
    try
    {
      backupDirectory =
           BackupDirectory.readBackupDirectoryDescriptor(v.getStringValue());
           BackupDirectory.readBackupDirectoryDescriptor(
               v.getValue().toString());
    }
    catch (ConfigException ce)
    {
@@ -602,7 +578,7 @@
    t = DirectoryServer.getAttributeType(ATTR_BACKUP_BACKEND_DN, true);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(Attributes.create(t, new AttributeValue(t,
    attrList.add(Attributes.create(t, AttributeValues.create(t,
        backupDirectory.getConfigEntryDN().toString())));
    userAttrs.put(t, attrList);
@@ -637,7 +613,7 @@
          .valueOf(entryDN));
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
    }
    String backupID = idValue.getStringValue();
    String backupID = idValue.getValue().toString();
    // Next, get the backup directory from the parent DN.
    DN parentDN = entryDN.getParentDNInSuffix();
@@ -659,7 +635,7 @@
    BackupDirectory backupDirectory;
    try {
      backupDirectory = BackupDirectory.readBackupDirectoryDescriptor(v
          .getStringValue());
          .getValue().toString());
    } catch (ConfigException ce) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, ce);
@@ -716,7 +692,7 @@
    if (backupDate != null) {
      t = DirectoryServer.getAttributeType(ATTR_BACKUP_DATE, true);
      attrList = new ArrayList<Attribute>(1);
      attrList.add(Attributes.create(t, new AttributeValue(t,
      attrList.add(Attributes.create(t, AttributeValues.create(t,
          GeneralizedTimeSyntax.format(backupDate))));
      userAttrs.put(t, attrList);
    }
@@ -744,7 +720,7 @@
      t = DirectoryServer.getAttributeType(ATTR_BACKUP_DEPENDENCY, true);
      AttributeBuilder builder = new AttributeBuilder(t);
      for (String s : dependencies) {
        builder.add(new AttributeValue(t, s));
        builder.add(AttributeValues.create(t, s));
      }
      attrList = new ArrayList<Attribute>(1);
      attrList.add(builder.toAttribute());
@@ -755,8 +731,9 @@
    if (signedHash != null) {
      t = DirectoryServer.getAttributeType(ATTR_BACKUP_SIGNED_HASH, true);
      attrList = new ArrayList<Attribute>(1);
      attrList.add(Attributes.create(t, new AttributeValue(t,
          new ASN1OctetString(signedHash))));
      attrList.add(Attributes.create(t,
          AttributeValues.create(t,
              ByteString.wrap(signedHash))));
      userAttrs.put(t, attrList);
    }
@@ -764,8 +741,9 @@
    if (unsignedHash != null) {
      t = DirectoryServer.getAttributeType(ATTR_BACKUP_UNSIGNED_HASH, true);
      attrList = new ArrayList<Attribute>(1);
      attrList.add(Attributes.create(t, new AttributeValue(t,
          new ASN1OctetString(unsignedHash))));
      attrList.add(Attributes.create(t,
          AttributeValues.create(t,
              ByteString.wrap(unsignedHash))));
      userAttrs.put(t, attrList);
    }
@@ -774,7 +752,7 @@
      for (Map.Entry<String, String> e : properties.entrySet()) {
        t = DirectoryServer.getAttributeType(toLowerCase(e.getKey()), true);
        attrList = new ArrayList<Attribute>(1);
        attrList.add(Attributes.create(t, new AttributeValue(
        attrList.add(Attributes.create(t, AttributeValues.create(
            t, e.getValue())));
        userAttrs.put(t, attrList);
      }
@@ -919,7 +897,7 @@
                {
                  BackupDirectory backupDirectory =
                       BackupDirectory.readBackupDirectoryDescriptor(
                            v.getStringValue());
                            v.getValue().toString());
                  AttributeType idType =
                       DirectoryServer.getAttributeType(ATTR_BACKUP_ID,
                                                        true);
@@ -976,7 +954,7 @@
            {
              BackupDirectory backupDirectory =
                   BackupDirectory.readBackupDirectoryDescriptor(
                        v.getStringValue());
                        v.getValue().toString());
              AttributeType idType =
                   DirectoryServer.getAttributeType(ATTR_BACKUP_ID,
                                                    true);
@@ -1238,7 +1216,7 @@
                               String rdnStringValue)
  {
    AttributeValue attrValue =
         new AttributeValue(rdnAttrType, rdnStringValue);
        AttributeValues.create(rdnAttrType, rdnStringValue);
    return parentDN.concat(RDN.create(rdnAttrType, attrValue));
  }
opends/src/server/org/opends/server/backends/LDIFBackend.java
@@ -44,6 +44,7 @@
import org.opends.server.api.AlertGenerator;
import org.opends.server.api.Backend;
import org.opends.server.config.ConfigException;
import org.opends.server.controls.SubtreeDeleteControl;
import org.opends.server.core.AddOperation;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.DirectoryServer;
@@ -106,7 +107,7 @@
  private DN[] baseDNs;
  // The mapping between parent DNs and their immediate children.
  private HashMap<DN,HashSet<DN>> childDNs;
  private final HashMap<DN,HashSet<DN>> childDNs;
  // The base DNs for this backend, in a hash set.
  private HashSet<DN> baseDNSet;
@@ -121,10 +122,10 @@
  private LDIFBackendCfg currentConfig;
  // The mapping between entry DNs and the corresponding entries.
  private LinkedHashMap<DN,Entry> entryMap;
  private final LinkedHashMap<DN,Entry> entryMap;
  // A read-write lock used to protect access to this backend.
  private ReentrantReadWriteLock backendLock;
  private final ReentrantReadWriteLock backendLock;
  // The path to the LDIF file containing the data for this backend.
  private String ldifFilePath;
@@ -733,13 +734,12 @@
      else
      {
        boolean subtreeDelete = false;
        for (Control c : deleteOperation.getRequestControls())
        if (deleteOperation != null
            && deleteOperation
                .getRequestControl(SubtreeDeleteControl.DECODER) != null)
        {
          if (c.getOID().equals(OID_SUBTREE_DELETE_CONTROL))
          {
            subtreeDelete = true;
            break;
          }
          subtreeDelete = true;
        }
        if (! subtreeDelete)
@@ -1579,6 +1579,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void preloadEntryCache() throws UnsupportedOperationException {
    throw new UnsupportedOperationException("Operation not supported.");
  }
opends/src/server/org/opends/server/backends/MemoryBackend.java
@@ -39,6 +39,7 @@
import org.opends.server.admin.std.server.MemoryBackendCfg;
import org.opends.server.api.Backend;
import org.opends.server.config.ConfigException;
import org.opends.server.controls.SubtreeDeleteControl;
import org.opends.server.core.AddOperation;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.DirectoryServer;
@@ -475,15 +476,12 @@
    // Check to see if the entry contains a subtree delete control.
    boolean subtreeDelete = false;
    if (deleteOperation != null)
    if (deleteOperation != null
        && deleteOperation
            .getRequestControl(SubtreeDeleteControl.DECODER) != null)
    {
      for (Control c : deleteOperation.getRequestControls())
      {
        if (c.getOID().equals(OID_SUBTREE_DELETE_CONTROL))
        {
          subtreeDelete = true;
        }
      }
      subtreeDelete = true;
    }
    HashSet<DN> children = childDNs.get(entryDN);
@@ -989,6 +987,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void preloadEntryCache() throws UnsupportedOperationException {
    throw new UnsupportedOperationException("Operation not supported.");
  }
opends/src/server/org/opends/server/backends/MonitorBackend.java
@@ -432,7 +432,7 @@
    // Get the RDN value and see if it matches the instance name for one of
    // the directory server monitor providers.
    String rdnValue = entryRDN.getAttributeValue(0).getStringValue();
    String rdnValue = entryRDN.getAttributeValue(0).getValue().toString();
    MonitorProvider<? extends MonitorProviderCfg> monitorProvider =
         DirectoryServer.getMonitorProvider(rdnValue.toLowerCase());
    if (monitorProvider == null)
@@ -506,7 +506,7 @@
  public boolean entryExists(DN entryDN)
         throws DirectoryException
  {
      return this.isATreeNode(entryDN);
    return this.isATreeNode(entryDN);
  }
@@ -1295,6 +1295,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void preloadEntryCache() throws UnsupportedOperationException {
    throw new UnsupportedOperationException("Operation not supported.");
  }
opends/src/server/org/opends/server/backends/NullBackend.java
@@ -31,7 +31,6 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.opends.messages.Category;
import org.opends.messages.Message;
@@ -48,19 +47,16 @@
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.AttributeType;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.Control;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDAPException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LDIFImportResult;
@@ -80,34 +76,29 @@
/**
 * This class implements /dev/null like backend for development and testing.
 *
 * The following behaviors of this backend implementation should be noted:
 *
 * * All read operations return success but no data.
 *
 * * All write operations return success but do nothing.
 *
 * * Bind operations fail with invalid credentials.
 *
 * * Compare operations are only possible on objectclass and return true
 *   for the following objeclasses only: top, nullbackendobject,
 *   extensibleobject. Otherwise comparison result is false or comparison
 *   fails altogether.
 *
 * * Controls are supported although this implementation does not provide
 *   any specific emulation for controls. Generally known request controls
 *   are accepted and default response controls returned where applicable.
 *
 * * Searches within this backend are always considered indexed.
 *
 * * Backend Import is supported by iterating over ldif reader on a single
 *   thread and issuing add operations which essentially do nothing at all.
 *
 * * Backend Export is supported but does nothing producing an empty ldif.
 *
 * * Backend Backup and Restore are not supported.
 *
 * This class implements /dev/null like backend for development and
 * testing. The following behaviors of this backend implementation
 * should be noted:
 * <ul>
 * <li>All read operations return success but no data.
 * <li>All write operations return success but do nothing.
 * <li>Bind operations fail with invalid credentials.
 * <li>Compare operations are only possible on objectclass and return
 * true for the following objeclasses only: top, nullbackendobject,
 * extensibleobject. Otherwise comparison result is false or comparison
 * fails altogether.
 * <li>Controls are supported although this implementation does not
 * provide any specific emulation for controls. Generally known request
 * controls are accepted and default response controls returned where
 * applicable.
 * <li>Searches within this backend are always considered indexed.
 * <li>Backend Import is supported by iterating over ldif reader on a
 * single thread and issuing add operations which essentially do nothing
 * at all.
 * <li>Backend Export is supported but does nothing producing an empty
 * ldif.
 * <li>Backend Backup and Restore are not supported.
 * </ul>
 * This backend implementation is for development and testing only, does
 * not represent a complete and stable API, should be considered private
 * and subject to change without notice.
@@ -405,34 +396,14 @@
  public void search(SearchOperation searchOperation)
         throws DirectoryException
  {
    List<Control> controls = searchOperation.getRequestControls();
    PagedResultsControl pageRequest = null;
    if (controls != null) {
      for (Control control : controls) {
        if (control.getOID().equals(OID_PAGED_RESULTS_CONTROL)) {
          // Ignore all but the first paged results control.
          if (pageRequest == null) {
            try {
              pageRequest = new PagedResultsControl(control.isCritical(),
                control.getValue());
            } catch (LDAPException e) {
              if (debugEnabled()) {
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
              }
              throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
                e.getMessageObject(), e);
            }
          }
        }
      }
    }
    PagedResultsControl pageRequest =
        searchOperation.getRequestControl(PagedResultsControl.DECODER);
    if (pageRequest != null) {
      // Indicate no more pages.
      PagedResultsControl control;
      control = new PagedResultsControl(pageRequest.isCritical(), 0,
        new ASN1OctetString());
      control =
          new PagedResultsControl(pageRequest.isCritical(), 0, null);
      searchOperation.getResponseControls().add(control);
    }
@@ -659,6 +630,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void preloadEntryCache() throws UnsupportedOperationException {
    throw new UnsupportedOperationException("Operation not supported.");
  }
opends/src/server/org/opends/server/backends/RootDSEBackend.java
@@ -54,7 +54,6 @@
import org.opends.server.core.WorkflowTopologyNode;
import org.opends.server.core.networkgroups.NetworkGroup;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.*;
import org.opends.server.util.LDIFWriter;
import org.opends.server.util.Validator;
@@ -838,7 +837,7 @@
    AttributeBuilder builder = new AttributeBuilder(type, name);
    for (DN dn : values) {
      builder.add(
          new AttributeValue(type, new ASN1OctetString(dn.toString())));
          AttributeValues.create(type, dn.toString()));
    }
    return builder.toAttribute();
@@ -871,7 +870,7 @@
    AttributeBuilder builder = new AttributeBuilder(type, name);
    builder.setInitialCapacity(values.size());
    for (String s : values) {
      builder.add(new AttributeValue(type, new ASN1OctetString(s)));
      builder.add(AttributeValues.create(type, s));
    }
    return builder.toAttribute();
opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -74,7 +74,6 @@
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.ErrorLogger;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.schema.AttributeTypeSyntax;
import org.opends.server.schema.DITContentRuleSyntax;
import org.opends.server.schema.DITStructureRuleSyntax;
@@ -301,9 +300,11 @@
    cfg.getBaseDN().toArray(baseDNs);
    this.baseDNs = baseDNs;
    creatorsName  = new AttributeValue(creatorsNameType, baseDNs[0].toString());
    creatorsName  = AttributeValues.create(
        creatorsNameType, baseDNs[0].toString());
    modifiersName =
         new AttributeValue(modifiersNameType, baseDNs[0].toString());
        AttributeValues.create(
            modifiersNameType, baseDNs[0].toString());
    long createTime = DirectoryServer.getSchema().getOldestModificationTime();
    createTimestamp =
@@ -715,8 +716,9 @@
              value.getValue(), schema, false);
          attrType = DirectoryServer.getAttributeType(attrType.getOID());
          newValueSet.add(new AttributeValue(attributeTypesType, attrType
              .getDefinitionWithFileName()));
          newValueSet.add(
              AttributeValues.create(attributeTypesType,
                  attrType.getDefinitionWithFileName()));
        }
        catch (DirectoryException e)
        {
@@ -741,8 +743,8 @@
          // add it to the valueset.
          String strippedStr = v.toString().replaceFirst(
              stripMinUpperBoundRegEx, "");
          ASN1OctetString s = new ASN1OctetString(strippedStr);
          AttributeValue strippedVal = new AttributeValue(s, s);
          ByteString s = ByteString.valueOf(strippedStr);
          AttributeValue strippedVal = AttributeValues.create(s, s);
          builder.add(strippedVal);
        }
        else
@@ -787,8 +789,8 @@
          ObjectClass oc = ObjectClassSyntax.decodeObjectClass(
              value.getValue(), schema, false);
          oc = DirectoryServer.getObjectClass(oc.getOID());
          newValueSet.add(new AttributeValue(objectClassesType, oc
              .getDefinitionWithFileName()));
          newValueSet.add(AttributeValues.create(
              objectClassesType, oc.getDefinitionWithFileName()));
        }
        catch (DirectoryException e)
        {
@@ -1123,7 +1125,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_ATTRTYPE.get(
                    v.getStringValue(), de.getMessageObject());
                    v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1150,7 +1152,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_OBJECTCLASS.
                    get(v.getStringValue(), de.getMessageObject());
                    get(v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1177,7 +1179,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_NAME_FORM.get(
                    v.getStringValue(), de.getMessageObject());
                    v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1204,7 +1206,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_DCR.get(
                    v.getStringValue(), de.getMessageObject());
                    v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1231,7 +1233,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_DSR.get(
                    v.getStringValue(), de.getMessageObject());
                    v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1258,7 +1260,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_MR_USE.get(
                    v.getStringValue(), de.getMessageObject());
                    v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1305,7 +1307,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_ATTRTYPE.get(
                    v.getStringValue(), de.getMessageObject());
                    v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1333,7 +1335,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_OBJECTCLASS.
                    get(v.getStringValue(), de.getMessageObject());
                    get(v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1360,7 +1362,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_NAME_FORM.get(
                    v.getStringValue(), de.getMessageObject());
                    v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1387,7 +1389,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_DCR.get(
                    v.getStringValue(), de.getMessageObject());
                    v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1415,7 +1417,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_DSR.get(
                    v.getStringValue(), de.getMessageObject());
                    v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1443,7 +1445,7 @@
                }
                Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_MR_USE.get(
                    v.getStringValue(), de.getMessageObject());
                    v.getValue().toString(), de.getMessageObject());
                throw new DirectoryException(
                               ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                               de);
@@ -1496,7 +1498,8 @@
      authzDN = DN.nullDN();
    }
    modifiersName = new AttributeValue(modifiersNameType, authzDN.toString());
    modifiersName = AttributeValues.create(
        modifiersNameType, authzDN.toString());
    modifyTimestamp = GeneralizedTimeSyntax.createGeneralizedTimeValue(
                           System.currentTimeMillis());
  }
@@ -1797,7 +1800,7 @@
          }
          Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_ATTRTYPE.get(
              v.getStringValue(), de.getMessageObject());
              v.getValue().toString(), de.getMessageObject());
          throw new DirectoryException(
                         ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                         de);
@@ -2123,7 +2126,7 @@
          }
          Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_OBJECTCLASS.get(
              v.getStringValue(), de.getMessageObject());
              v.getValue().toString(), de.getMessageObject());
          throw new DirectoryException(
                         ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                         de);
@@ -2428,7 +2431,7 @@
          }
          Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_NAME_FORM.get(
              v.getStringValue(), de.getMessageObject());
              v.getValue().toString(), de.getMessageObject());
          throw new DirectoryException(
                         ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                         de);
@@ -2959,7 +2962,7 @@
          }
          Message message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_DSR.get(
              v.getStringValue(), de.getMessageObject());
              v.getValue().toString(), de.getMessageObject());
          throw new DirectoryException(
                         ResultCode.INVALID_ATTRIBUTE_SYNTAX, message,
                         de);
@@ -3331,7 +3334,8 @@
    {
      if (schemaFile.equals(nf.getSchemaFile()))
      {
        values.add(new AttributeValue(nameFormsType, nf.getDefinition()));
        values.add(AttributeValues.create(
            nameFormsType, nf.getDefinition()));
      }
    }
@@ -3353,7 +3357,7 @@
    {
      if (schemaFile.equals(dcr.getSchemaFile()))
      {
        values.add(new AttributeValue(ditContentRulesType,
        values.add(AttributeValues.create(ditContentRulesType,
                                      dcr.getDefinition()));
      }
    }
@@ -3400,7 +3404,7 @@
    {
      if (schemaFile.equals(mru.getSchemaFile()))
      {
        values.add(new AttributeValue(matchingRuleUsesType,
        values.add(AttributeValues.create(matchingRuleUsesType,
                                      mru.getDefinition()));
      }
    }
@@ -3483,7 +3487,7 @@
                              addedTypes, depth+1);
    }
    values.add(new AttributeValue(attributeTypesType,
    values.add(AttributeValues.create(attributeTypesType,
                                  attributeType.getDefinition()));
    addedTypes.add(attributeType);
  }
@@ -3534,7 +3538,7 @@
                                 addedClasses, depth+1);
    }
    values.add(new AttributeValue(objectClassesType,
    values.add(AttributeValues.create(objectClassesType,
                                  objectClass.getDefinition()));
    addedClasses.add(objectClass);
  }
@@ -3585,7 +3589,7 @@
      }
    }
    values.add(new AttributeValue(ditStructureRulesType,
    values.add(AttributeValues.create(ditStructureRulesType,
                                  ditStructureRule.getDefinition()));
    addedDSRs.add(ditStructureRule);
  }
opends/src/server/org/opends/server/backends/TrustStoreBackend.java
@@ -75,33 +75,7 @@
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.ErrorLogger;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.Attributes;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DN;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.FilePermission;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LDIFImportResult;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.RDN;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
import org.opends.server.types.*;
import org.opends.server.util.CertificateManager;
import org.opends.server.util.Validator;
@@ -581,7 +555,7 @@
                                   baseDN, null);
    }
    String certAlias = v.getStringValue();
    String certAlias = v.getValue().toString();
    ByteString certValue;
    try
    {
@@ -592,7 +566,7 @@
            String.valueOf(entryDN), certAlias);
        throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message);
      }
      certValue = new ASN1OctetString(cert.getEncoded());
      certValue = ByteString.wrap(cert.getEncoded());
    }
    catch (Exception e)
    {
@@ -630,7 +604,7 @@
        true);
    AttributeBuilder builder = new AttributeBuilder(t);
    builder.setOption("binary");
    builder.add(new AttributeValue(t, certValue));
    builder.add(AttributeValues.create(t, certValue));
    attrList = new ArrayList<Attribute>(1);
    attrList.add(builder.toAttribute());
    userAttrs.put(t, attrList);
@@ -1370,7 +1344,7 @@
                               String rdnStringValue)
  {
    AttributeValue attrValue =
         new AttributeValue(rdnAttrType, rdnStringValue);
        AttributeValues.create(rdnAttrType, rdnStringValue);
    return parentDN.concat(RDN.create(rdnAttrType, attrValue));
  }
@@ -1575,7 +1549,7 @@
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                   baseDN, null);
    }
    String certAlias = v.getStringValue();
    String certAlias = v.getValue().toString();
    try
    {
@@ -1642,7 +1616,7 @@
               DirectoryServer.getServerErrorResultCode(), message);
        }
        byte[] certBytes = i.next().getValueBytes();
        ByteString certBytes = i.next().getValue();
        if (i.hasNext())
        {
@@ -1665,7 +1639,7 @@
                 new FileOutputStream(tempFile.getPath(), false);
            try
            {
              outputStream.write(certBytes);
              certBytes.copyTo(outputStream);
            }
            finally
            {
@@ -1713,7 +1687,7 @@
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
                                   baseDN, null);
    }
    String certAlias = v.getStringValue();
    String certAlias = v.getValue().toString();
    try
    {
opends/src/server/org/opends/server/backends/jeb/ApproximateIndexer.java
@@ -165,7 +165,7 @@
        try
        {
          byte[] keyBytes =
               approximateRule.normalizeValue(value.getValue()).value();
               approximateRule.normalizeValue(value.getValue()).toByteArray();
          keys.add(keyBytes);
        }
@@ -201,7 +201,7 @@
        try
        {
          byte[] keyBytes =
              approximateRule.normalizeValue(value.getValue()).value();
              approximateRule.normalizeValue(value.getValue()).toByteArray();
          Boolean cInsert = modifiedKeys.get(keyBytes);
          if(cInsert == null)
opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java
@@ -34,7 +34,6 @@
import org.opends.server.api.SubstringMatchingRule;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.api.ApproximateMatchingRule;
import org.opends.server.protocols.asn1.ASN1OctetString;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
@@ -797,7 +796,7 @@
    {
      int len = Math.min(substrLength, remain);
      keyBytes = makeSubstringKey(value, i, len);
      set.add(new ASN1OctetString(keyBytes));
      set.add(ByteString.wrap(keyBytes));
    }
    return set;
@@ -947,7 +946,7 @@
    {
      // Make a key from the normalized assertion value.
      byte[] keyBytes =
           equalityFilter.getAssertionValue().getNormalizedValue().value();
          equalityFilter.getAssertionValue().getNormalizedValue().toByteArray();
      DatabaseEntry key = new DatabaseEntry(keyBytes);
      if(debugBuffer != null)
@@ -1026,7 +1025,7 @@
      OrderingMatchingRule orderingRule =
           filter.getAttributeType().getOrderingMatchingRule();
      byte[] lower = orderingRule.normalizeValue(
           filter.getAssertionValue().getValue()).value();
           filter.getAssertionValue().getValue()).toByteArray();
      // Set the upper bound to 0 to search all keys greater then the lower
      // bound.
@@ -1082,7 +1081,7 @@
      OrderingMatchingRule orderingRule =
           filter.getAttributeType().getOrderingMatchingRule();
      byte[] upper = orderingRule.normalizeValue(
           filter.getAssertionValue().getValue()).value();
           filter.getAssertionValue().getValue()).toByteArray();
      if(debugBuffer != null)
      {
@@ -1133,7 +1132,7 @@
        {
          ByteString normValue =
               matchRule.normalizeSubstring(filter.getSubInitialElement());
          byte[] normBytes = normValue.value();
          byte[] normBytes = normValue.toByteArray();
          EntryIDSet list = matchInitialSubstring(normBytes);
          results.retainAll(list);
@@ -1178,7 +1177,7 @@
      {
        // Normalize the substring according to the substring matching rule.
        ByteString normValue = matchRule.normalizeSubstring(element);
        byte[] normBytes = normValue.value();
        byte[] normBytes = normValue.toByteArray();
        // Get the candidate entry IDs from the index.
        EntryIDSet list = matchSubstring(normBytes);
@@ -1240,10 +1239,12 @@
           getAttributeType().getOrderingMatchingRule();
      // Set the lower bound for a range search.
      byte[] lower = orderingRule.normalizeValue(lowerValue.getValue()).value();
      byte[] lower =
          orderingRule.normalizeValue(lowerValue.getValue()).toByteArray();
      // Set the upper bound for a range search.
      byte[] upper = orderingRule.normalizeValue(upperValue.getValue()).value();
      byte[] upper =
          orderingRule.normalizeValue(upperValue.getValue()).toByteArray();
      // Read the range: lower <= keys <= upper.
      return orderingIndex.readRange(lower, upper, true, true);
@@ -1329,7 +1330,7 @@
      // Make a key from the normalized assertion value.
      byte[] keyBytes =
           approximateMatchingRule.normalizeValue(
               approximateFilter.getAssertionValue().getValue()).value();
               approximateFilter.getAssertionValue().getValue()).toByteArray();
      DatabaseEntry key = new DatabaseEntry(keyBytes);
      if(debugBuffer != null)
opends/src/server/org/opends/server/backends/jeb/DN2URI.java
@@ -33,20 +33,7 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDAPURL;
import org.opends.server.types.Modification;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchResultReference;
import org.opends.server.types.SearchScope;
import org.opends.server.types.*;
import org.opends.server.util.StaticUtils;
import java.io.UnsupportedEncodingException;
@@ -315,7 +302,7 @@
            {
              for (AttributeValue v : a)
              {
                insert(txn, entryDN, v.getStringValue());
                insert(txn, entryDN, v.getValue().toString());
              }
            }
            break;
@@ -329,7 +316,7 @@
            {
              for (AttributeValue v : a)
              {
                delete(txn, entryDN, v.getStringValue());
                delete(txn, entryDN, v.getValue().toString());
              }
            }
            break;
@@ -344,7 +331,7 @@
            {
              for (AttributeValue v : a)
              {
                insert(txn, entryDN, v.getStringValue());
                insert(txn, entryDN, v.getValue().toString());
              }
            }
            break;
@@ -679,7 +666,7 @@
          }
          // We have found a subordinate referral.
          DN dn = DN.decode(new ASN1OctetString(key.getData()));
          DN dn = DN.decode(ByteString.wrap(key.getData()));
          // Make sure the referral is within scope.
          if (searchOp.getScope() == SearchScope.SINGLE_LEVEL)
opends/src/server/org/opends/server/backends/jeb/EntryCachePreloader.java
@@ -51,6 +51,7 @@
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.Entry;
import org.opends.server.types.ByteString;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.loggers.ErrorLogger.logError;
@@ -291,7 +292,7 @@
          long entryID =
            JebFormat.entryIDFromDatabase(preloadEntry.entryIDBytes);
          Entry entry =
            JebFormat.entryFromDatabase(preloadEntry.entryBytes,
            ID2Entry.entryFromDatabase(ByteString.wrap(preloadEntry.entryBytes),
            jeb.getRootContainer().getCompressedSchema());
          try {
            // Even if the entry does not end up in the cache its still
opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -38,11 +38,11 @@
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.controls.PagedResultsControl;
import org.opends.server.controls.ServerSideSortRequestControl;
import org.opends.server.controls.ServerSideSortResponseControl;
import org.opends.server.controls.SubtreeDeleteControl;
import org.opends.server.controls.VLVRequestControl;
import org.opends.server.types.*;
import org.opends.server.util.StaticUtils;
@@ -59,7 +59,6 @@
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.util.ServerConstants.*;
import org.opends.server.admin.std.server.LocalDBBackendCfg;
import org.opends.server.admin.std.server.LocalDBIndexCfg;
import org.opends.server.admin.std.server.LocalDBVLVIndexCfg;
@@ -74,7 +73,7 @@
 * the guts of the backend API methods for LDAP operations.
 */
public class EntryContainer
    implements ConfigurationChangeListener<LocalDBBackendCfg>
implements ConfigurationChangeListener<LocalDBBackendCfg>
{
  /**
   * The tracer object for the debug logger.
@@ -130,17 +129,17 @@
  /**
   * The backend to which this entry entryContainer belongs.
   */
  private Backend backend;
  private final Backend backend;
  /**
   * The root container in which this entryContainer belongs.
   */
  private RootContainer rootContainer;
  private final RootContainer rootContainer;
  /**
   * The baseDN this entry container is responsible for.
   */
  private DN baseDN;
  private final DN baseDN;
  /**
   * The backend configuration.
@@ -150,7 +149,7 @@
  /**
   * The JE database environment.
   */
  private Environment env;
  private final Environment env;
  /**
   * The DN database maps a normalized DN string to an entry ID (8 bytes).
@@ -185,12 +184,12 @@
  /**
   * The set of attribute indexes.
   */
  private HashMap<AttributeType, AttributeIndex> attrIndexMap;
  private final HashMap<AttributeType, AttributeIndex> attrIndexMap;
  /**
   * The set of VLV indexes.
   */
  private HashMap<String, VLVIndex> vlvIndexMap;
  private final HashMap<String, VLVIndex> vlvIndexMap;
  private String databasePrefix;
  /**
@@ -198,15 +197,15 @@
   * indexes used within this entry container.
   */
  public class AttributeJEIndexCfgManager implements
      ConfigurationAddListener<LocalDBIndexCfg>,
      ConfigurationDeleteListener<LocalDBIndexCfg>
  ConfigurationAddListener<LocalDBIndexCfg>,
  ConfigurationDeleteListener<LocalDBIndexCfg>
  {
    /**
     * {@inheritDoc}
     */
    public boolean isConfigurationAddAcceptable(
            LocalDBIndexCfg cfg,
            List<Message> unacceptableReasons)
        LocalDBIndexCfg cfg,
        List<Message> unacceptableReasons)
    {
      // TODO: validate more before returning true?
      return true;
@@ -224,7 +223,7 @@
      try
      {
        AttributeIndex index =
            new AttributeIndex(cfg, state, env, EntryContainer.this);
          new AttributeIndex(cfg, state, env, EntryContainer.this);
        index.open();
        if(!index.isTrusted())
        {
@@ -238,13 +237,13 @@
      {
        messages.add(Message.raw(StaticUtils.stackTraceToSingleLineString(e)));
        ccr = new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(),
                                     adminActionRequired,
                                     messages);
            adminActionRequired,
            messages);
        return ccr;
      }
      return new ConfigChangeResult(ResultCode.SUCCESS, adminActionRequired,
                                    messages);
          messages);
    }
    /**
@@ -277,8 +276,8 @@
      {
        messages.add(Message.raw(StaticUtils.stackTraceToSingleLineString(de)));
        ccr = new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(),
                                     adminActionRequired,
                                     messages);
            adminActionRequired,
            messages);
        return ccr;
      }
      finally
@@ -287,7 +286,7 @@
      }
      return new ConfigChangeResult(ResultCode.SUCCESS, adminActionRequired,
                                    messages);
          messages);
    }
  }
@@ -296,8 +295,8 @@
   * used within this entry container.
   */
  public class VLVJEIndexCfgManager implements
      ConfigurationAddListener<LocalDBVLVIndexCfg>,
      ConfigurationDeleteListener<LocalDBVLVIndexCfg>
  ConfigurationAddListener<LocalDBVLVIndexCfg>,
  ConfigurationDeleteListener<LocalDBVLVIndexCfg>
  {
    /**
     * {@inheritDoc}
@@ -321,7 +320,7 @@
      String[] sortAttrs = cfg.getSortOrder().split(" ");
      SortKey[] sortKeys = new SortKey[sortAttrs.length];
      OrderingMatchingRule[] orderingRules =
          new OrderingMatchingRule[sortAttrs.length];
        new OrderingMatchingRule[sortAttrs.length];
      boolean[] ascending = new boolean[sortAttrs.length];
      for(int i = 0; i < sortAttrs.length; i++)
      {
@@ -344,14 +343,14 @@
        catch(Exception e)
        {
          Message msg =
              ERR_JEB_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(
                  String.valueOf(sortKeys[i]), cfg.getName());
            ERR_JEB_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(
                String.valueOf(sortKeys[i]), cfg.getName());
          unacceptableReasons.add(msg);
          return false;
        }
        AttributeType attrType =
            DirectoryServer.getAttributeType(sortAttrs[i].toLowerCase());
          DirectoryServer.getAttributeType(sortAttrs[i].toLowerCase());
        if(attrType == null)
        {
          Message msg = ERR_JEB_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(
@@ -391,21 +390,21 @@
      {
        messages.add(Message.raw(StaticUtils.stackTraceToSingleLineString(e)));
        ccr = new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(),
                                     adminActionRequired,
                                     messages);
            adminActionRequired,
            messages);
        return ccr;
      }
      return new ConfigChangeResult(ResultCode.SUCCESS, adminActionRequired,
                                    messages);
          messages);
    }
    /**
     * {@inheritDoc}
     */
    public boolean isConfigurationDeleteAcceptable(
            LocalDBVLVIndexCfg cfg,
            List<Message> unacceptableReasons)
        LocalDBVLVIndexCfg cfg,
        List<Message> unacceptableReasons)
    {
      // TODO: validate more before returning true?
      return true;
@@ -424,7 +423,7 @@
      try
      {
        VLVIndex vlvIndex =
            vlvIndexMap.get(cfg.getName().toLowerCase());
          vlvIndexMap.get(cfg.getName().toLowerCase());
        vlvIndex.close();
        deleteDatabase(vlvIndex);
        vlvIndexMap.remove(cfg.getName());
@@ -433,8 +432,8 @@
      {
        messages.add(Message.raw(StaticUtils.stackTraceToSingleLineString(de)));
        ccr = new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(),
                                     adminActionRequired,
                                     messages);
            adminActionRequired,
            messages);
        return ccr;
      }
      finally
@@ -443,7 +442,7 @@
      }
      return new ConfigChangeResult(ResultCode.SUCCESS, adminActionRequired,
                                    messages);
          messages);
    }
  }
@@ -471,9 +470,9 @@
   * @throws ConfigException if a configuration related error occurs.
   */
  public EntryContainer(DN baseDN, String databasePrefix, Backend backend,
                        LocalDBBackendCfg config, Environment env,
                        RootContainer rootContainer)
      throws ConfigException
      LocalDBBackendCfg config, Environment env,
      RootContainer rootContainer)
  throws ConfigException
  {
    this.backend = backend;
    this.baseDN = baseDN;
@@ -505,12 +504,12 @@
    config.addLocalDBChangeListener(this);
    attributeJEIndexCfgManager =
        new AttributeJEIndexCfgManager();
      new AttributeJEIndexCfgManager();
    config.addLocalDBIndexAddListener(attributeJEIndexCfgManager);
    config.addLocalDBIndexDeleteListener(attributeJEIndexCfgManager);
    vlvJEIndexCfgManager =
        new VLVJEIndexCfgManager();
      new VLVJEIndexCfgManager();
    config.addLocalDBVLVIndexAddListener(vlvJEIndexCfgManager);
    config.addLocalDBVLVIndexDeleteListener(vlvJEIndexCfgManager);
  }
@@ -522,17 +521,17 @@
   * @throws ConfigException if a configuration related error occurs.
   */
  public void open()
      throws DatabaseException, ConfigException
  throws DatabaseException, ConfigException
  {
    try
    {
      DataConfig entryDataConfig =
          new DataConfig(config.isEntriesCompressed(),
                         config.isCompactEncoding(),
                         rootContainer.getCompressedSchema());
        new DataConfig(config.isEntriesCompressed(),
            config.isCompactEncoding(),
            rootContainer.getCompressedSchema());
      id2entry = new ID2Entry(databasePrefix + "_" + ID2ENTRY_DATABASE_NAME,
                              entryDataConfig, env, this);
          entryDataConfig, env, this);
      id2entry.open();
      dn2id = new DN2ID(databasePrefix + "_" + DN2ID_DATABASE_NAME, env, this);
@@ -542,9 +541,9 @@
      state.open();
      id2children = new Index(databasePrefix + "_" + ID2CHILDREN_DATABASE_NAME,
                              new ID2CIndexer(), state,
                              config.getIndexEntryLimit(), 0, true,
                              env,this);
          new ID2CIndexer(), state,
          config.getIndexEntryLimit(), 0, true,
          env,this);
      id2children.open();
      if(!id2children.isTrusted())
@@ -554,9 +553,9 @@
      }
      id2subtree = new Index(databasePrefix + "_" + ID2SUBTREE_DATABASE_NAME,
                             new ID2SIndexer(), state,
                             config.getIndexEntryLimit(), 0, true,
                             env, this);
          new ID2SIndexer(), state,
          config.getIndexEntryLimit(), 0, true,
          env, this);
      id2subtree.open();
      if(!id2subtree.isTrusted())
@@ -566,7 +565,7 @@
      }
      dn2uri = new DN2URI(databasePrefix + "_" + REFERRAL_DATABASE_NAME,
                          env, this);
          env, this);
      dn2uri.open();
      for (String idx : config.listLocalDBIndexes())
@@ -574,7 +573,7 @@
        LocalDBIndexCfg indexCfg = config.getLocalDBIndex(idx);
        AttributeIndex index =
            new AttributeIndex(indexCfg, state, env, this);
          new AttributeIndex(indexCfg, state, env, this);
        index.open();
        if(!index.isTrusted())
        {
@@ -617,7 +616,7 @@
   * @throws DatabaseException If an error occurs in the JE database.
   */
  public void close()
      throws DatabaseException
  throws DatabaseException
  {
    // Close core indexes.
    dn2id.close();
@@ -819,13 +818,13 @@
   * @throws DatabaseException If an error occurs in the JE database.
   */
  public long getNumSubordinates(DN entryDN, boolean subtree)
      throws DatabaseException
  throws DatabaseException
  {
    EntryID entryID = dn2id.get(null, entryDN, LockMode.DEFAULT);
    if (entryID != null)
    {
      DatabaseEntry key =
          new DatabaseEntry(JebFormat.entryIDToDatabase(entryID.longValue()));
        new DatabaseEntry(JebFormat.entryIDToDatabase(entryID.longValue()));
      EntryIDSet entryIDSet;
      if(!subtree)
      {
@@ -857,97 +856,22 @@
   * @throws CanceledOperationException if this operation should be cancelled.
   */
  public void search(SearchOperation searchOperation)
       throws DirectoryException, DatabaseException, CanceledOperationException
  throws DirectoryException, DatabaseException, CanceledOperationException
  {
    DN baseDN = searchOperation.getBaseDN();
    SearchScope searchScope = searchOperation.getScope();
    List<Control> controls = searchOperation.getRequestControls();
    PagedResultsControl pageRequest = null;
    ServerSideSortRequestControl sortRequest = null;
    VLVRequestControl vlvRequest = null;
    if (controls != null)
    PagedResultsControl pageRequest = searchOperation
    .getRequestControl(PagedResultsControl.DECODER);
    ServerSideSortRequestControl sortRequest = searchOperation
    .getRequestControl(ServerSideSortRequestControl.DECODER);
    VLVRequestControl vlvRequest = searchOperation
    .getRequestControl(VLVRequestControl.DECODER);
    if (vlvRequest != null && pageRequest != null)
    {
      for (Control control : controls)
      {
        if (control.getOID().equals(OID_PAGED_RESULTS_CONTROL))
        {
          // Ignore all but the first paged results control.
          if (pageRequest == null)
          {
            try
            {
              pageRequest = new PagedResultsControl(control.isCritical(),
                                                    control.getValue());
            }
            catch (LDAPException e)
            {
              if (debugEnabled())
              {
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
              }
              throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
                                           e.getMessageObject(), e);
            }
            if (vlvRequest != null)
            {
              Message message =
                  ERR_JEB_SEARCH_CANNOT_MIX_PAGEDRESULTS_AND_VLV.get();
              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                           message);
            }
          }
        }
        else if (control.getOID().equals(OID_SERVER_SIDE_SORT_REQUEST_CONTROL))
        {
          // Ignore all but the first sort request control.
          if (sortRequest == null)
          {
            try
            {
              sortRequest = ServerSideSortRequestControl.decodeControl(control);
            }
            catch (LDAPException e)
            {
              if (debugEnabled())
              {
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
              }
              throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
                                           e.getMessageObject(), e);
            }
          }
        }
        else if (control.getOID().equals(OID_VLV_REQUEST_CONTROL))
        {
          // Ignore all but the first VLV request control.
          if (vlvRequest == null)
          {
            try
            {
              vlvRequest = VLVRequestControl.decodeControl(control);
            }
            catch (LDAPException e)
            {
              if (debugEnabled())
              {
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
              }
              throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
                                           e.getMessageObject(), e);
            }
            if (pageRequest != null)
            {
              Message message =
                  ERR_JEB_SEARCH_CANNOT_MIX_PAGEDRESULTS_AND_VLV.get();
              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                           message);
            }
          }
        }
      }
      Message message = ERR_JEB_SEARCH_CANNOT_MIX_PAGEDRESULTS_AND_VLV.get();
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
    }
    // Handle client abandon of paged results.
@@ -956,8 +880,7 @@
      if (pageRequest.getSize() == 0)
      {
        PagedResultsControl control;
        control = new PagedResultsControl(pageRequest.isCritical(), 0,
                                          new ASN1OctetString());
        control = new PagedResultsControl(pageRequest.isCritical(), 0, null);
        searchOperation.getResponseControls().add(control);
        return;
      }
@@ -1006,8 +929,7 @@
      {
        // Indicate no more pages.
        PagedResultsControl control;
        control = new PagedResultsControl(pageRequest.isCritical(), 0,
                                          new ASN1OctetString());
        control = new PagedResultsControl(pageRequest.isCritical(), 0, null);
        searchOperation.getResponseControls().add(control);
      }
@@ -1031,13 +953,13 @@
        try
        {
          entryIDList =
              vlvIndex.evaluate(null, searchOperation, sortRequest, vlvRequest,
                                debugBuffer);
            vlvIndex.evaluate(null, searchOperation, sortRequest, vlvRequest,
                debugBuffer);
          if(entryIDList != null)
          {
            searchOperation.addResponseControl(
                new ServerSideSortResponseControl(LDAPResultCode.SUCCESS,
                                                  null));
                    null));
            candidatesAreInScope = true;
            break;
          }
@@ -1060,7 +982,7 @@
    {
      // Create an index filter to get the search result candidate entries.
      IndexFilter indexFilter =
          new IndexFilter(this, searchOperation, debugBuffer);
        new IndexFilter(this, searchOperation, debugBuffer);
      // Evaluate the filter against the attribute indexes.
      entryIDList = indexFilter.evaluate();
@@ -1074,7 +996,7 @@
        if (baseID == null)
        {
          Message message =
                  ERR_JEB_SEARCH_NO_SUCH_OBJECT.get(baseDN.toString());
            ERR_JEB_SEARCH_NO_SUCH_OBJECT.get(baseDN.toString());
          DN matchedDN = getMatchedDN(baseDN);
          throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
              message, matchedDN, null);
@@ -1114,9 +1036,9 @@
        try
        {
          entryIDList = EntryIDSetSorter.sort(this, entryIDList,
                                              searchOperation,
                                              sortRequest.getSortOrder(),
                                              vlvRequest);
              searchOperation,
              sortRequest.getSortOrder(),
              vlvRequest);
          searchOperation.addResponseControl(
              new ServerSideSortResponseControl(LDAPResultCode.SUCCESS, null));
        }
@@ -1155,7 +1077,7 @@
    if (entryIDList.isDefined())
    {
      searchIndexed(entryIDList, candidatesAreInScope, searchOperation,
                    pageRequest);
          pageRequest);
    }
    else
    {
@@ -1170,14 +1092,14 @@
      }
      ClientConnection clientConnection =
          searchOperation.getClientConnection();
        searchOperation.getClientConnection();
      if(! clientConnection.hasPrivilege(Privilege.UNINDEXED_SEARCH,
                                         searchOperation))
          searchOperation))
      {
        Message message =
            ERR_JEB_SEARCH_UNINDEXED_INSUFFICIENT_PRIVILEGES.get();
          ERR_JEB_SEARCH_UNINDEXED_INSUFFICIENT_PRIVILEGES.get();
        throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
                                     message);
            message);
      }
      if (sortRequest != null)
@@ -1185,14 +1107,14 @@
        // FIXME -- Add support for sorting unindexed searches using indexes
        //          like DSEE currently does.
        searchOperation.addResponseControl(
             new ServerSideSortResponseControl(
                      LDAPResultCode.UNWILLING_TO_PERFORM, null));
            new ServerSideSortResponseControl(
                LDAPResultCode.UNWILLING_TO_PERFORM, null));
        if (sortRequest.isCritical())
        {
          Message message = ERR_JEB_SEARCH_CANNOT_SORT_UNINDEXED.get();
          throw new DirectoryException(
                         ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, message);
              ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, message);
        }
      }
@@ -1219,8 +1141,8 @@
   * processed.
   */
  private void searchNotIndexed(SearchOperation searchOperation,
                                PagedResultsControl pageRequest)
       throws DirectoryException, CanceledOperationException
      PagedResultsControl pageRequest)
  throws DirectoryException, CanceledOperationException
  {
    EntryCache<?> entryCache = DirectoryServer.getEntryCache();
    DN baseDN = searchOperation.getBaseDN();
@@ -1230,7 +1152,7 @@
    // The base entry must already have been processed if this is
    // a request for the next page in paged results.  So we skip
    // the base entry processing if the cookie is set.
    if (pageRequest == null || pageRequest.getCookie().value().length == 0)
    if (pageRequest == null || pageRequest.getCookie().length() == 0)
    {
      // Fetch the base entry.
      Entry baseEntry = null;
@@ -1284,7 +1206,7 @@
            // Indicate no more pages.
            PagedResultsControl control;
            control = new PagedResultsControl(pageRequest.isCritical(), 0,
                                              new ASN1OctetString());
                null);
            searchOperation.getResponseControls().add(control);
          }
        }
@@ -1312,7 +1234,7 @@
    // Set the starting value.
    byte[] begin;
    if (pageRequest != null && pageRequest.getCookie().value().length != 0)
    if (pageRequest != null && pageRequest.getCookie().length() != 0)
    {
      // The cookie contains the DN of the next entry to be returned.
      try
@@ -1326,10 +1248,10 @@
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        String str = StaticUtils.bytesToHex(pageRequest.getCookie().value());
        String str = pageRequest.getCookie().toHex();
        Message msg = ERR_JEB_INVALID_PAGED_RESULTS_COOKIE.get(str);
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
                                     msg, e);
            msg, e);
      }
    }
    else
@@ -1344,7 +1266,7 @@
    int lookthroughCount = 0;
    int lookthroughLimit =
        searchOperation.getClientConnection().getLookthroughLimit();
      searchOperation.getClientConnection().getLookthroughLimit();
    try
    {
@@ -1364,7 +1286,7 @@
            //Lookthrough limit exceeded
            searchOperation.setResultCode(ResultCode.ADMIN_LIMIT_EXCEEDED);
            searchOperation.appendErrorMessage(
              NOTE_JEB_LOOKTHROUGH_LIMIT_EXCEEDED.get(lookthroughLimit));
                NOTE_JEB_LOOKTHROUGH_LIMIT_EXCEEDED.get(lookthroughLimit));
            return;
          }
          int cmp = dn2id.getComparator().compare(key.getData(), end);
@@ -1377,14 +1299,14 @@
          // We have found a subordinate entry.
          EntryID entryID = new EntryID(data);
          DN dn = DN.decode(new ASN1OctetString(key.getData()));
          DN dn = DN.decode(ByteString.wrap(key.getData()));
          boolean isInScope = true;
          if (searchScope == SearchScope.SINGLE_LEVEL)
          {
            // Check if this entry is an immediate child.
            if ((dn.getNumComponents() !=
                 baseDN.getNumComponents() + 1))
              baseDN.getNumComponents() + 1))
            {
              isInScope = false;
            }
@@ -1398,7 +1320,7 @@
            // Try the entry cache first. Note no need to take a lock.
            lockList.clear();
            cacheEntry = entryCache.getEntry(backend, entryID.longValue(),
                                             LockType.NONE, lockList);
                LockType.NONE, lockList);
            if (cacheEntry == null)
            {
@@ -1420,15 +1342,15 @@
                if (searchOperation.getFilter().matchesEntry(entry))
                {
                  if (pageRequest != null &&
                       searchOperation.getEntriesSent() ==
                       pageRequest.getSize())
                      searchOperation.getEntriesSent() ==
                        pageRequest.getSize())
                  {
                    // The current page is full.
                    // Set the cookie to remember where we were.
                    ASN1OctetString cookie = new ASN1OctetString(key.getData());
                    ByteString cookie = ByteString.wrap(key.getData());
                    PagedResultsControl control;
                    control = new PagedResultsControl(pageRequest.isCritical(),
                                                      0, cookie);
                        0, cookie);
                    searchOperation.getResponseControls().add(control);
                    return;
                  }
@@ -1468,8 +1390,7 @@
    {
      // Indicate no more pages.
      PagedResultsControl control;
      control = new PagedResultsControl(pageRequest.isCritical(), 0,
                                        new ASN1OctetString());
      control = new PagedResultsControl(pageRequest.isCritical(), 0, null);
      searchOperation.getResponseControls().add(control);
    }
@@ -1498,10 +1419,10 @@
   * processed.
   */
  private void searchIndexed(EntryIDSet entryIDList,
                             boolean candidatesAreInScope,
                             SearchOperation searchOperation,
                             PagedResultsControl pageRequest)
       throws DirectoryException, CanceledOperationException
      boolean candidatesAreInScope,
      SearchOperation searchOperation,
      PagedResultsControl pageRequest)
  throws DirectoryException, CanceledOperationException
  {
    EntryCache<?> entryCache = DirectoryServer.getEntryCache();
    SearchScope searchScope = searchOperation.getScope();
@@ -1511,12 +1432,12 @@
    // Set the starting value.
    EntryID begin = null;
    if (pageRequest != null && pageRequest.getCookie().value().length != 0)
    if (pageRequest != null && pageRequest.getCookie().length() != 0)
    {
      // The cookie contains the ID of the next entry to be returned.
      try
      {
        begin = new EntryID(new DatabaseEntry(pageRequest.getCookie().value()));
        begin = new EntryID(pageRequest.getCookie().toLong());
      }
      catch (Exception e)
      {
@@ -1524,10 +1445,10 @@
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        String str = StaticUtils.bytesToHex(pageRequest.getCookie().value());
        String str = pageRequest.getCookie().toHex();
        Message msg = ERR_JEB_INVALID_PAGED_RESULTS_COOKIE.get(str);
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
                                     msg, e);
            msg, e);
      }
    }
    else
@@ -1541,7 +1462,7 @@
    // Make sure the candidate list is smaller than the lookthrough limit
    int lookthroughLimit =
        searchOperation.getClientConnection().getLookthroughLimit();
      searchOperation.getClientConnection().getLookthroughLimit();
    if(lookthroughLimit > 0 && entryIDList.size() > lookthroughLimit)
    {
      //Lookthrough limit exceeded
@@ -1565,7 +1486,7 @@
        // Try the entry cache first. Note no need to take a lock.
        lockList.clear();
        cacheEntry = entryCache.getEntry(backend, id.longValue(),
                                         LockType.NONE, lockList);
            LockType.NONE, lockList);
        // Release any entry lock whatever happens during this block.
        // (This is actually redundant since we did not take a lock).
@@ -1606,8 +1527,8 @@
            {
              // Check if this entry is an immediate child.
              if ((entryDN.getNumComponents() ==
                   baseDN.getNumComponents() + 1) &&
                   entryDN.isDescendantOf(baseDN))
                baseDN.getNumComponents() + 1) &&
                entryDN.isDescendantOf(baseDN))
              {
                isInScope = true;
              }
@@ -1622,8 +1543,8 @@
            else if (searchScope == SearchScope.SUBORDINATE_SUBTREE)
            {
              if ((entryDN.getNumComponents() >
                   baseDN.getNumComponents()) &&
                   entryDN.isDescendantOf(baseDN))
              baseDN.getNumComponents()) &&
              entryDN.isDescendantOf(baseDN))
              {
                isInScope = true;
              }
@@ -1646,16 +1567,16 @@
                if (searchOperation.getFilter().matchesEntry(entry))
                {
                  if (pageRequest != null &&
                       searchOperation.getEntriesSent() ==
                       pageRequest.getSize())
                      searchOperation.getEntriesSent() ==
                        pageRequest.getSize())
                  {
                    // The current page is full.
                    // Set the cookie to remember where we were.
                    byte[] cookieBytes = id.getDatabaseEntry().getData();
                    ASN1OctetString cookie = new ASN1OctetString(cookieBytes);
                    ByteString cookie = ByteString.wrap(cookieBytes);
                    PagedResultsControl control;
                    control = new PagedResultsControl(pageRequest.isCritical(),
                                                      0, cookie);
                        0, cookie);
                    searchOperation.getResponseControls().add(control);
                    return;
                  }
@@ -1689,7 +1610,7 @@
    // exists. However, if we have returned at least one entry or subordinate
    // reference it implies the base does exist, so we can omit the check.
    if (searchOperation.getEntriesSent() == 0 &&
         searchOperation.getReferencesSent() == 0)
        searchOperation.getReferencesSent() == 0)
    {
      // Fetch the base entry if it exists.
      Entry baseEntry = null;
@@ -1727,8 +1648,7 @@
    {
      // Indicate no more pages.
      PagedResultsControl control;
      control = new PagedResultsControl(pageRequest.isCritical(), 0,
                                        new ASN1OctetString());
      control = new PagedResultsControl(pageRequest.isCritical(), 0, null);
      searchOperation.getResponseControls().add(control);
    }
@@ -1750,7 +1670,7 @@
   * @throws CanceledOperationException if this operation should be cancelled.
   */
  public void addEntry(Entry entry, AddOperation addOperation)
      throws DatabaseException, DirectoryException, CanceledOperationException
  throws DatabaseException, DirectoryException, CanceledOperationException
  {
    Transaction txn = beginTransaction();
    DN parentDN = getParentWithinBase(entry.getDN());
@@ -1761,7 +1681,7 @@
      if (dn2id.get(txn, entry.getDN(), LockMode.DEFAULT) != null)
      {
        Message message =
            ERR_JEB_ADD_ENTRY_ALREADY_EXISTS.get(entry.getDN().toString());
          ERR_JEB_ADD_ENTRY_ALREADY_EXISTS.get(entry.getDN().toString());
        throw new DirectoryException(ResultCode.ENTRY_ALREADY_EXISTS,
            message);
      }
@@ -1792,7 +1712,7 @@
      {
        // Do not ever expect to come through here.
        Message message =
            ERR_JEB_ADD_ENTRY_ALREADY_EXISTS.get(entry.getDN().toString());
          ERR_JEB_ADD_ENTRY_ALREADY_EXISTS.get(entry.getDN().toString());
        throw new DirectoryException(ResultCode.ENTRY_ALREADY_EXISTS,
            message);
      }
@@ -1802,7 +1722,7 @@
      {
        // Do not ever expect to come through here.
        Message message =
            ERR_JEB_ADD_ENTRY_ALREADY_EXISTS.get(entry.getDN().toString());
          ERR_JEB_ADD_ENTRY_ALREADY_EXISTS.get(entry.getDN().toString());
        throw new DirectoryException(ResultCode.ENTRY_ALREADY_EXISTS,
            message);
      }
@@ -1812,7 +1732,7 @@
      {
        // Do not ever expect to come through here.
        Message message =
            ERR_JEB_ADD_ENTRY_ALREADY_EXISTS.get(entry.getDN().toString());
          ERR_JEB_ADD_ENTRY_ALREADY_EXISTS.get(entry.getDN().toString());
        throw new DirectoryException(ResultCode.ENTRY_ALREADY_EXISTS,
            message);
      }
@@ -1834,14 +1754,14 @@
        // Iterate up through the superior entries, starting above the parent.
        for (DN dn = getParentWithinBase(parentDN); dn != null;
             dn = getParentWithinBase(dn))
        dn = getParentWithinBase(dn))
        {
          // Read the ID from dn2id.
          EntryID nodeID = dn2id.get(txn, dn, LockMode.DEFAULT);
          if (nodeID == null)
          {
            Message msg =
                ERR_JEB_MISSING_DN2ID_RECORD.get(dn.toNormalizedString());
              ERR_JEB_MISSING_DN2ID_RECORD.get(dn.toNormalizedString());
            throw new JebException(msg);
          }
@@ -1913,7 +1833,7 @@
   * @throws CanceledOperationException if this operation should be cancelled.
   */
  public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
      throws DirectoryException, DatabaseException, CanceledOperationException
  throws DirectoryException, DatabaseException, CanceledOperationException
  {
    Transaction txn = beginTransaction();
    IndexBuffer indexBuffer = null;
@@ -1926,37 +1846,29 @@
      // Determine whether this is a subtree delete.
      boolean isSubtreeDelete = false;
      if(deleteOperation != null)
      if (deleteOperation != null
          && deleteOperation
              .getRequestControl(SubtreeDeleteControl.DECODER) != null)
      {
        List<Control> controls = deleteOperation.getRequestControls();
        if (controls != null)
        {
          for (Control control : controls)
          {
            if (control.getOID().equals(OID_SUBTREE_DELETE_CONTROL))
            {
              isSubtreeDelete = true;
            }
          }
        }
        isSubtreeDelete = true;
      }
      /*
      * We will iterate backwards through a range of the dn2id keys to
      * find subordinates of the target entry from the bottom of the tree
      * upwards. For example, any subordinates of "dc=example,dc=com" appear
      * in dn2id with a key ending in ",dc=example,dc=com". The entry
      * "cn=joe,ou=people,dc=example,dc=com" will appear after the entry
      * "ou=people,dc=example,dc=com".
      */
       * We will iterate backwards through a range of the dn2id keys to
       * find subordinates of the target entry from the bottom of the tree
       * upwards. For example, any subordinates of "dc=example,dc=com" appear
       * in dn2id with a key ending in ",dc=example,dc=com". The entry
       * "cn=joe,ou=people,dc=example,dc=com" will appear after the entry
       * "ou=people,dc=example,dc=com".
       */
      byte[] suffix = StaticUtils.getBytes("," + entryDN.toNormalizedString());
      /*
      * Set the starting value to a value of equal length but slightly
      * greater than the target DN. Since keys are compared in
      * reverse order we must set the first byte (the comma).
      * No possibility of overflow here.
      */
       * Set the starting value to a value of equal length but slightly
       * greater than the target DN. Since keys are compared in
       * reverse order we must set the first byte (the comma).
       * No possibility of overflow here.
       */
      byte[] begin = suffix.clone();
      begin[0] = (byte) (begin[0] + 1);
      int subordinateEntriesDeleted = 0;
@@ -2003,7 +1915,7 @@
            // the target entry is not a leaf.
            Message message =
                ERR_JEB_DELETE_NOT_ALLOWED_ON_NONLEAF.get(entryDN.toString());
              ERR_JEB_DELETE_NOT_ALLOWED_ON_NONLEAF.get(entryDN.toString());
            throw new DirectoryException(ResultCode.NOT_ALLOWED_ON_NONLEAF,
                message);
          }
@@ -2016,11 +1928,11 @@
          }
          /*
          * Delete this entry which by now must be a leaf because
          * we have been deleting from the bottom of the tree upwards.
          */
           * Delete this entry which by now must be a leaf because
           * we have been deleting from the bottom of the tree upwards.
           */
          EntryID entryID = new EntryID(data);
          DN subordinateDN = DN.decode(new ASN1OctetString(key.getData()));
          DN subordinateDN = DN.decode(ByteString.wrap(key.getData()));
          deleteEntry(txn, indexBuffer, true, entryDN, subordinateDN, entryID);
          subordinateEntriesDeleted++;
@@ -2098,12 +2010,12 @@
  }
  private void deleteEntry(Transaction txn,
                           IndexBuffer indexBuffer,
                           boolean manageDsaIT,
                           DN targetDN,
                           DN leafDN,
                           EntryID leafID)
      throws DatabaseException, DirectoryException, JebException
      IndexBuffer indexBuffer,
      boolean manageDsaIT,
      DN targetDN,
      DN leafDN,
      EntryID leafID)
  throws DatabaseException, DirectoryException, JebException
  {
    if(leafID == null || leafDN == null)
    {
@@ -2113,7 +2025,7 @@
      if (leafID == null)
      {
        Message message =
            ERR_JEB_DELETE_NO_SUCH_OBJECT.get(leafDN.toString());
          ERR_JEB_DELETE_NO_SUCH_OBJECT.get(leafDN.toString());
        DN matchedDN = getMatchedDN(baseDN);
        throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
            message, matchedDN, null);
@@ -2169,7 +2081,7 @@
    if(indexBuffer != null)
    {
      byte[] leafIDKeyBytes =
          JebFormat.entryIDToDatabase(leafID.longValue());
        JebFormat.entryIDToDatabase(leafID.longValue());
      id2children.delete(indexBuffer, leafIDKeyBytes);
      id2subtree.delete(indexBuffer, leafIDKeyBytes);
    }
@@ -2183,21 +2095,21 @@
    // Iterate up through the superior entries from the target entry.
    boolean isParent = true;
    for (DN parentDN = getParentWithinBase(targetDN); parentDN != null;
         parentDN = getParentWithinBase(parentDN))
    parentDN = getParentWithinBase(parentDN))
    {
      // Read the ID from dn2id.
      EntryID parentID = dn2id.get(txn, parentDN, LockMode.DEFAULT);
      if (parentID == null)
      {
        Message msg =
            ERR_JEB_MISSING_DN2ID_RECORD.get(parentDN.toNormalizedString());
          ERR_JEB_MISSING_DN2ID_RECORD.get(parentDN.toNormalizedString());
        throw new JebException(msg);
      }
      if(indexBuffer != null)
      {
        byte[] parentIDBytes =
            JebFormat.entryIDToDatabase(parentID.longValue());
          JebFormat.entryIDToDatabase(parentID.longValue());
        // Remove from id2children.
        if (isParent)
        {
@@ -2239,7 +2151,7 @@
   *                              determination.
   */
  public boolean entryExists(DN entryDN)
      throws DirectoryException
  throws DirectoryException
  {
    EntryCache<?> entryCache = DirectoryServer.getEntryCache();
@@ -2283,7 +2195,7 @@
   * @throws DatabaseException An error occurred during a database operation.
   */
  public Entry getEntry(DN entryDN)
      throws DatabaseException, DirectoryException
  throws DatabaseException, DirectoryException
  {
    EntryCache<?> entryCache = DirectoryServer.getEntryCache();
    Entry entry = null;
@@ -2316,7 +2228,7 @@
        // The entryID does not exist.
        Message msg = ERR_JEB_MISSING_ID2ENTRY_RECORD.get(entryID.toString());
        throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
          msg);
            msg);
      }
      // Put the entry in the cache making sure not to overwrite
@@ -2347,7 +2259,7 @@
  public void replaceEntry(Entry oldEntry, Entry newEntry,
      ModifyOperation modifyOperation) throws DatabaseException,
      DirectoryException, CanceledOperationException
  {
      {
    Transaction txn = beginTransaction();
    try
@@ -2358,7 +2270,7 @@
      {
        // The entry does not exist.
        Message message =
            ERR_JEB_MODIFY_NO_SUCH_OBJECT.get(newEntry.getDN().toString());
          ERR_JEB_MODIFY_NO_SUCH_OBJECT.get(newEntry.getDN().toString());
        DN matchedDN = getMatchedDN(baseDN);
        throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
            message, matchedDN, null);
@@ -2443,7 +2355,7 @@
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
          message, e);
    }
  }
      }
  /**
   * Moves and/or renames the provided entry in this backend, altering any
@@ -2467,8 +2379,8 @@
   * @throws DatabaseException If an error occurs in the JE database.
   */
  public void renameEntry(DN currentDN, Entry entry,
                          ModifyDNOperation modifyDNOperation)
      throws DatabaseException, DirectoryException, CanceledOperationException
      ModifyDNOperation modifyDNOperation)
  throws DatabaseException, DirectoryException, CanceledOperationException
  {
    Transaction txn = beginTransaction();
    DN oldSuperiorDN = getParentWithinBase(currentDN);
@@ -2498,7 +2410,7 @@
        Message message = ERR_JEB_MODIFYDN_ALREADY_EXISTS.get(
            entry.getDN().toString());
        throw new DirectoryException(ResultCode.ENTRY_ALREADY_EXISTS,
                                     message);
            message);
      }
      EntryID oldApexID = dn2id.get(txn, currentDN, LockMode.DEFAULT);
@@ -2508,7 +2420,7 @@
        dn2uri.targetEntryReferrals(currentDN, null);
        Message message =
                ERR_JEB_MODIFYDN_NO_SUCH_OBJECT.get(currentDN.toString());
          ERR_JEB_MODIFYDN_NO_SUCH_OBJECT.get(currentDN.toString());
        DN matchedDN = getMatchedDN(baseDN);
        throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
            message, matchedDN, null);
@@ -2519,7 +2431,7 @@
      {
        Message msg = ERR_JEB_MISSING_ID2ENTRY_RECORD.get(oldApexID.toString());
        throw new DirectoryException(
              DirectoryServer.getServerErrorResultCode(), msg);
            DirectoryServer.getServerErrorResultCode(), msg);
      }
      if (!isManageDsaITOperation(modifyDNOperation))
@@ -2539,8 +2451,8 @@
        if (newSuperiorID == null)
        {
          Message msg =
                  ERR_JEB_NEW_SUPERIOR_NO_SUCH_OBJECT.get(
                          newSuperiorDN.toString());
            ERR_JEB_NEW_SUPERIOR_NO_SUCH_OBJECT.get(
                newSuperiorDN.toString());
          DN matchedDN = getMatchedDN(baseDN);
          throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
              msg, matchedDN, null);
@@ -2626,8 +2538,8 @@
          // Construct the new DN of the entry.
          DN newDN = modDN(oldEntry.getDN(),
                           currentDN.getNumComponents(),
                           entry.getDN());
              currentDN.getNumComponents(),
              entry.getDN());
          // Assign a new entry ID if we are renumbering.
          EntryID newID = oldID;
@@ -2709,12 +2621,12 @@
  }
  private void renameApexEntry(Transaction txn, IndexBuffer buffer,
                               DN oldSuperiorDN, DN newSuperiorDN,
                               EntryID oldID, EntryID newID,
                               Entry oldEntry, Entry newEntry,
                               boolean isApexEntryMoved,
                               ModifyDNOperation modifyDNOperation)
      throws DirectoryException, DatabaseException
      DN oldSuperiorDN, DN newSuperiorDN,
      EntryID oldID, EntryID newID,
      Entry oldEntry, Entry newEntry,
      boolean isApexEntryMoved,
      ModifyDNOperation modifyDNOperation)
  throws DirectoryException, DatabaseException
  {
    DN oldDN = oldEntry.getDN();
    DN newDN = newEntry.getDN();
@@ -2752,7 +2664,7 @@
      {
        parentID = dn2id.get(txn, dn, LockMode.DEFAULT);
        parentIDKeyBytes =
            JebFormat.entryIDToDatabase(parentID.longValue());
          JebFormat.entryIDToDatabase(parentID.longValue());
        if(isParent)
        {
          id2children.removeID(buffer, parentIDKeyBytes, oldID);
@@ -2791,7 +2703,7 @@
      {
        parentID = dn2id.get(txn, dn, LockMode.DEFAULT);
        parentIDKeyBytes =
            JebFormat.entryIDToDatabase(parentID.longValue());
          JebFormat.entryIDToDatabase(parentID.longValue());
        if(isParent)
        {
          id2children.insertID(buffer, parentIDKeyBytes, newID);
@@ -2810,18 +2722,18 @@
  }
  private void renameSubordinateEntry(Transaction txn, IndexBuffer buffer,
                                      DN oldSuperiorDN, DN newSuperiorDN,
                                      EntryID oldID, EntryID newID,
                                      Entry oldEntry, DN newDN,
                                      boolean isApexEntryMoved,
                                      ModifyDNOperation modifyDNOperation)
      throws DirectoryException, DatabaseException
      DN oldSuperiorDN, DN newSuperiorDN,
      EntryID oldID, EntryID newID,
      Entry oldEntry, DN newDN,
      boolean isApexEntryMoved,
      ModifyDNOperation modifyDNOperation)
  throws DirectoryException, DatabaseException
  {
    DN oldDN = oldEntry.getDN();
    Entry newEntry = oldEntry.duplicate(false);
    newEntry.setDN(newDN);
    List<Modification> modifications =
        Collections.unmodifiableList(new ArrayList<Modification>(0));
      Collections.unmodifiableList(new ArrayList<Modification>(0));
    // Create a new entry that is a copy of the old entry but with the new DN.
    // Also invoke any subordinate modify DN plugins on the entry.
@@ -2834,10 +2746,10 @@
    if (! modifyDNOperation.isSynchronizationOperation())
    {
      PluginConfigManager pluginManager =
          DirectoryServer.getPluginConfigManager();
        DirectoryServer.getPluginConfigManager();
      PluginResult.SubordinateModifyDN pluginResult =
          pluginManager.invokeSubordinateModifyDNPlugins(
              modifyDNOperation, oldEntry, newEntry, modifications);
        pluginManager.invokeSubordinateModifyDNPlugins(
            modifyDNOperation, oldEntry, newEntry, modifications);
      if (!pluginResult.continueProcessing())
      {
@@ -2854,10 +2766,10 @@
            invalidReason))
        {
          Message message =
              ERR_JEB_MODIFYDN_ABORTED_BY_SUBORDINATE_SCHEMA_ERROR.get(
                  oldDN.toString(),
                  newDN.toString(),
                  invalidReason.toString());
            ERR_JEB_MODIFYDN_ABORTED_BY_SUBORDINATE_SCHEMA_ERROR.get(
                oldDN.toString(),
                newDN.toString(),
                invalidReason.toString());
          throw new DirectoryException(
              DirectoryServer.getServerErrorResultCode(), message);
        }
@@ -2893,7 +2805,7 @@
      {
        EntryID parentID = dn2id.get(txn, dn, LockMode.DEFAULT);
        byte[] parentIDKeyBytes =
            JebFormat.entryIDToDatabase(parentID.longValue());
          JebFormat.entryIDToDatabase(parentID.longValue());
        id2subtree.removeID(buffer, parentIDKeyBytes, oldID);
      }
    }
@@ -2912,11 +2824,11 @@
      byte[] parentIDKeyBytes;
      boolean isParent = true;
      for (DN superiorDN = newDN; superiorDN != null;
           superiorDN = getParentWithinBase(superiorDN))
      superiorDN = getParentWithinBase(superiorDN))
      {
        newParentID = dn2id.get(txn, superiorDN, LockMode.DEFAULT);
        parentIDKeyBytes =
            JebFormat.entryIDToDatabase(newParentID.longValue());
          JebFormat.entryIDToDatabase(newParentID.longValue());
        if(isParent)
        {
          id2children.insertID(buffer, parentIDKeyBytes, newID);
@@ -2944,7 +2856,7 @@
        {
          EntryID parentID = dn2id.get(txn, dn, LockMode.DEFAULT);
          byte[] parentIDKeyBytes =
              JebFormat.entryIDToDatabase(parentID.longValue());
            JebFormat.entryIDToDatabase(parentID.longValue());
          id2subtree.insertID(buffer, parentIDKeyBytes, newID);
        }
      }
@@ -3010,7 +2922,7 @@
    public int compare(byte[] a, byte[] b)
    {
      for (int ai = a.length - 1, bi = b.length - 1;
           ai >= 0 && bi >= 0; ai--, bi--)
      ai >= 0 && bi >= 0; ai--, bi--)
      {
        if (a[ai] > b[bi])
        {
@@ -3047,7 +2959,7 @@
   * @throws JebException If an error occurs in the JE backend.
   */
  private void indexInsertEntry(Transaction txn, Entry entry, EntryID entryID)
      throws DatabaseException, DirectoryException, JebException
  throws DatabaseException, DirectoryException, JebException
  {
    for (AttributeIndex index : attrIndexMap.values())
    {
@@ -3070,8 +2982,8 @@
   * @throws DirectoryException If a Directory Server error occurs.
   */
  private void indexInsertEntry(IndexBuffer buffer, Entry entry,
                                EntryID entryID)
      throws DatabaseException, DirectoryException
      EntryID entryID)
  throws DatabaseException, DirectoryException
  {
    for (AttributeIndex index : attrIndexMap.values())
    {
@@ -3095,7 +3007,7 @@
   * @throws JebException If an error occurs in the JE backend.
   */
  private void indexRemoveEntry(Transaction txn, Entry entry, EntryID entryID)
      throws DatabaseException, DirectoryException, JebException
  throws DatabaseException, DirectoryException, JebException
  {
    for (AttributeIndex index : attrIndexMap.values())
    {
@@ -3118,8 +3030,8 @@
   * @throws DirectoryException If a Directory Server error occurs.
   */
  private void indexRemoveEntry(IndexBuffer buffer, Entry entry,
                                EntryID entryID)
      throws DatabaseException, DirectoryException
      EntryID entryID)
  throws DatabaseException, DirectoryException
  {
    for (AttributeIndex index : attrIndexMap.values())
    {
@@ -3146,9 +3058,9 @@
   * @throws JebException If an error occurs in the JE backend.
   */
  private void indexModifications(Transaction txn, Entry oldEntry,
                                  Entry newEntry,
                                  EntryID entryID, List<Modification> mods)
      throws DatabaseException, DirectoryException, JebException
      Entry newEntry,
      EntryID entryID, List<Modification> mods)
  throws DatabaseException, DirectoryException, JebException
  {
    // Process in index configuration order.
    for (AttributeIndex index : attrIndexMap.values())
@@ -3157,7 +3069,7 @@
      boolean attributeModified = false;
      AttributeType indexAttributeType = index.getAttributeType();
      Iterable<AttributeType> subTypes =
          DirectoryServer.getSchema().getSubTypes(indexAttributeType);
        DirectoryServer.getSchema().getSubTypes(indexAttributeType);
      for (Modification mod : mods)
      {
@@ -3202,9 +3114,9 @@
   * @throws DirectoryException If a Directory Server error occurs.
   */
  private void indexModifications(IndexBuffer buffer, Entry oldEntry,
                                  Entry newEntry,
                                  EntryID entryID, List<Modification> mods)
      throws DatabaseException, DirectoryException
      Entry newEntry,
      EntryID entryID, List<Modification> mods)
  throws DatabaseException, DirectoryException
  {
    // Process in index configuration order.
    for (AttributeIndex index : attrIndexMap.values())
@@ -3213,7 +3125,7 @@
      boolean attributeModified = false;
      AttributeType indexAttributeType = index.getAttributeType();
      Iterable<AttributeType> subTypes =
          DirectoryServer.getSchema().getSubTypes(indexAttributeType);
        DirectoryServer.getSchema().getSubTypes(indexAttributeType);
      for (Modification mod : mods)
      {
@@ -3257,7 +3169,7 @@
    if (entryID != null)
    {
      DatabaseEntry key =
          new DatabaseEntry(JebFormat.entryIDToDatabase(entryID.longValue()));
        new DatabaseEntry(JebFormat.entryIDToDatabase(entryID.longValue()));
      EntryIDSet entryIDSet;
      entryIDSet = id2subtree.readKey(key, null, LockMode.DEFAULT);
@@ -3371,7 +3283,7 @@
   * a new transaction.
   */
  public Transaction beginTransaction()
      throws DatabaseException
  throws DatabaseException
  {
    Transaction parentTxn = null;
    TransactionConfig txnConfig = null;
@@ -3391,7 +3303,7 @@
   * the transaction.
   */
  public static void transactionCommit(Transaction txn)
      throws DatabaseException
  throws DatabaseException
  {
    if (txn != null)
    {
@@ -3411,7 +3323,7 @@
   * transaction.
   */
  public static void transactionAbort(Transaction txn)
      throws DatabaseException
  throws DatabaseException
  {
    if (txn != null)
    {
@@ -3476,7 +3388,7 @@
   * database.
   */
  public void deleteDatabase(DatabaseContainer database)
      throws DatabaseException
  throws DatabaseException
  {
    if(database == state)
    {
@@ -3521,7 +3433,7 @@
   * to delete the index.
   */
  public void deleteAttributeIndex(AttributeIndex index)
      throws DatabaseException
  throws DatabaseException
  {
    index.close();
    if(env.getConfig().getTransactional())
@@ -3613,7 +3525,7 @@
   * @throws JebException If an error occurs in the JE backend.
   */
  public void setDatabasePrefix(String newDatabasePrefix)
      throws DatabaseException, JebException
  throws DatabaseException, JebException
  {
    List<DatabaseContainer> databases = new ArrayList<DatabaseContainer>();
@@ -3671,13 +3583,13 @@
        {
          transactionAbort(txn);
        String msg = e.getMessage();
        if (msg == null)
        {
          msg = stackTraceToSingleLineString(e);
        }
        Message message = ERR_JEB_UNCHECKED_EXCEPTION.get(msg);
        throw new JebException(message, e);
          String msg = e.getMessage();
          if (msg == null)
          {
            msg = stackTraceToSingleLineString(e);
          }
          Message message = ERR_JEB_UNCHECKED_EXCEPTION.get(msg);
          throw new JebException(message, e);
        }
      }
      else
@@ -3756,8 +3668,8 @@
      {
        adminActionRequired = true;
        Message message =
                NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(
                        id2children.getName());
          NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(
              id2children.getName());
        messages.add(message);
      }
@@ -3765,21 +3677,21 @@
      {
        adminActionRequired = true;
        Message message =
                NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(
                        id2subtree.getName());
          NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(
              id2subtree.getName());
        messages.add(message);
      }
    }
    DataConfig entryDataConfig =
        new DataConfig(cfg.isEntriesCompressed(),
                       cfg.isCompactEncoding(),
                       rootContainer.getCompressedSchema());
      new DataConfig(cfg.isEntriesCompressed(),
          cfg.isCompactEncoding(),
          rootContainer.getCompressedSchema());
    id2entry.setDataConfig(entryDataConfig);
    this.config = cfg;
    return new ConfigChangeResult(ResultCode.SUCCESS,
                                  adminActionRequired, messages);
        adminActionRequired, messages);
  }
  /**
@@ -3791,7 +3703,7 @@
   *                           configuration object.
   */
  public EnvironmentConfig getEnvironmentConfig()
      throws DatabaseException
  throws DatabaseException
  {
    return env.getConfig();
  }
@@ -3903,7 +3815,7 @@
   * @throws DatabaseException if a JE database error occurs.
   */
  public long clearDatabase(DatabaseContainer database)
      throws DatabaseException
  throws DatabaseException
  {
    long count = 0;
    database.close();
@@ -3948,7 +3860,7 @@
   * @throws DatabaseException if a JE database error occurs.
   */
  public long clearAttributeIndex(AttributeIndex index)
      throws DatabaseException
  throws DatabaseException
  {
    long count = 0;
@@ -3963,27 +3875,27 @@
          if(index.equalityIndex != null)
          {
            count += env.truncateDatabase(txn, index.equalityIndex.getName(),
                                          true);
                true);
          }
          if(index.presenceIndex != null)
          {
            count += env.truncateDatabase(txn, index.presenceIndex.getName(),
                                          true);
                true);
          }
          if(index.substringIndex != null)
          {
            count += env.truncateDatabase(txn, index.substringIndex.getName(),
                                          true);
                true);
          }
          if(index.orderingIndex != null)
          {
            count += env.truncateDatabase(txn, index.orderingIndex.getName(),
                                          true);
                true);
          }
          if(index.approximateIndex != null)
          {
            count += env.truncateDatabase(txn, index.approximateIndex.getName(),
                                          true);
                true);
          }
          transactionCommit(txn);
        }
@@ -3998,27 +3910,27 @@
        if(index.equalityIndex != null)
        {
          count += env.truncateDatabase(null, index.equalityIndex.getName(),
                                        true);
              true);
        }
        if(index.presenceIndex != null)
        {
          count += env.truncateDatabase(null, index.presenceIndex.getName(),
                                        true);
              true);
        }
        if(index.substringIndex != null)
        {
          count += env.truncateDatabase(null, index.substringIndex.getName(),
                                        true);
              true);
        }
        if(index.orderingIndex != null)
        {
          count += env.truncateDatabase(null, index.orderingIndex.getName(),
                                        true);
              true);
        }
        if(index.approximateIndex != null)
        {
          count += env.truncateDatabase(null, index.approximateIndex.getName(),
                                        true);
              true);
        }
      }
    }
@@ -4044,7 +3956,7 @@
   * existing entry from being performed
   */
  private DN getMatchedDN(DN baseDN)
    throws DirectoryException
  throws DirectoryException
  {
    DN matchedDN = null;
    DN parentDN  = baseDN.getParentDNInSuffix();
opends/src/server/org/opends/server/backends/jeb/EntryIDSetSorter.java
@@ -39,14 +39,7 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.SearchOperation;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
import org.opends.server.types.SortOrder;
import org.opends.server.types.*;
import static org.opends.messages.JebMessages.*;
import static org.opends.server.util.StaticUtils.*;
@@ -206,9 +199,10 @@
      }
      else
      {
        AttributeValue assertionValue = new
             AttributeValue(sortOrder.getSortKeys()[0].getAttributeType(),
                            vlvRequest.getGreaterThanOrEqualAssertion());
        AttributeValue assertionValue =
            AttributeValues.create(
                sortOrder.getSortKeys()[0].getAttributeType(),
                vlvRequest.getGreaterThanOrEqualAssertion());
        boolean targetFound     = false;
        int targetOffset        = 0;
opends/src/server/org/opends/server/backends/jeb/EqualityIndexer.java
@@ -172,7 +172,7 @@
      {
        try
        {
          byte[] keyBytes = value.getNormalizedValue().value();
          byte[] keyBytes = value.getNormalizedValue().toByteArray();
          keys.add(keyBytes);
        }
@@ -207,7 +207,7 @@
      {
        try
        {
          byte[] keyBytes = value.getNormalizedValue().value();
          byte[] keyBytes = value.getNormalizedValue().toByteArray();
          Boolean cInsert = modifiedKeys.get(keyBytes);
          if(cInsert == null)
opends/src/server/org/opends/server/backends/jeb/ExportJob.java
@@ -34,16 +34,13 @@
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.util.LDIFException;
import org.opends.server.util.StaticUtils;
import java.io.IOException;
import java.util.*;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
@@ -238,7 +235,7 @@
        Entry entry = null;
        try
        {
          entry = JebFormat.entryFromDatabase(data.getData(),
          entry = ID2Entry.entryFromDatabase(ByteString.wrap(data.getData()),
                       entryContainer.getRootContainer().getCompressedSchema());
        }
        catch (Exception e)
opends/src/server/org/opends/server/backends/jeb/ID2Entry.java
@@ -33,9 +33,16 @@
import com.sleepycat.je.*;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.*;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.protocols.asn1.ASN1;
import org.opends.server.protocols.asn1.ASN1Reader;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.api.CompressedSchema;
import java.io.IOException;
import java.util.zip.DataFormatException;
/**
 * Represents the database containing the LDAP entries. The database key is
@@ -54,6 +61,139 @@
   */
  private DataConfig dataConfig;
  private static ThreadLocal<EntryCoder> entryCodingBuffers =
      new ThreadLocal<EntryCoder>();
  /**
   * A cached set of ByteStringBuilder buffers and ASN1Writer used to encode
   * entries.
   */
  private static class EntryCoder
  {
    ByteStringBuilder encodedBuffer;
    private ByteStringBuilder entryBuffer;
    private ByteStringBuilder compressedEntryBuffer;
    private ASN1Writer writer;
    private EntryCoder()
    {
      encodedBuffer = new ByteStringBuilder();
      entryBuffer = new ByteStringBuilder();
      compressedEntryBuffer = new ByteStringBuilder();
      writer = ASN1.getWriter(encodedBuffer);
    }
    private Entry decode(ByteString bytes, CompressedSchema compressedSchema)
        throws DirectoryException,ASN1Exception,LDAPException,
        DataFormatException, IOException
    {
      // Get the format version.
      byte formatVersion = bytes.byteAt(0);
      if(formatVersion != JebFormat.FORMAT_VERSION)
      {
        Message message =
            ERR_JEB_INCOMPATIBLE_ENTRY_VERSION.get(formatVersion);
        throw new ASN1Exception(message);
      }
      // Read the ASN1 sequence.
      ASN1Reader reader = ASN1.getReader(bytes.subSequence(1, bytes.length()));
      reader.readStartSequence();
      // See if it was compressed.
      int uncompressedSize = (int)reader.readInteger();
      if(uncompressedSize > 0)
      {
        // We will use the cached buffers to avoid allocations.
        // Reset the buffers;
        entryBuffer.clear();
        compressedEntryBuffer.clear();
        // It was compressed.
        reader.readOctetString(compressedEntryBuffer);
        CryptoManager cryptoManager = DirectoryServer.getCryptoManager();
        // TODO: Should handle the case where uncompress returns < 0
        compressedEntryBuffer.uncompress(entryBuffer, cryptoManager,
            uncompressedSize);
        // Since we are used the cached buffers (ByteStringBuilders),
        // the decoded attribute values will not refer back to the
        // original buffer.
        return Entry.decode(entryBuffer.asReader(), compressedSchema);
      }
      else
      {
        // Since we don't have to do any decompression, we can just decode
        // the entry off the
        ByteString encodedEntry = reader.readOctetString();
        return Entry.decode(encodedEntry.asReader(), compressedSchema);
      }
    }
    private ByteString encodeCopy(Entry entry, DataConfig dataConfig)
        throws DirectoryException
    {
      encodeVolatile(entry, dataConfig);
      return encodedBuffer.toByteString();
    }
    private DatabaseEntry encodeInternal(Entry entry, DataConfig dataConfig)
        throws DirectoryException
    {
      encodeVolatile(entry, dataConfig);
      return new DatabaseEntry(encodedBuffer.getBackingArray(), 0,
          encodedBuffer.length());
    }
    private void encodeVolatile(Entry entry, DataConfig dataConfig)
        throws DirectoryException
    {
      // Reset the buffers;
      encodedBuffer.clear();
      entryBuffer.clear();
      compressedEntryBuffer.clear();
      // Encode the entry for later use.
      entry.encode(entryBuffer, dataConfig.getEntryEncodeConfig());
      // First write the DB format version byte.
      encodedBuffer.append(JebFormat.FORMAT_VERSION);
      try
      {
        // Then start the ASN1 sequence.
        writer.writeStartSequence(JebFormat.TAG_DATABASE_ENTRY);
        // Do optional compression.
        CryptoManager cryptoManager = DirectoryServer.getCryptoManager();
        if (dataConfig.isCompressed() && cryptoManager != null &&
            entryBuffer.compress(compressedEntryBuffer, cryptoManager))
        {
          // Compression needed and successful.
          writer.writeInteger(entryBuffer.length());
          writer.writeOctetString(compressedEntryBuffer);
        }
        else
        {
          writer.writeInteger(0);
          writer.writeOctetString(entryBuffer);
        }
        writer.writeEndSequence();
      }
      catch(IOException ioe)
      {
        // TODO: This should never happen with byte buffer.
        if(debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ioe);
        }
      }
    }
  }
  /**
   * Create a new ID2Entry object.
   *
@@ -96,20 +236,75 @@
  }
  /**
   * Convert an entry to its database format.
   * Decodes an entry from its database representation.
   * <p>
   * An entry on disk is ASN1 encoded in this format:
   *
   * @param entry The LDAP entry to be converted.
   * @return The database entry.
   * <pre>
   * DatabaseEntry ::= [APPLICATION 0] IMPLICIT SEQUENCE {
   *  uncompressedSize      INTEGER,      -- A zero value means not compressed.
   *  dataBytes             OCTET STRING  -- Optionally compressed encoding of
   *                                         the data bytes.
   * }
   *
   * ID2EntryValue ::= DatabaseEntry
   *  -- Where dataBytes contains an encoding of DirectoryServerEntry.
   *
   * DirectoryServerEntry ::= [APPLICATION 1] IMPLICIT SEQUENCE {
   *  dn                      LDAPDN,
   *  objectClasses           SET OF LDAPString,
   *  userAttributes          AttributeList,
   *  operationalAttributes   AttributeList
   * }
   * </pre>
   *
   * @param bytes A byte array containing the encoded database value.
   * @param compressedSchema The compressed schema manager to use when decoding.
   * @return The decoded entry.
   * @throws ASN1Exception If the data is not in the expected ASN.1 encoding
   * format.
   * @throws LDAPException If the data is not in the expected ASN.1 encoding
   * format.
   * @throws DataFormatException If an error occurs while trying to decompress
   * compressed data.
   * @throws DirectoryException If a Directory Server error occurs.
   * @throws IOException if an error occurs while reading the ASN1 sequence.
   */
  static public Entry entryFromDatabase(ByteString bytes,
                                        CompressedSchema compressedSchema)
      throws DirectoryException,ASN1Exception,LDAPException,
      DataFormatException,IOException
  {
    EntryCoder coder = entryCodingBuffers.get();
    if(coder == null)
    {
      coder = new EntryCoder();
      entryCodingBuffers.set(coder);
    }
    return coder.decode(bytes, compressedSchema);
  }
  /**
   * Encodes an entry to the raw database format, with optional compression.
   *
   * @param entry The entry to encode.
   * @param dataConfig Compression and cryptographic options.
   * @return A ByteSTring containing the encoded database value.
   *
   * @throws  DirectoryException  If a problem occurs while attempting to encode
   *                              the entry.
   */
  public DatabaseEntry entryData(Entry entry)
          throws DirectoryException
  static public ByteString entryToDatabase(Entry entry, DataConfig dataConfig)
      throws DirectoryException
  {
    byte[] entryBytes;
    entryBytes = JebFormat.entryToDatabase(entry, dataConfig);
    return new DatabaseEntry(entryBytes);
    EntryCoder coder = entryCodingBuffers.get();
    if(coder == null)
    {
      coder = new EntryCoder();
      entryCodingBuffers.set(coder);
    }
    return coder.encodeCopy(entry, dataConfig);
  }
  /**
@@ -128,7 +323,13 @@
       throws DatabaseException, DirectoryException
  {
    DatabaseEntry key = id.getDatabaseEntry();
    DatabaseEntry data = entryData(entry);
    EntryCoder coder = entryCodingBuffers.get();
    if(coder == null)
    {
      coder = new EntryCoder();
      entryCodingBuffers.set(coder);
    }
    DatabaseEntry data = coder.encodeInternal(entry, dataConfig);
    OperationStatus status;
    status = insert(txn, key, data);
@@ -154,7 +355,13 @@
       throws DatabaseException, DirectoryException
  {
    DatabaseEntry key = id.getDatabaseEntry();
    DatabaseEntry data = entryData(entry);
    EntryCoder coder = entryCodingBuffers.get();
    if(coder == null)
    {
      coder = new EntryCoder();
      entryCodingBuffers.set(coder);
    }
    DatabaseEntry data = coder.encodeInternal(entry, dataConfig);
    OperationStatus status;
    status = put(txn, key, data);
@@ -231,44 +438,19 @@
      return null;
    }
    byte[] entryBytes = data.getData();
    byte entryVersion = JebFormat.getEntryVersion(entryBytes);
    //Try to decode the entry based on the version number. On later versions,
    //a case could be written to upgrade entries if it is not the current
    //version
    Entry entry = null;
    switch(entryVersion)
    try
    {
      case JebFormat.FORMAT_VERSION :
        try
        {
          entry = JebFormat.entryFromDatabase(entryBytes,
                       entryContainer.getRootContainer().getCompressedSchema());
        }
        catch (Exception e)
        {
          Message message = ERR_JEB_ENTRY_DATABASE_CORRUPT.get(id.toString());
          throw new DirectoryException(
              DirectoryServer.getServerErrorResultCode(), message);
        }
        break;
      //case 0x00                     :
      //  Call upgrade method? Call 0x00 decode method?
      default   :
        Message message =
            ERR_JEB_INCOMPATIBLE_ENTRY_VERSION.get(id.toString(), entryVersion);
        throw new DirectoryException(
              DirectoryServer.getServerErrorResultCode(), message);
    }
    if (entry != null)
    {
      Entry entry = entryFromDatabase(ByteString.wrap(data.getData()),
          entryContainer.getRootContainer().getCompressedSchema());
      entry.processVirtualAttributes();
      return entry;
    }
    return entry;
    catch (Exception e)
    {
      Message message = ERR_JEB_ENTRY_DATABASE_CORRUPT.get(id.toString());
      throw new DirectoryException(
          DirectoryServer.getServerErrorResultCode(), message);
    }
  }
  /**
opends/src/server/org/opends/server/backends/jeb/IndexQuery.java
@@ -25,185 +25,198 @@
 *      Copyright 2009 Sun Microsystems, Inc.
 */
package org.opends.server.backends.jeb;
import java.util.Collection;
import static org.opends.server.backends.jeb.IndexFilter.*;
/**
 * This class represents a JE Backend Query.
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.VOLATILE,
     mayInstantiate=false,
     mayExtend=true,
     mayInvoke=false)
    stability = org.opends.server.types.StabilityLevel.VOLATILE,
    mayInstantiate = false,
    mayExtend = true,
    mayInvoke = false)
public abstract class IndexQuery
{
  /**
  * Evaluates the index query and returns the EntryIDSet.
  * @return The EntryIDSet as a result of evaulation of this query.
  */
   * Evaluates the index query and returns the EntryIDSet.
   *
   * @return The EntryIDSet as a result of evaulation of this query.
   */
  public abstract EntryIDSet evaluate();
   /**
    * Creates an IntersectionIndexQuery object from a collection of IndexQuery
    * objects.
    * @param subIndexQueries A collection of IndexQuery objects.
    * @return An IntersectionIndexQuery object.
    */
   public static IndexQuery createIntersectionIndexQuery(
           Collection<IndexQuery> subIndexQueries)
   {
     return new IntersectionIndexQuery(subIndexQueries);
   }
   /**
    * Creates a union IndexQuery object from a collection of IndexQuery
    * objects.
    * @param subIndexQueries Collection of IndexQuery objects.
    * @return A UnionIndexQuery object.
    */
   public static IndexQuery createUnionIndexQuery(
           Collection<IndexQuery> subIndexQueries)
   {
     return new UnionIndexQuery(subIndexQueries);
   }
   /**
    * Creates an empty IndexQuery object.
    * @return A NullIndexQuery object.
    */
   public static IndexQuery createNullIndexQuery()
   {
     return new NullIndexQuery();
   }
}
/**
* This class creates a Null  IndexQuery. It is used when there
*  is no record in the index. It may also be used when the
 * index contains all the records but an empty EntryIDSet should be
 * returned as part of the optimization.
*/
final class NullIndexQuery extends IndexQuery
{
  /**
   * {@inheritDoc}
   * Creates an IntersectionIndexQuery object from a collection of
   * IndexQuery objects.
   *
   * @param subIndexQueries
   *          A collection of IndexQuery objects.
   * @return An IntersectionIndexQuery object.
   */
  @Override
  public EntryIDSet evaluate()
  public static IndexQuery createIntersectionIndexQuery(
      Collection<IndexQuery> subIndexQueries)
  {
    return new EntryIDSet();
  }
}
/**
 * This class creates an intersection IndexQuery from a collection of
 * IndexQuery objects.
 */
final class IntersectionIndexQuery extends IndexQuery
{
  /**
   * Collection of IndexQuery objects.
   */
  private final  Collection<IndexQuery> subIndexQueries;
  /**
   * Creates an instance of IntersectionIndexQuery.
   * @param subIndexQueries Collection of IndexQuery objects.
   */
  IntersectionIndexQuery(Collection<IndexQuery> subIndexQueries)
  {
    this.subIndexQueries = subIndexQueries;
    return new IntersectionIndexQuery(subIndexQueries);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public EntryIDSet evaluate()
  {
   EntryIDSet entryIDs = null;
   for (IndexQuery query : subIndexQueries)
   {
     if (entryIDs == null)
     {
       entryIDs = query.evaluate();
     }
     else
     {
       entryIDs.retainAll(query.evaluate());
     }
     if (entryIDs.isDefined() &&
         entryIDs.size() <= FILTER_CANDIDATE_THRESHOLD)
     {
       break;
     }
   }
   return entryIDs;
  }
}
/**
 * This class creates a union of IndexQuery objects.
 */
final class UnionIndexQuery extends IndexQuery
{
  /**
   * Collection containing IndexQuery objects.
   */
  private final Collection<IndexQuery> subIndexQueries;
  /**
   * Creates an instance of UnionIndexQuery.
   * @param subIndexQueries The Collection of IndexQuery objects.
   * Creates a union IndexQuery object from a collection of IndexQuery
   * objects.
   *
   * @param subIndexQueries
   *          Collection of IndexQuery objects.
   * @return A UnionIndexQuery object.
   */
  UnionIndexQuery(Collection<IndexQuery> subIndexQueries)
  public static IndexQuery createUnionIndexQuery(
      Collection<IndexQuery> subIndexQueries)
  {
    this.subIndexQueries = subIndexQueries;
    return new UnionIndexQuery(subIndexQueries);
  }
  /**
   * {@inheritDoc}
   * Creates an empty IndexQuery object.
   *
   * @return A NullIndexQuery object.
   */
  @Override
  public EntryIDSet evaluate()
  public static IndexQuery createNullIndexQuery()
  {
    EntryIDSet entryIDs = null;
    for (IndexQuery query : subIndexQueries)
    return new NullIndexQuery();
  }
  /**
   * This class creates a Null IndexQuery. It is used when there is no
   * record in the index. It may also be used when the index contains
   * all the records but an empty EntryIDSet should be returned as part
   * of the optimization.
   */
  private static final class NullIndexQuery extends IndexQuery
  {
    /**
     * {@inheritDoc}
     */
    @Override
    public EntryIDSet evaluate()
    {
      if (entryIDs == null)
      {
        entryIDs = query.evaluate();
      }
      else
      {
        entryIDs.addAll(query.evaluate());
      }
      if (entryIDs.isDefined() &&
          entryIDs.size() <= FILTER_CANDIDATE_THRESHOLD)
      {
        break;
      }
      return new EntryIDSet();
    }
    return entryIDs;
  }
}
  /**
   * This class creates an intersection IndexQuery from a collection of
   * IndexQuery objects.
   */
  private static final class IntersectionIndexQuery extends IndexQuery
  {
    /**
     * Collection of IndexQuery objects.
     */
    private final Collection<IndexQuery> subIndexQueries;
    /**
     * Creates an instance of IntersectionIndexQuery.
     *
     * @param subIndexQueries
     *          Collection of IndexQuery objects.
     */
    private IntersectionIndexQuery(Collection<IndexQuery> subIndexQueries)
    {
      this.subIndexQueries = subIndexQueries;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public EntryIDSet evaluate()
    {
      EntryIDSet entryIDs = null;
      for (IndexQuery query : subIndexQueries)
      {
        if (entryIDs == null)
        {
          entryIDs = query.evaluate();
        }
        else
        {
          entryIDs.retainAll(query.evaluate());
        }
        if (entryIDs.isDefined()
            && entryIDs.size() <= FILTER_CANDIDATE_THRESHOLD)
        {
          break;
        }
      }
      return entryIDs;
    }
  }
  /**
   * This class creates a union of IndexQuery objects.
   */
  private static final class UnionIndexQuery extends IndexQuery
  {
    /**
     * Collection containing IndexQuery objects.
     */
    private final Collection<IndexQuery> subIndexQueries;
    /**
     * Creates an instance of UnionIndexQuery.
     *
     * @param subIndexQueries
     *          The Collection of IndexQuery objects.
     */
    private UnionIndexQuery(Collection<IndexQuery> subIndexQueries)
    {
      this.subIndexQueries = subIndexQueries;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public EntryIDSet evaluate()
    {
      EntryIDSet entryIDs = null;
      for (IndexQuery query : subIndexQueries)
      {
        if (entryIDs == null)
        {
          entryIDs = query.evaluate();
        }
        else
        {
          entryIDs.addAll(query.evaluate());
        }
        if (entryIDs.isDefined()
            && entryIDs.size() <= FILTER_CANDIDATE_THRESHOLD)
        {
          break;
        }
      }
      return entryIDs;
    }
  }
}
opends/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java
@@ -25,34 +25,41 @@
 *      Copyright 2009 Sun Microsystems, Inc.
 */
package org.opends.server.backends.jeb;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.LockMode;
import java.util.Collection;
import java.util.Map;
import org.opends.server.api.IndexQueryFactory;
import org.opends.server.types.ByteSequence;
/**
 * This class is an implementation of IndexQueryFactory which creates
 * IndexQuery objects as part of the query of the JEB index.
*/
public final class IndexQueryFactoryImpl
        implements IndexQueryFactory<IndexQuery>
 */
public final class IndexQueryFactoryImpl implements
    IndexQueryFactory<IndexQuery>
{
  /**
   * The Map containing the string type identifier and the corresponding index.
   * The Map containing the string type identifier and the corresponding
   * index.
   */
  private Map<String,Index> indexMap;
  private Map<String, Index> indexMap;
  /**
   * Creates a new IndexQueryFactoryImpl object.
   * @param indexMap A map containing the index id and the corresponding index.
   *
   * @param indexMap
   *          A map containing the index id and the corresponding index.
   */
  public IndexQueryFactoryImpl(Map<String,Index> indexMap)
  public IndexQueryFactoryImpl(Map<String, Index> indexMap)
  {
    this.indexMap = indexMap;
  }
@@ -60,62 +67,61 @@
  /**
   *{@inheritDoc}
   * {@inheritDoc}
   */
  public IndexQuery createExactMatchQuery(final String indexID,
          final byte[] value)
      final ByteSequence value)
  {
    return new IndexQuery()
    {
      @Override
      public EntryIDSet evaluate()
      {
        //Read the database and get Record for the key.
        DatabaseEntry key = new DatabaseEntry(value);
        //Select the right index to be used.
        Index index = indexMap.get(indexID);
        EntryIDSet entrySet = index.readKey(key,null,LockMode.DEFAULT);
        return entrySet;
      }
    };
        @Override
        public EntryIDSet evaluate()
        {
          // Read the database and get Record for the key.
          DatabaseEntry key = new DatabaseEntry(value.toByteArray());
          // Select the right index to be used.
          Index index = indexMap.get(indexID);
          EntryIDSet entrySet =
              index.readKey(key, null, LockMode.DEFAULT);
          return entrySet;
        }
      };
  }
  /**
   *{@inheritDoc}
   * {@inheritDoc}
   */
  public IndexQuery createRangeMatchQuery(
                                              final String indexID,
                                              final byte[] lowerBound,
                                              final byte[] upperBound,
                                              final boolean includeLowerBound,
                                              final boolean includeUpperBound)
  public IndexQuery createRangeMatchQuery(final String indexID,
      final ByteSequence lowerBound, final ByteSequence upperBound,
      final boolean includeLowerBound, final boolean includeUpperBound)
  {
    return new IndexQuery()
    {
      @Override
      public EntryIDSet evaluate()
      {
        //Find the right index.
        Index index = indexMap.get(indexID);
        EntryIDSet entrySet =   index.readRange(lowerBound,upperBound,
                includeLowerBound,
            includeUpperBound);
        return entrySet;
      }
    };
        @Override
        public EntryIDSet evaluate()
        {
          // Find the right index.
          Index index = indexMap.get(indexID);
          EntryIDSet entrySet =
              index.readRange(lowerBound.toByteArray(), upperBound
                  .toByteArray(), includeLowerBound, includeUpperBound);
          return entrySet;
        }
      };
  }
  /**
   *{@inheritDoc}
   * {@inheritDoc}
   */
  public IndexQuery  createIntersectionQuery(Collection<IndexQuery>
                                                                subqueries)
  public IndexQuery createIntersectionQuery(
      Collection<IndexQuery> subqueries)
  {
    return IndexQuery.createIntersectionIndexQuery(subqueries);
  }
@@ -123,7 +129,7 @@
  /**
   *{@inheritDoc}
   * {@inheritDoc}
   */
  public IndexQuery createUnionQuery(Collection<IndexQuery> subqueries)
  {
@@ -133,20 +139,21 @@
  /**
   *{@inheritDoc}
   * It returns an empty EntryIDSet object  when either all or no record sets
   * are requested.
   * {@inheritDoc}
   * <p>
   * It returns an empty EntryIDSet object when either all or no record
   * sets are requested.
   */
  public IndexQuery createMatchAllQuery()
  {
    return new IndexQuery()
    {
      @Override
      public EntryIDSet evaluate()
      {
        return new EntryIDSet();
      }
    };
        @Override
        public EntryIDSet evaluate()
        {
          return new EntryIDSet();
        }
      };
  }
}
opends/src/server/org/opends/server/backends/jeb/IndexRebuildThread.java
@@ -389,8 +389,9 @@
        try
        {
          EntryID entryID = new EntryID(key);
          Entry entry = JebFormat.entryFromDatabase(data.getData(),
                             ec.getRootContainer().getCompressedSchema());
          Entry entry = ID2Entry.entryFromDatabase(
              ByteString.wrap(data.getData()),
              ec.getRootContainer().getCompressedSchema());
          // Insert into dn2id.
          if (dn2id.insert(txn, entry.getDN(), entryID))
@@ -472,8 +473,9 @@
        try
        {
          EntryID entryID = new EntryID(key);
          Entry entry = JebFormat.entryFromDatabase(data.getData(),
                             ec.getRootContainer().getCompressedSchema());
          Entry entry = ID2Entry.entryFromDatabase(
              ByteString.wrap(data.getData()),
              ec.getRootContainer().getCompressedSchema());
          // Insert into dn2uri.
          if (dn2uri.addEntry(txn, entry))
@@ -558,8 +560,9 @@
        try
        {
          EntryID entryID = new EntryID(key);
          Entry entry = JebFormat.entryFromDatabase(data.getData(),
                             ec.getRootContainer().getCompressedSchema());
          Entry entry = ID2Entry.entryFromDatabase(
              ByteString.wrap(data.getData()),
              ec.getRootContainer().getCompressedSchema());
          // Check that the parent entry exists.
          DN parentDN = ec.getParentWithinBase(entry.getDN());
@@ -671,8 +674,9 @@
        try
        {
          EntryID entryID = new EntryID(key);
          Entry entry = JebFormat.entryFromDatabase(data.getData(),
                             ec.getRootContainer().getCompressedSchema());
          Entry entry = ID2Entry.entryFromDatabase(
              ByteString.wrap(data.getData()),
              ec.getRootContainer().getCompressedSchema());
          // Check that the parent entry exists.
          DN parentDN = ec.getParentWithinBase(entry.getDN());
@@ -809,8 +813,9 @@
        try
        {
          EntryID entryID = new EntryID(key);
          Entry entry = JebFormat.entryFromDatabase(data.getData(),
                             ec.getRootContainer().getCompressedSchema());
          Entry entry = ID2Entry.entryFromDatabase(
              ByteString.wrap(data.getData()),
              ec.getRootContainer().getCompressedSchema());
          // Insert into attribute indexType.
          if(index.addEntry(txn, entryID, entry))
@@ -887,8 +892,9 @@
        try
        {
          EntryID entryID = new EntryID(key);
          Entry entry = JebFormat.entryFromDatabase(data.getData(),
                             ec.getRootContainer().getCompressedSchema());
          Entry entry = ID2Entry.entryFromDatabase(
              ByteString.wrap(data.getData()),
              ec.getRootContainer().getCompressedSchema());
          // Insert into attribute indexType.
          if(vlvIndex.addEntry(txn, entryID, entry))
@@ -973,8 +979,9 @@
        try
        {
          EntryID entryID = new EntryID(key);
          Entry entry = JebFormat.entryFromDatabase(data.getData(),
                             ec.getRootContainer().getCompressedSchema());
          Entry entry = ID2Entry.entryFromDatabase(
              ByteString.wrap(data.getData()),
              ec.getRootContainer().getCompressedSchema());
          // Insert into attribute indexType.
          if(index.addEntry(txn, entryID, entry))
opends/src/server/org/opends/server/backends/jeb/JECompressedSchema.java
@@ -32,31 +32,20 @@
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.io.IOException;
import org.opends.messages.Message;
import org.opends.server.api.CompressedSchema;
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.Attributes;
import org.opends.server.types.ByteArray;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ObjectClass;
import org.opends.server.protocols.asn1.*;
import org.opends.server.types.*;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.Database;
@@ -107,21 +96,22 @@
  private AtomicInteger ocCounter;
  // The map between encoded representations and attribute types.
  private ConcurrentHashMap<ByteArray,AttributeType> atDecodeMap;
  private ConcurrentHashMap<ByteSequence,AttributeType> atDecodeMap;
  // The map between encoded representations and attribute options.
  private ConcurrentHashMap<ByteArray,Set<String>> aoDecodeMap;
  private ConcurrentHashMap<ByteSequence,Set<String>> aoDecodeMap;
  // The map between encoded representations and object class sets.
  private ConcurrentHashMap<ByteArray,Map<ObjectClass,String>> ocDecodeMap;
  private ConcurrentHashMap<ByteSequence,Map<ObjectClass,String>> ocDecodeMap;
  // The map between attribute descriptions and their encoded
  // representations.
  private ConcurrentHashMap<AttributeType,
               ConcurrentHashMap<Set<String>,ByteArray>> adEncodeMap;
  private final ConcurrentHashMap<AttributeType,
                ConcurrentHashMap<Set<String>, ByteSequence>> adEncodeMap;
  // The map between object class sets and encoded representations.
  private ConcurrentHashMap<Map<ObjectClass,String>,ByteArray> ocEncodeMap;
  private final ConcurrentHashMap<Map<ObjectClass,String>,
      ByteSequence> ocEncodeMap;
  // The compressed attribute description schema database.
  private Database adDatabase;
@@ -132,6 +122,9 @@
  // The environment in which the databases are held.
  private Environment environment;
  private final ByteStringBuilder storeWriterBuffer;
  private final ASN1Writer storeWriter;
  /**
@@ -149,17 +142,21 @@
  {
    this.environment = environment;
    atDecodeMap = new ConcurrentHashMap<ByteArray,AttributeType>();
    aoDecodeMap = new ConcurrentHashMap<ByteArray,Set<String>>();
    ocDecodeMap = new ConcurrentHashMap<ByteArray,Map<ObjectClass,String>>();
    atDecodeMap = new ConcurrentHashMap<ByteSequence,AttributeType>();
    aoDecodeMap = new ConcurrentHashMap<ByteSequence,Set<String>>();
    ocDecodeMap = new ConcurrentHashMap<ByteSequence,Map<ObjectClass,String>>();
    adEncodeMap =
         new ConcurrentHashMap<AttributeType,
                  ConcurrentHashMap<Set<String>,ByteArray>>();
    ocEncodeMap = new ConcurrentHashMap<Map<ObjectClass,String>,ByteArray>();
                  ConcurrentHashMap<Set<String>, ByteSequence>>();
    ocEncodeMap = new ConcurrentHashMap<Map<ObjectClass,String>,
        ByteSequence>();
    adCounter = new AtomicInteger(1);
    ocCounter = new AtomicInteger(1);
    storeWriterBuffer = new ByteStringBuilder();
    storeWriter = ASN1.getWriter(storeWriterBuffer);
    load();
  }
@@ -211,21 +208,23 @@
                                                 LockMode.READ_UNCOMMITTED);
      while (status == OperationStatus.SUCCESS)
      {
        ByteArray token = new ByteArray(keyEntry.getData());
        highestToken = Math.max(highestToken, decodeInt(token.array()));
        byte[] tokenBytes = keyEntry.getData();
        ByteString token = ByteString.wrap(tokenBytes);
        highestToken = Math.max(highestToken, decodeInt(tokenBytes));
        ArrayList<ASN1Element> elements =
             ASN1Sequence.decodeAsSequence(valueEntry.getData()).elements();
        ASN1Reader reader =
            ASN1.getReader(valueEntry.getData());
        reader.readStartSequence();
        LinkedHashMap<ObjectClass,String> ocMap =
             new LinkedHashMap<ObjectClass,String>(elements.size());
        for (int i=0; i < elements.size(); i++)
             new LinkedHashMap<ObjectClass,String>();
        while(reader.hasNextElement())
        {
          ASN1OctetString os = elements.get(i).decodeAsOctetString();
          String ocName = os.stringValue();
          String ocName = reader.readOctetStringAsString();
          String lowerName = toLowerCase(ocName);
          ObjectClass oc = DirectoryServer.getObjectClass(lowerName, true);
          ocMap.put(oc, ocName);
        }
        reader.readEndSequence();
        ocEncodeMap.put(ocMap, token);
        ocDecodeMap.put(token, ocMap);
@@ -266,34 +265,34 @@
                                                 LockMode.READ_UNCOMMITTED);
      while (status == OperationStatus.SUCCESS)
      {
        ByteArray token = new ByteArray(keyEntry.getData());
        highestToken = Math.max(highestToken, decodeInt(token.array()));
        byte[] tokenBytes = keyEntry.getData();
        ByteString token = ByteString.wrap(tokenBytes);
        highestToken = Math.max(highestToken, decodeInt(tokenBytes));
        ArrayList<ASN1Element> elements =
             ASN1Sequence.decodeAsSequence(valueEntry.getData()).elements();
        ASN1OctetString os = elements.get(0).decodeAsOctetString();
        String attrName = os.stringValue();
        ASN1Reader reader =
            ASN1.getReader(valueEntry.getData());
        reader.readStartSequence();
        String attrName = reader.readOctetStringAsString();
        String lowerName = toLowerCase(attrName);
        AttributeType attrType =
             DirectoryServer.getAttributeType(lowerName, true);
            DirectoryServer.getAttributeType(lowerName, true);
        LinkedHashSet<String> options =
             new LinkedHashSet<String>(elements.size()-1);
        for (int i=1; i < elements.size(); i++)
            new LinkedHashSet<String>();
        while(reader.hasNextElement())
        {
          os = elements.get(i).decodeAsOctetString();
          options.add(os.stringValue());
          options.add(reader.readOctetStringAsString());
        }
        reader.readEndSequence();
        atDecodeMap.put(token, attrType);
        aoDecodeMap.put(token, options);
        ConcurrentHashMap<Set<String>,ByteArray> map =
             adEncodeMap.get(attrType);
        ConcurrentHashMap<Set<String>, ByteSequence> map = adEncodeMap
            .get(attrType);
        if (map == null)
        {
          map = new ConcurrentHashMap<Set<String>,ByteArray>(1);
          map = new ConcurrentHashMap<Set<String>, ByteSequence>(1);
          map.put(options, token);
          adEncodeMap.put(attrType, map);
        }
@@ -359,8 +358,8 @@
    atDecodeMap = null;
    aoDecodeMap = null;
    ocDecodeMap = null;
    adEncodeMap = null;
    ocEncodeMap = null;
    //adEncodeMap = null;
    //ocEncodeMap = null;
    adCounter   = null;
    ocCounter   = null;
  }
@@ -371,58 +370,45 @@
   * {@inheritDoc}
   */
  @Override()
  public byte[] encodeObjectClasses(Map<ObjectClass,String> objectClasses)
  public void encodeObjectClasses(ByteStringBuilder entryBuffer,
                                  Map<ObjectClass,String> objectClasses)
         throws DirectoryException
  {
    ByteArray encodedClasses = ocEncodeMap.get(objectClasses);
    ByteSequence encodedClasses = ocEncodeMap.get(objectClasses);
    if (encodedClasses == null)
    {
      synchronized (ocEncodeMap)
      {
        int setValue = ocCounter.getAndIncrement();
        byte[] tokenArray = encodeInt(setValue);
        encodedClasses = ByteString.wrap(tokenArray);
        ArrayList<ASN1Element> elements =
             new ArrayList<ASN1Element>(objectClasses.size());
        for (String ocName : objectClasses.values())
        {
          elements.add(new ASN1OctetString(ocName));
        }
        byte[] encodedOCs = new ASN1Sequence(elements).encode();
        store(ocDatabase, tokenArray, encodedOCs);
        encodedClasses = new ByteArray(tokenArray);
        storeObjectClass(tokenArray, objectClasses);
        ocEncodeMap.put(objectClasses, encodedClasses);
        ocDecodeMap.put(encodedClasses, objectClasses);
        return tokenArray;
      }
    }
    else
    {
      return encodedClasses.array();
    }
    entryBuffer.appendBERLength(encodedClasses.length());
    encodedClasses.copyTo(entryBuffer);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public Map<ObjectClass,String> decodeObjectClasses(
                                      byte[] encodedObjectClasses)
         throws DirectoryException
      ByteSequenceReader entryBufferReader) throws DirectoryException
  {
    ByteArray byteArray = new ByteArray(encodedObjectClasses);
    int tokenLength = entryBufferReader.getBERLength();
    ByteSequence byteArray = entryBufferReader.getByteSequence(tokenLength);
    Map<ObjectClass,String> ocMap = ocDecodeMap.get(byteArray);
    if (ocMap == null)
    {
      Message message = ERR_JEB_COMPSCHEMA_UNKNOWN_OC_TOKEN.get(
                             bytesToHex(encodedObjectClasses));
      Message message = ERR_JEB_COMPSCHEMA_UNKNOWN_OC_TOKEN.get(byteArray
          .toByteString().toHex());
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
                                   message);
          message);
    }
    else
    {
@@ -430,52 +416,90 @@
    }
  }
  private void storeObjectClass(byte[] token,
                                Map<ObjectClass,String> objectClasses)
      throws DirectoryException
  {
    synchronized(storeWriter)
    {
      try
      {
        storeWriterBuffer.clear();
        storeWriter.writeStartSequence();
        for (String ocName : objectClasses.values())
        {
          storeWriter.writeOctetString(ocName);
        }
        storeWriter.writeEndSequence();
        store(ocDatabase, token, storeWriterBuffer);
      }
      catch(IOException ioe)
      {
        // TODO: Shouldn't happen but should log a message
      }
    }
  }
  private void storeAttribute(byte[] token,
                              AttributeType attrType, Set<String> options)
      throws DirectoryException
  {
    synchronized(storeWriter)
    {
      try
      {
        storeWriterBuffer.clear();
        storeWriter.writeStartSequence();
        storeWriter.writeOctetString(attrType.getNameOrOID());
        for (String option : options)
        {
          storeWriter.writeOctetString(option);
        }
        storeWriter.writeEndSequence();
        store(adDatabase, token, storeWriterBuffer);
      }
      catch(IOException ioe)
      {
        // TODO: Shouldn't happen but should log a message
      }
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public byte[] encodeAttribute(Attribute attribute)
         throws DirectoryException
  public void encodeAttribute(ByteStringBuilder entryBuffer,
                              Attribute attribute) throws DirectoryException
  {
    AttributeType type = attribute.getAttributeType();
    Set<String> options = attribute.getOptions();
    ConcurrentHashMap<Set<String>,ByteArray> map =
         adEncodeMap.get(type);
    ConcurrentHashMap<Set<String>, ByteSequence> map = adEncodeMap.get(type);
    if (map == null)
    {
      byte[] tokenArray;
      ByteString byteString;
      synchronized (adEncodeMap)
      {
        map = new ConcurrentHashMap<Set<String>,ByteArray>(1);
        map = new ConcurrentHashMap<Set<String>, ByteSequence>(1);
        int intValue = adCounter.getAndIncrement();
        tokenArray = encodeInt(intValue);
        ByteArray byteArray = new ByteArray(tokenArray);
        map.put(options,byteArray);
        byteString = ByteString.wrap(tokenArray);
        map.put(options,byteString);
        ArrayList<ASN1Element> elements =
             new ArrayList<ASN1Element>(options.size()+1);
        elements.add(new ASN1OctetString(attribute.getName()));
        for (String option : options)
        {
          elements.add(new ASN1OctetString(option));
        }
        byte[] encodedValue = new ASN1Sequence(elements).encode();
        store(adDatabase, tokenArray, encodedValue);
        storeAttribute(tokenArray, type, options);
        adEncodeMap.put(type, map);
        atDecodeMap.put(byteArray, type);
        aoDecodeMap.put(byteArray, options);
        atDecodeMap.put(byteString, type);
        aoDecodeMap.put(byteString, options);
      }
      return encodeAttribute(tokenArray, attribute);
      encodeAttribute(entryBuffer, byteString, attribute);
    }
    else
    {
      ByteArray byteArray = map.get(options);
      ByteSequence byteArray = map.get(options);
      if (byteArray == null)
      {
        byte[] tokenArray;
@@ -483,29 +507,16 @@
        {
          int intValue = adCounter.getAndIncrement();
          tokenArray = encodeInt(intValue);
          byteArray = new ByteArray(tokenArray);
          byteArray = ByteString.wrap(tokenArray);
          map.put(options,byteArray);
          ArrayList<ASN1Element> elements =
               new ArrayList<ASN1Element>(options.size()+1);
          elements.add(new ASN1OctetString(attribute.getName()));
          for (String option : options)
          {
            elements.add(new ASN1OctetString(option));
          }
          byte[] encodedValue = new ASN1Sequence(elements).encode();
          store(adDatabase, tokenArray, encodedValue);
          storeAttribute(tokenArray, type, options);
          atDecodeMap.put(byteArray, type);
          aoDecodeMap.put(byteArray, options);
        }
      }
        return encodeAttribute(tokenArray, attribute);
      }
      else
      {
        return encodeAttribute(byteArray.array(), attribute);
      }
      encodeAttribute(entryBuffer, byteArray, attribute);
    }
  }
@@ -515,126 +526,70 @@
   * Encodes the information in the provided attribute to a byte
   * array.
   *
   * @param  buffer     The byte buffer to encode the attribute into.
   * @param  adArray    The byte array that is a placeholder for the
   *                    attribute type and set of options.
   * @param  attribute  The attribute to be encoded.
   *
   * @return  An encoded representation of the provided attribute.
   */
  private byte[] encodeAttribute(byte[] adArray, Attribute attribute)
  private void encodeAttribute(ByteStringBuilder buffer, ByteSequence adArray,
                                 Attribute attribute)
  {
    int totalValuesLength = 0;
    byte[][] subArrays = new  byte[attribute.size()*2][];
    int pos = 0;
    for (AttributeValue v : attribute)
    // Write the length of the adArray followed by the adArray.
    buffer.appendBERLength(adArray.length());
    adArray.copyTo(buffer);
    // Write the number of attributes
    buffer.appendBERLength(attribute.size());
    // Write the attribute values as length / value pairs
    for(AttributeValue v : attribute)
    {
      byte[] vBytes = v.getValueBytes();
      byte[] lBytes = ASN1Element.encodeLength(vBytes.length);
      subArrays[pos++] = lBytes;
      subArrays[pos++] = vBytes;
      totalValuesLength += lBytes.length + vBytes.length;
      buffer.appendBERLength(v.getValue().length());
      buffer.append(v.getValue());
    }
    byte[] adArrayLength = ASN1Element.encodeLength(adArray.length);
    byte[] countBytes = ASN1Element.encodeLength(attribute.size());
    int totalLength = adArrayLength.length + adArray.length +
                      countBytes.length + totalValuesLength;
    byte[] array = new byte[totalLength];
    System.arraycopy(adArrayLength, 0, array, 0,
                     adArrayLength.length);
    pos = adArrayLength.length;
    System.arraycopy(adArray, 0, array, pos, adArray.length);
    pos += adArray.length;
    System.arraycopy(countBytes, 0, array, pos, countBytes.length);
    pos += countBytes.length;
    for (int i=0; i < subArrays.length; i++)
    {
      System.arraycopy(subArrays[i], 0, array, pos,
                       subArrays[i].length);
      pos += subArrays[i].length;
    }
    return array;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public Attribute decodeAttribute(byte[] encodedEntry, int startPos,
                                   int length)
  public Attribute decodeAttribute(ByteSequenceReader entryBufferReader)
         throws DirectoryException
  {
    // Figure out how many bytes are in the token that is the placeholder for
    // the attribute description.
    int pos = startPos;
    int adArrayLength = encodedEntry[pos] & 0x7F;
    if (adArrayLength != encodedEntry[pos++])
    {
      int numLengthBytes = adArrayLength;
      adArrayLength = 0;
      for (int i=0; i < numLengthBytes; i++, pos++)
      {
        adArrayLength = (adArrayLength << 8) | (encodedEntry[pos] & 0xFF);
      }
    }
    int adArrayLength = entryBufferReader.getBERLength();
    // Get the attribute description token and make sure it resolves to an
    // attribute type and option set.
    ByteArray adArray = new ByteArray(new byte[adArrayLength]);
    System.arraycopy(encodedEntry, pos, adArray.array(), 0, adArrayLength);
    pos += adArrayLength;
    ByteSequence adArray = entryBufferReader.getByteSequence(adArrayLength);
    AttributeType attrType = atDecodeMap.get(adArray);
    Set<String> options = aoDecodeMap.get(adArray);
    if ((attrType == null) || (options == null))
    {
      Message message = ERR_JEB_COMPSCHEMA_UNRECOGNIZED_AD_TOKEN.get(
                             bytesToHex(adArray.array()));
      Message message = ERR_JEB_COMPSCHEMA_UNRECOGNIZED_AD_TOKEN.get(adArray
          .toByteString().toHex());
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
                                   message);
          message);
    }
    // Determine the number of values for the attribute.
    int numValues = encodedEntry[pos] & 0x7F;
    if (numValues != encodedEntry[pos++])
    {
      int numValuesBytes = numValues;
      numValues = 0;
      for (int i=0; i < numValuesBytes; i++, pos++)
      {
        numValues = (numValues << 8) | (encodedEntry[pos] & 0xFF);
      }
    }
    int numValues = entryBufferReader.getBERLength();
    // For the common case of a single value with no options, generate
    // less garbage.
    if (numValues == 1 && options.isEmpty())
    {
      int valueLength = encodedEntry[pos] & 0x7F;
      if (valueLength != encodedEntry[pos++])
      {
        int valueLengthBytes = valueLength;
        valueLength = 0;
        for (int j = 0; j < valueLengthBytes; j++, pos++)
        {
          valueLength = (valueLength << 8) | (encodedEntry[pos] & 0xFF);
        }
      }
      int valueLength = entryBufferReader.getBERLength();
      byte[] valueBytes = new byte[valueLength];
      System.arraycopy(encodedEntry, pos, valueBytes, 0, valueLength);
      return Attributes.create(attrType, new AttributeValue(attrType,
          new ASN1OctetString(valueBytes)));
      ByteString valueBytes =
          entryBufferReader.getByteSequence(valueLength).toByteString();
      return Attributes.create(attrType,
          AttributeValues.create(attrType, valueBytes));
    }
    else
    {
@@ -644,30 +599,18 @@
      builder.setInitialCapacity(numValues);
      for (int i = 0; i < numValues; i++)
      {
        int valueLength = encodedEntry[pos] & 0x7F;
        if (valueLength != encodedEntry[pos++])
        {
          int valueLengthBytes = valueLength;
          valueLength = 0;
          for (int j = 0; j < valueLengthBytes; j++, pos++)
          {
            valueLength = (valueLength << 8) | (encodedEntry[pos] & 0xFF);
          }
        }
        int valueLength = entryBufferReader.getBERLength();
        byte[] valueBytes = new byte[valueLength];
        System.arraycopy(encodedEntry, pos, valueBytes, 0, valueLength);
        pos += valueLength;
        builder.add(new AttributeValue(attrType,
            new ASN1OctetString(valueBytes)));
        ByteString valueBytes =
            entryBufferReader.getByteSequence(valueLength).toByteString();
        builder.add(AttributeValues.create(attrType,
            valueBytes));
      }
      return builder.toAttribute();
    }
  }
  /**
   * Stores the provided key-value pair in the specified database container.
   *
@@ -678,12 +621,14 @@
   * @throws  DirectoryException  If a problem occurs while attempting to store
   *                              the data.
   */
  private void store(Database database, byte[] keyBytes, byte[] valueBytes)
  private void store(Database database, byte[] keyBytes,
                     ByteStringBuilder valueBytes)
          throws DirectoryException
  {
    boolean successful = false;
    DatabaseEntry keyEntry   = new DatabaseEntry(keyBytes);
    DatabaseEntry valueEntry = new DatabaseEntry(valueBytes);
    DatabaseEntry valueEntry = new DatabaseEntry(valueBytes.getBackingArray(),
        0, valueBytes.length());
    for (int i=0; i < 3; i++)
    {
opends/src/server/org/opends/server/backends/jeb/JEExtensibleIndexer.java
@@ -73,13 +73,6 @@
  /**
   * The extensible matching rule which needs to be indexed.
   */
  private final ExtensibleMatchingRule matchingRule;
  /**
   * Creates a new extensible indexer for JE backend.
   *
   * @param attributeType The attribute type for which an indexer is
@@ -92,7 +85,6 @@
          ExtensibleIndexer extensibleIndexer)
  {
    this.attributeType = attributeType;
    this.matchingRule = matchingRule;
    this.extensibleIndexer = extensibleIndexer;
  }
@@ -118,6 +110,7 @@
   *
   * @return A byte array comparator.
   */
  @Override
  public Comparator<byte[]> getComparator()
  {
    return comparator;
opends/src/server/org/opends/server/backends/jeb/JebFormat.java
@@ -26,23 +26,9 @@
 */
package org.opends.server.backends.jeb;
import org.opends.server.api.CompressedSchema;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1Integer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.types.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.DataFormatException;
/**
 * Handles the disk representation of LDAP data.
 */
@@ -70,219 +56,6 @@
  public static final byte TAG_DIRECTORY_SERVER_ENTRY = 0x61;
  /**
   * Decode a DatabaseEntry.  The encoded bytes may be compressed and/or
   * encrypted.
   *
   * @param bytes The encoded bytes of a DatabaseEntry.
   * @return The decoded bytes.
   * @throws ASN1Exception If the data is not in the expected ASN.1 encoding
   * format.
   * @throws DataFormatException If an error occurs while trying to decompress
   * compressed data.
   */
  static public byte[] decodeDatabaseEntry(byte[] bytes)
       throws ASN1Exception,DataFormatException
  {
    // FIXME: This array copy could be very costly on performance. We need to
    // FIXME: find a faster way to implement this versioning feature.
    // Remove version number from the encoded bytes
    byte[] encodedBytes = new byte[bytes.length - 1];
    System.arraycopy(bytes, 1, encodedBytes, 0, encodedBytes.length);
    // Decode the sequence.
    List<ASN1Element> elements;
    elements = ASN1Sequence.decodeAsSequence(encodedBytes).elements();
    // Decode the uncompressed size.
    int uncompressedSize;
    uncompressedSize = elements.get(0).decodeAsInteger().intValue();
    // Decode the data bytes.
    byte[] dataBytes;
    dataBytes = elements.get(1).decodeAsOctetString().value();
    byte[] uncompressedBytes;
    if (uncompressedSize == 0)
    {
      // The bytes are not compressed.
      uncompressedBytes = dataBytes;
    }
    else
    {
      // The bytes are compressed.
      CryptoManager cryptoManager = DirectoryServer.getCryptoManager();
      uncompressedBytes = new byte[uncompressedSize];
      /* int len = */ cryptoManager.uncompress(dataBytes, uncompressedBytes);
    }
    return uncompressedBytes;
  }
  /**
   * Decodes an entry from its database representation.
   * <p>
   * An entry on disk is ASN1 encoded in this format:
   *
   * <pre>
   * DatabaseEntry ::= [APPLICATION 0] IMPLICIT SEQUENCE {
   *  uncompressedSize      INTEGER,      -- A zero value means not compressed.
   *  dataBytes             OCTET STRING  -- Optionally compressed encoding of
   *                                         the data bytes.
   * }
   *
   * ID2EntryValue ::= DatabaseEntry
   *  -- Where dataBytes contains an encoding of DirectoryServerEntry.
   *
   * DirectoryServerEntry ::= [APPLICATION 1] IMPLICIT SEQUENCE {
   *  dn                      LDAPDN,
   *  objectClasses           SET OF LDAPString,
   *  userAttributes          AttributeList,
   *  operationalAttributes   AttributeList
   * }
   * </pre>
   *
   * @param bytes A byte array containing the encoded database value.
   * @param compressedSchema The compressed schema manager to use when decoding.
   * @return The decoded entry.
   * @throws ASN1Exception If the data is not in the expected ASN.1 encoding
   * format.
   * @throws LDAPException If the data is not in the expected ASN.1 encoding
   * format.
   * @throws DataFormatException If an error occurs while trying to decompress
   * compressed data.
   * @throws DirectoryException If a Directory Server error occurs.
   */
  static public Entry entryFromDatabase(byte[] bytes,
                                        CompressedSchema compressedSchema)
       throws DirectoryException,ASN1Exception,LDAPException,DataFormatException
  {
    byte[] uncompressedBytes = decodeDatabaseEntry(bytes);
    return decodeDirectoryServerEntry(uncompressedBytes, compressedSchema);
  }
  /**
   * Decode an entry from a ASN1 encoded DirectoryServerEntry.
   *
   * @param bytes A byte array containing the encoding of DirectoryServerEntry.
   * @param compressedSchema The compressed schema manager to use when decoding.
   * @return The decoded entry.
   * @throws ASN1Exception If the data is not in the expected ASN.1 encoding
   * format.
   * @throws LDAPException If the data is not in the expected ASN.1 encoding
   * format.
   * @throws DirectoryException If a Directory Server error occurs.
   */
  static private Entry decodeDirectoryServerEntry(byte[] bytes,
                            CompressedSchema compressedSchema)
       throws DirectoryException,ASN1Exception,LDAPException
  {
    return Entry.decode(bytes, compressedSchema);
  }
  /**
   * Encodes a DatabaseEntry.  The encoded bytes may be compressed and/or
   * encrypted.
   *
   * @param bytes The bytes to encode.
   * @param dataConfig Compression and cryptographic options.
   * @return A byte array containing the encoded DatabaseEntry.
   */
  static public byte[] encodeDatabaseEntry(byte[] bytes, DataConfig dataConfig)
  {
    int uncompressedSize = 0;
    // Do optional compression.
    CryptoManager cryptoManager = DirectoryServer.getCryptoManager();
    if (dataConfig.isCompressed() && cryptoManager != null)
    {
      byte[] compressedBuffer = new byte[bytes.length];
      int compressedSize = cryptoManager.compress(bytes,
                                                  compressedBuffer);
      if (compressedSize != -1)
      {
        // Compression was successful.
        uncompressedSize = bytes.length;
        bytes = new byte[compressedSize];
        System.arraycopy(compressedBuffer, 0, bytes, 0, compressedSize);
        if(debugEnabled())
        {
          TRACER.debugInfo("Compression %d/%d%n",
                    compressedSize, uncompressedSize);
        }
      }
    }
    // Encode the DatabaseEntry.
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2);
    elements.add(new ASN1Integer(uncompressedSize));
    elements.add(new ASN1OctetString(bytes));
    byte[] asn1Sequence =
        new ASN1Sequence(TAG_DATABASE_ENTRY, elements).encode();
    // FIXME: This array copy could be very costly on performance. We need to
    // FIXME: find a faster way to implement this versioning feature.
    // Prefix version number to the encoded bytes
    byte[] encodedBytes = new byte[asn1Sequence.length + 1];
    encodedBytes[0] = FORMAT_VERSION;
    System.arraycopy(asn1Sequence, 0, encodedBytes, 1, asn1Sequence.length);
    return encodedBytes;
  }
  /**
   * Encodes an entry to the raw database format, with optional compression.
   *
   * @param entry The entry to encode.
   * @param dataConfig Compression and cryptographic options.
   * @return A byte array containing the encoded database value.
   *
   * @throws  DirectoryException  If a problem occurs while attempting to encode
   *                              the entry.
   */
  static public byte[] entryToDatabase(Entry entry, DataConfig dataConfig)
         throws DirectoryException
  {
    byte[] uncompressedBytes = encodeDirectoryServerEntry(entry,
                                             dataConfig.getEntryEncodeConfig());
    return encodeDatabaseEntry(uncompressedBytes, dataConfig);
  }
  /**
   * Encodes an entry to the raw database format, without compression.
   *
   * @param entry The entry to encode.
   * @return A byte array containing the encoded database value.
   *
   * @throws  DirectoryException  If a problem occurs while attempting to encode
   *                              the entry.
   */
  static public byte[] entryToDatabase(Entry entry)
         throws DirectoryException
  {
    return entryToDatabase(entry, new DataConfig(false, false, null));
  }
  /**
   * Encode a ASN1 DirectoryServerEntry.
   *
   * @param entry The entry to encode.
   * @encodeConfig The configuration to use when encoding the entry.
   * @return A byte array containing the encoded DirectoryServerEntry.
   *
   * @throws  DirectoryException  If a problem occurs while attempting to encode
   *                              the entry.
   */
  static private byte[] encodeDirectoryServerEntry(Entry entry,
                                                 EntryEncodeConfig encodeConfig)
         throws DirectoryException
  {
    return entry.encode(encodeConfig);
  }
  /**
   * Decode an entry ID value from its database representation. Note that
   * this method will throw an ArrayIndexOutOfBoundsException if the bytes
   * array length is less than 8.
@@ -454,16 +227,4 @@
    return bytes;
  }
   /**
   * Get the version number of the DatabaseEntry.
   *
   * @param bytes The encoded bytes of a DatabaseEntry.
   * @return The version number.
   */
  public static byte getEntryVersion(byte[] bytes)
  {
    return bytes[0];
  }
}
opends/src/server/org/opends/server/backends/jeb/OctetStringKeyComparator.java
File was deleted
opends/src/server/org/opends/server/backends/jeb/OrderingIndexer.java
@@ -170,7 +170,7 @@
        try
        {
          byte[] keyBytes = orderingRule.normalizeValue(value.getValue())
              .value();
              .toByteArray();
          keys.add(keyBytes);
        }
@@ -207,7 +207,7 @@
        try
        {
          byte[] keyBytes =
               orderingRule.normalizeValue(value.getValue()).value();
               orderingRule.normalizeValue(value.getValue()).toByteArray();
          Boolean cInsert = modifiedKeys.get(keyBytes);
          if(cInsert == null)
opends/src/server/org/opends/server/backends/jeb/SortValues.java
@@ -250,7 +250,7 @@
      }
      else
      {
        buffer.append(values[i].getStringValue());
        buffer.append(values[i].getValue().toString());
      }
    }
opends/src/server/org/opends/server/backends/jeb/SortValuesSet.java
@@ -27,15 +27,11 @@
package org.opends.server.backends.jeb;
import org.opends.server.types.*;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Element;
import java.util.LinkedList;
import com.sleepycat.je.DatabaseException;
/**
 * This class representsa  partial sorted set of sorted entries in a VLV
 * This class represents a partial sorted set of sorted entries in a VLV
 * index.
 */
public class SortValuesSet
@@ -469,35 +465,23 @@
  private byte[] attributeValuesToDatabase(AttributeValue[] values)
      throws DirectoryException
  {
    int totalValueBytes = 0;
    LinkedList<byte[]> valueBytes = new LinkedList<byte[]>();
    ByteStringBuilder builder = new ByteStringBuilder();
    for (AttributeValue v : values)
    {
      byte[] vBytes;
      if(v == null)
      {
        vBytes = new byte[0];
        builder.appendBERLength(0);
      }
      else
      {
        vBytes = v.getNormalizedValueBytes();
        builder.appendBERLength(v.getNormalizedValue().length());
        builder.append(v.getNormalizedValue());
      }
      byte[] vLength = ASN1Element.encodeLength(vBytes.length);
      valueBytes.add(vLength);
      valueBytes.add(vBytes);
      totalValueBytes += vLength.length + vBytes.length;
    }
    builder.trimToSize();
    byte[] attrBytes = new byte[totalValueBytes];
    int pos = 0;
    for (byte[] b : valueBytes)
    {
      System.arraycopy(b, 0, attrBytes, pos, b.length);
      pos += b.length;
    }
    return attrBytes;
    return builder.getBackingArray();
  }
  /**
@@ -570,8 +554,9 @@
         i < entryIDs.length * numValues;
         i++, j++)
    {
      values[j] = new AttributeValue(sortKeys[j].getAttributeType(),
                                     new ASN1OctetString(getValue(i)));
      values[j] = AttributeValues.create(
          sortKeys[j].getAttributeType(),
          getValue(i));
    }
    return new SortValues(id, values, vlvIndex.sortOrder);
@@ -603,12 +588,12 @@
         i < (index + 1) * numValues;
         i++, j++)
    {
      byte[] value = getValue(i);
      ByteString value = getValue(i);
      if(value != null)
      {
        values[j] = new AttributeValue(sortKeys[j].getAttributeType(),
                                       new ASN1OctetString(value));
        values[j] = AttributeValues.create(
            sortKeys[j].getAttributeType(), value);
      }
    }
@@ -653,7 +638,7 @@
   * @throws DirectoryException If a Directory Server error occurs.
   * @throws DatabaseException If an error occurs in the JE database.
   */
  public byte[] getValue(int index)
  public ByteString getValue(int index)
      throws DatabaseException, DirectoryException
  {
    if(valuesBytesOffsets == null)
@@ -689,7 +674,7 @@
        {
          byte[] valueBytes = new byte[valueLength];
          System.arraycopy(valuesBytes, vBytesPos, valueBytes, 0, valueLength);
          return valueBytes;
          return ByteString.wrap(valueBytes);
        }
      }
      else
@@ -697,6 +682,6 @@
        vBytesPos += valueLength;
      }
    }
    return new byte[0];
    return ByteString.wrap(new byte[0]);
  }
}
opends/src/server/org/opends/server/backends/jeb/SubstringIndexer.java
@@ -168,7 +168,7 @@
      {
        try
        {
          byte[] normalizedBytes = value.getNormalizedValue().value();
          byte[] normalizedBytes = value.getNormalizedValue().toByteArray();
          substringKeys(normalizedBytes, keys);
        }
@@ -245,7 +245,7 @@
      {
        try
        {
          byte[] normalizedBytes = value.getNormalizedValue().value();
          byte[] normalizedBytes = value.getNormalizedValue().toByteArray();
          substringKeys(normalizedBytes, modifiedKeys, insert);
        }
opends/src/server/org/opends/server/backends/jeb/VLVIndex.java
@@ -51,8 +51,6 @@
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.config.ConfigException;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.controls.VLVRequestControl;
import org.opends.server.controls.VLVResponseControl;
@@ -1296,13 +1294,13 @@
        try
        {
          byte[] vBytes = vlvRequest.getGreaterThanOrEqualAssertion().value();
          byte[] vLength = ASN1Element.encodeLength(vBytes.length);
          byte[] keyBytes = new byte[vBytes.length + vLength.length];
          System.arraycopy(vLength, 0, keyBytes, 0, vLength.length);
          System.arraycopy(vBytes, 0, keyBytes, vLength.length, vBytes.length);
          ByteSequence vBytes = vlvRequest.getGreaterThanOrEqualAssertion();
          ByteStringBuilder keyBytes =
              new ByteStringBuilder(vBytes.length() + 4);
          keyBytes.appendBERLength(vBytes.length());
          vBytes.copyTo(keyBytes);
          key.setData(keyBytes);
          key.setData(keyBytes.getBackingArray(), 0, keyBytes.length());
          status = cursor.getSearchKeyRange(key, data, lockMode);
          if(status == OperationStatus.SUCCESS)
          {
@@ -1324,9 +1322,9 @@
                new SortValuesSet(key.getData(), data.getData(), this);
            AttributeValue[] assertionValue = new AttributeValue[1];
            assertionValue[0] =
                new AttributeValue(
                AttributeValues.create(
                    sortOrder.getSortKeys()[0].getAttributeType(),
                    vlvRequest.getGreaterThanOrEqualAssertion());
                        vlvRequest.getGreaterThanOrEqualAssertion());
            int adjustedTargetOffset =
                sortValuesSet.binarySearch(-1, assertionValue);
@@ -1582,39 +1580,25 @@
  byte[] encodeKey(long entryID, AttributeValue[] values)
      throws DirectoryException
  {
    int totalValueBytes = 0;
    LinkedList<byte[]> valueBytes = new LinkedList<byte[]>();
    ByteStringBuilder builder = new ByteStringBuilder();
    for (AttributeValue v : values)
    {
      byte[] vBytes;
      if(v == null)
      {
        vBytes = new byte[0];
        builder.appendBERLength(0);
      }
      else
      {
        vBytes = v.getNormalizedValueBytes();
        builder.appendBERLength(v.getNormalizedValue().length());
        builder.append(v.getNormalizedValue());
      }
      byte[] vLength = ASN1Element.encodeLength(vBytes.length);
      valueBytes.add(vLength);
      valueBytes.add(vBytes);
      totalValueBytes += vLength.length + vBytes.length;
    }
    builder.append(entryID);
    builder.trimToSize();
    byte[] entryIDBytes =
        JebFormat.entryIDToDatabase(entryID);
    byte[] attrBytes = new byte[entryIDBytes.length + totalValueBytes];
    int pos = 0;
    for (byte[] b : valueBytes)
    {
      System.arraycopy(b, 0, attrBytes, pos, b.length);
      pos += b.length;
    }
    System.arraycopy(entryIDBytes, 0, attrBytes, pos, entryIDBytes.length);
    return attrBytes;
    return builder.getBackingArray();
  }
  /**
@@ -1658,8 +1642,9 @@
        byte[] valueBytes = new byte[valueLength];
        System.arraycopy(keyBytes, vBytesPos, valueBytes, 0, valueLength);
        attributeValues[i] =
            new AttributeValue(sortOrder.getSortKeys()[i].getAttributeType(),
                new ASN1OctetString(valueBytes));
            AttributeValues.create(
                sortOrder.getSortKeys()[i].getAttributeType(),
                ByteString.wrap(valueBytes));
      }
      vBytesPos += valueLength;
opends/src/server/org/opends/server/backends/jeb/VLVKeyComparator.java
@@ -29,6 +29,7 @@
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ByteString;
import java.util.Comparator;
import java.io.Serializable;
@@ -282,12 +283,12 @@
        break;
      }
      byte[] b1Bytes = set.getValue((index * orderingRules.length) + j);
      byte[] b2Bytes = null;
      ByteString b1Bytes = set.getValue((index * orderingRules.length) + j);
      ByteString b2Bytes = null;
      if(values[j] != null)
      {
        b2Bytes = values[j].getNormalizedValueBytes();
        b2Bytes = values[j].getNormalizedValue();
      }
      // A null value will always come after a non-null value.
@@ -310,11 +311,11 @@
      int result;
      if(ascending[j])
      {
        result = orderingRules[j].compare(b1Bytes, b2Bytes);
        result = orderingRules[j].compareValues(b1Bytes, b2Bytes);
      }
      else
      {
        result = orderingRules[j].compare(b2Bytes, b1Bytes);
        result = orderingRules[j].compareValues(b2Bytes, b1Bytes);
      }
      if(result != 0)
opends/src/server/org/opends/server/backends/jeb/VerifyJob.java
@@ -44,7 +44,6 @@
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.api.ApproximateMatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.util.StaticUtils;
import org.opends.server.util.ServerConstants;
@@ -472,8 +471,9 @@
        Entry entry;
        try
        {
          entry = JebFormat.entryFromDatabase(data.getData(),
                                 rootContainer.getCompressedSchema());
          entry = ID2Entry.entryFromDatabase(
              ByteString.wrap(data.getData()),
              rootContainer.getCompressedSchema());
        }
        catch (Exception e)
        {
@@ -578,7 +578,7 @@
        DN dn;
        try
        {
          dn = DN.decode(new ASN1OctetString(key.getData()));
          dn = DN.decode(ByteString.wrap(key.getData()));
        }
        catch (DirectoryException e)
        {
@@ -955,7 +955,7 @@
      hashMap = new HashMap<ByteString, Long>();
      entryLimitMap.put(index, hashMap);
    }
    ByteString octetString = new ASN1OctetString(key);
    ByteString octetString = ByteString.wrap(key);
    Long counter = hashMap.get(octetString);
    if (counter == null)
    {
@@ -1142,7 +1142,7 @@
          attrType.getOrderingMatchingRule();
      ApproximateMatchingRule approximateMatchingRule =
          attrType.getApproximateMatchingRule();
      ASN1OctetString previousValue = null;
      ByteString previousValue = null;
      OperationStatus status;
      for (status = cursor.getFirst(key, data, LockMode.DEFAULT);
@@ -1184,7 +1184,7 @@
            case SUBSTRING:
              ArrayList<ByteString> subAnyElements =
                   new ArrayList<ByteString>(1);
              subAnyElements.add(new ASN1OctetString(value));
              subAnyElements.add(ByteString.wrap(value));
              sf = SearchFilter.createSubstringFilter(attrType,null,
                                                      subAnyElements,null);
@@ -1197,13 +1197,14 @@
              // 2. Make sure the key value is greater then the previous key
              //    value.
              assertionValue =
                  new AttributeValue(attrType, new ASN1OctetString(value));
                  AttributeValues.create(attrType,
                      ByteString.wrap(value));
              sf = SearchFilter.createEqualityFilter(attrType,assertionValue);
              if(orderingMatchingRule != null && previousValue != null)
              {
                ASN1OctetString thisValue = new ASN1OctetString(value);
                ByteString thisValue = ByteString.wrap(value);
                int order = orderingMatchingRule.compareValues(thisValue,
                                                               previousValue);
                if(order > 0)
@@ -1214,8 +1215,8 @@
                    TRACER.debugError("Reversed ordering of index keys " +
                        "(keys dumped in the order found in database)%n" +
                        "Key 1:%n%s%nKey 2:%n%s",
                               keyDump(index, thisValue.value()),
                               keyDump(index,previousValue.value()));
                               keyDump(index, thisValue.toByteArray()),
                               keyDump(index,previousValue.toByteArray()));
                  }
                  continue;
                }
@@ -1225,8 +1226,9 @@
                  if(debugEnabled())
                  {
                    TRACER.debugError("Duplicate index keys%nKey 1:%n%s%n" +
                        "Key2:%n%s", keyDump(index, thisValue.value()),
                                     keyDump(index,previousValue.value()));
                        "Key2:%n%s", keyDump(index, thisValue.toByteArray()),
                                     keyDump(index,
                                         previousValue.toByteArray()));
                  }
                  continue;
                }
@@ -1238,7 +1240,8 @@
              break;
            case EQ:
              assertionValue =
                   new AttributeValue(attrType, new ASN1OctetString(value));
                  AttributeValues.create(attrType,
                      ByteString.wrap(value));
              sf = SearchFilter.createEqualityFilter(attrType,assertionValue);
              break;
@@ -1310,7 +1313,7 @@
              }
              else
              {
                ByteString normalizedValue = new ASN1OctetString(value);
                ByteString normalizedValue = ByteString.wrap(value);
                List<Attribute> attrs = entry.getAttribute(attrType);
                if ((attrs != null) && (!attrs.isEmpty()))
                {
@@ -1839,7 +1842,7 @@
      {
        for (AttributeValue value : attr)
        {
          byte[] normalizedBytes = value.getNormalizedValue().value();
          byte[] normalizedBytes = value.getNormalizedValue().toByteArray();
          // Equality index.
          if (equalityIndex != null)
@@ -1886,7 +1889,7 @@
            DatabaseEntry key = new DatabaseEntry();
            for (ByteString keyBytes : keyBytesSet)
            {
              key.setData(keyBytes.value());
              key.setData(keyBytes.toByteArray());
              try
              {
                ConditionResult cr;
@@ -1929,7 +1932,7 @@
                 attr.getAttributeType().getOrderingMatchingRule();
            normalizedBytes =
                 orderingRule.normalizeValue(value.getValue()).value();
                 orderingRule.normalizeValue(value.getValue()).toByteArray();
            DatabaseEntry key = new DatabaseEntry(normalizedBytes);
            try
@@ -1972,7 +1975,7 @@
                attr.getAttributeType().getApproximateMatchingRule();
            normalizedBytes =
                approximateRule.normalizeValue(value.getValue()).value();
                approximateRule.normalizeValue(value.getValue()).toByteArray();
            DatabaseEntry key = new DatabaseEntry(normalizedBytes);
            try
opends/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java
@@ -42,7 +42,6 @@
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.backends.jeb.*;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.messages.Message;
import org.opends.messages.JebMessages;
import static org.opends.messages.JebMessages.*;
@@ -868,7 +867,7 @@
              message = ERR_JEB_IMPORT_NO_WORKER_THREADS.get();
              throw new JebException(message);
            }
            DN dn = DN.decode(new ASN1OctetString(key.getData()));
            DN dn = DN.decode(ByteString.wrap(key.getData()));
            if(!context.getIncludeBranches().contains(dn)) {
              EntryID id = new EntryID(data);
              Entry entry =
opends/src/server/org/opends/server/backends/task/RecurringTask.java
@@ -76,23 +76,23 @@
  // The DN of the entry that actually defines this task.
  private DN recurringTaskEntryDN;
  private final DN recurringTaskEntryDN;
  // The entry that actually defines this task.
  private Entry recurringTaskEntry;
  private final Entry recurringTaskEntry;
  // The unique ID for this recurring task.
  private String recurringTaskID;
  private final String recurringTaskID;
  // The fully-qualified name of the class that will be used to implement the
  // class.
  private String taskClassName;
  private final String taskClassName;
  // Task instance.
  private Task task;
  // Task scheduler for this task.
  private TaskScheduler taskScheduler;
  private final TaskScheduler taskScheduler;
  // Number of tokens in the task schedule tab.
  private static final int TASKTAB_NUM_TOKENS = 5;
@@ -180,7 +180,7 @@
      throw new DirectoryException(ResultCode.OBJECTCLASS_VIOLATION, message);
    }
    recurringTaskID = value.getStringValue();
    recurringTaskID = value.getValue().toString();
    // Get the schedule for this task.
@@ -224,7 +224,7 @@
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
    }
    String taskScheduleTab = value.getStringValue();
    String taskScheduleTab = value.toString();
    parseTaskTab(taskScheduleTab);
    // Get the class name from the entry.  If there isn't one, then fail.
@@ -267,7 +267,7 @@
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
    }
    taskClassName = value.getStringValue();
    taskClassName = value.getValue().toString();
    // Make sure that the specified class can be loaded.
opends/src/server/org/opends/server/backends/task/Task.java
@@ -52,19 +52,7 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.ErrorLogger;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.Attributes;
import org.opends.server.types.DN;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.InitializationException;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
import org.opends.server.types.Operation;
import org.opends.server.types.*;
import org.opends.server.util.EMailMessage;
import org.opends.server.util.StaticUtils;
import org.opends.server.util.TimeThread;
@@ -440,7 +428,7 @@
      throw new InitializationException(message);
    }
    return value.getStringValue();
    return value.getValue().toString();
  }
@@ -480,7 +468,7 @@
    Iterator<AttributeValue> iterator = attrList.get(0).iterator();
    while (iterator.hasNext())
    {
      valueStrings.add(iterator.next().getStringValue());
      valueStrings.add(iterator.next().getValue().toString());
    }
    return valueStrings;
@@ -1006,7 +994,7 @@
      }
      List<Attribute> attrList = taskEntry.getAttribute(type);
      AttributeValue value = new AttributeValue(type, messageString);
      AttributeValue value = AttributeValues.create(type, messageString);
      if (attrList == null)
      {
        attrList = new ArrayList<Attribute>();
opends/src/server/org/opends/server/backends/task/TaskBackend.java
@@ -863,7 +863,7 @@
      }
      AttributeValue v = iterator.next();
      String valueString = toLowerCase(v.getStringValue());
      String valueString = toLowerCase(v.toString());
      if (!(valueString.startsWith("cancel") ||
        valueString.startsWith("stop"))) {
        acceptable = false;
@@ -2352,6 +2352,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void preloadEntryCache() throws UnsupportedOperationException {
    throw new UnsupportedOperationException("Operation not supported.");
  }
opends/src/server/org/opends/server/backends/task/TaskScheduler.java
@@ -1979,7 +1979,7 @@
      throw new DirectoryException(ResultCode.OBJECTCLASS_VIOLATION, message);
    }
    String taskClassName = value.getStringValue();
    String taskClassName = value.getValue().toString();
    if (! DirectoryServer.getAllowedTasks().contains(taskClassName))
    {
      Message message = ERR_TASKSCHED_NOT_ALLOWED_TASK.get(taskClassName);
opends/src/server/org/opends/server/config/BooleanConfigAttribute.java
@@ -40,9 +40,10 @@
import org.opends.server.api.AttributeSyntax;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.AttributeValues;
import org.opends.server.types.ByteString;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.messages.ConfigMessages.*;
@@ -241,13 +242,15 @@
         new LinkedHashSet<AttributeValue>(1);
    if (booleanValue)
    {
      valueSet.add(new AttributeValue(new ASN1OctetString(CONFIG_VALUE_TRUE),
                                      new ASN1OctetString(CONFIG_VALUE_TRUE)));
      valueSet.add(AttributeValues.create(
          ByteString.valueOf(CONFIG_VALUE_TRUE),
          ByteString.valueOf(CONFIG_VALUE_TRUE)));
    }
    else
    {
      valueSet.add(new AttributeValue(new ASN1OctetString(CONFIG_VALUE_FALSE),
                                      new ASN1OctetString(CONFIG_VALUE_FALSE)));
      valueSet.add(AttributeValues.create(
          ByteString.valueOf(CONFIG_VALUE_FALSE),
          ByteString.valueOf(CONFIG_VALUE_FALSE)));
    }
    return valueSet;
@@ -288,7 +291,7 @@
  public boolean valueIsAcceptable(AttributeValue value,
                                   StringBuilder rejectReason)
  {
    String stringValue = value.getStringValue();
    String stringValue = value.getValue().toString();
    if (stringValue.equalsIgnoreCase(CONFIG_VALUE_TRUE) ||
        stringValue.equalsIgnoreCase(CONFIG_VALUE_FALSE))
    {
@@ -464,7 +467,8 @@
          {
            // Get the value and parse it as a Boolean.
            Iterator<AttributeValue> iterator = a.iterator();
            String valueString = iterator.next().getStringValue().toLowerCase();
            String valueString =
                iterator.next().getValue().toString().toLowerCase();
            if (valueString.equals("true") || valueString.equals("yes") ||
                valueString.equals("on") || valueString.equals("1"))
@@ -526,7 +530,8 @@
        {
          // Get the value and parse it as a Boolean.
          Iterator<AttributeValue> iterator = a.iterator();
          String valueString = iterator.next().getStringValue().toLowerCase();
          String valueString =
              iterator.next().getValue().toString().toLowerCase();
          if (valueString.equals("true") || valueString.equals("yes") ||
              valueString.equals("on") || valueString.equals("1"))
opends/src/server/org/opends/server/config/ConfigAttribute.java
@@ -449,7 +449,7 @@
    if (! valueIsAcceptable(value, rejectReason))
    {
      Message message = ERR_CONFIG_ATTR_REJECTED_VALUE.get(
          value.getStringValue(), name, rejectReason.toString());
          value.getValue().toString(), name, rejectReason.toString());
      throw new ConfigException(message);
    }
@@ -470,7 +470,7 @@
      if (! valueIsAcceptable(value, rejectReason))
      {
        Message message = ERR_CONFIG_ATTR_REJECTED_VALUE.get(
            value.getStringValue(), name, rejectReason.toString());
            value.getValue().toString(), name, rejectReason.toString());
        throw new ConfigException(message);
      }
    }
@@ -589,14 +589,14 @@
      if (tempValues.contains(value))
      {
        Message message = ERR_CONFIG_ATTR_ADD_VALUES_ALREADY_EXISTS.get(
            name, value.getStringValue());
            name, value.getValue().toString());
        throw new ConfigException(message);
      }
      if (! valueIsAcceptable(value, rejectReason))
      {
        Message message = ERR_CONFIG_ATTR_REJECTED_VALUE.get(
            value.getStringValue(), name, rejectReason.toString());
            value.getValue().toString(), name, rejectReason.toString());
        throw new ConfigException(message);
      }
    }
@@ -657,7 +657,7 @@
      if (! tempValues.remove(value))
      {
        Message message =
            ERR_CONFIG_ATTR_NO_SUCH_VALUE.get(name, value.getStringValue());
           ERR_CONFIG_ATTR_NO_SUCH_VALUE.get(name, value.getValue().toString());
        throw new ConfigException(message);
      }
    }
opends/src/server/org/opends/server/config/DNConfigAttribute.java
@@ -40,11 +40,7 @@
import org.opends.server.api.AttributeSyntax;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DN;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -448,8 +444,8 @@
      }
      AttributeValue attrValue =
           new AttributeValue(new ASN1OctetString(value.toString()),
                              new ASN1OctetString(value.toNormalizedString()));
          AttributeValues.create(ByteString.valueOf(value.toString()),
              ByteString.valueOf(value.toNormalizedString()));
      if (valueSet.contains(attrValue))
      {
@@ -496,8 +492,8 @@
    else
    {
      valueSet = new LinkedHashSet<AttributeValue>(1);
      valueSet.add(new AttributeValue(new ASN1OctetString(value.toString()),
                            new ASN1OctetString(value.toNormalizedString())));
      valueSet.add(AttributeValues.create(ByteString.valueOf(value.toString()),
          ByteString.valueOf(value.toNormalizedString())));
    }
    return valueSet;
@@ -524,8 +520,8 @@
    for (DN value : values)
    {
      valueSet.add(new AttributeValue(new ASN1OctetString(value.toString()),
                            new ASN1OctetString(value.toNormalizedString())));
      valueSet.add(AttributeValues.create(ByteString.valueOf(value.toString()),
          ByteString.valueOf(value.toNormalizedString())));
    }
    return valueSet;
@@ -577,7 +573,7 @@
    // Make sure that it can be parsed as a DN.
    try
    {
      DN.decode(value.getStringValue());
      DN.decode(value.getValue().toString());
    }
    catch (Exception e)
    {
@@ -587,7 +583,7 @@
      }
      rejectReason.append(ERR_CONFIG_ATTR_DN_CANNOT_PARSE.get(
              value.getStringValue(), getName(),
              value.getValue().toString(), getName(),
              String.valueOf(e)));
      return false;
    }
@@ -692,8 +688,8 @@
      }
      valueSet.add(new AttributeValue(new ASN1OctetString(dn.toString()),
                            new ASN1OctetString(dn.toNormalizedString())));
      valueSet.add(AttributeValues.create(ByteString.valueOf(dn.toString()),
          ByteString.valueOf(dn.toNormalizedString())));
    }
@@ -841,7 +837,7 @@
              DN dn;
              try
              {
                dn = DN.decode(v.getStringValue());
                dn = DN.decode(v.getValue().toString());
              }
              catch (Exception e)
              {
@@ -851,7 +847,7 @@
                }
                Message message = ERR_CONFIG_ATTR_DN_CANNOT_PARSE.get(
                    v.getStringValue(), getName(), String.valueOf(e));
                    v.getValue().toString(), getName(), String.valueOf(e));
                throw new ConfigException(message, e);
              }
@@ -911,7 +907,7 @@
            DN dn;
            try
            {
              dn = DN.decode(v.getStringValue());
              dn = DN.decode(v.getValue().toString());
            }
            catch (Exception e)
            {
@@ -921,7 +917,7 @@
              }
              Message message = ERR_CONFIG_ATTR_DN_CANNOT_PARSE.get(
                  v.getStringValue(), getName(), String.valueOf(e));
                  v.getValue().toString(), getName(), String.valueOf(e));
              throw new ConfigException(message, e);
            }
opends/src/server/org/opends/server/config/IntegerConfigAttribute.java
@@ -40,10 +40,7 @@
import org.opends.server.api.AttributeSyntax;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -683,8 +680,8 @@
      String valueString = String.valueOf(value);
      AttributeValue attrValue =
           new AttributeValue(new ASN1OctetString(valueString),
                              new ASN1OctetString(valueString));
          AttributeValues.create(ByteString.valueOf(valueString),
              ByteString.valueOf(valueString));
      if (valueSet.contains(attrValue))
      {
@@ -726,8 +723,8 @@
         new LinkedHashSet<AttributeValue>(1);
    String valueString = String.valueOf(value);
    valueSet.add(new AttributeValue(new ASN1OctetString(valueString),
                                    new ASN1OctetString(valueString)));
    valueSet.add(AttributeValues.create(ByteString.valueOf(valueString),
        ByteString.valueOf(valueString)));
    return valueSet;
  }
@@ -754,8 +751,8 @@
    for (long value : values)
    {
      String valueString = String.valueOf(value);
      valueSet.add(new AttributeValue(new ASN1OctetString(valueString),
                                      new ASN1OctetString(valueString)));
      valueSet.add(AttributeValues.create(ByteString.valueOf(valueString),
          ByteString.valueOf(valueString)));
    }
    return valueSet;
@@ -797,7 +794,7 @@
                                   StringBuilder rejectReason)
  {
    // First, make sure we can represent it as a long.
    String stringValue = value.getStringValue();
    String stringValue = value.getValue().toString();
    long longValue;
    try
    {
@@ -951,8 +948,8 @@
      }
      valueSet.add(new AttributeValue(new ASN1OctetString(valueString),
                                      new ASN1OctetString(valueString)));
      valueSet.add(AttributeValues.create(ByteString.valueOf(valueString),
          ByteString.valueOf(valueString)));
    }
@@ -1101,12 +1098,12 @@
              long longValue;
              try
              {
                longValue = Long.parseLong(v.getStringValue());
                longValue = Long.parseLong(v.getValue().toString());
              }
              catch (Exception e)
              {
                Message message = ERR_CONFIG_ATTR_INT_COULD_NOT_PARSE.get(
                    v.getStringValue(), a.getName(), String.valueOf(e));
                    v.getValue().toString(), a.getName(), String.valueOf(e));
                throw new ConfigException(message, e);
              }
@@ -1183,12 +1180,12 @@
            long longValue;
            try
            {
              longValue = Long.parseLong(v.getStringValue());
              longValue = Long.parseLong(v.getValue().toString());
            }
            catch (Exception e)
            {
              Message message = ERR_CONFIG_ATTR_INT_COULD_NOT_PARSE.get(
                  v.getStringValue(), a.getName(), String.valueOf(e));
                  v.getValue().toString(), a.getName(), String.valueOf(e));
              throw new ConfigException(message, e);
            }
opends/src/server/org/opends/server/config/IntegerWithUnitConfigAttribute.java
@@ -41,10 +41,7 @@
import org.opends.server.api.AttributeSyntax;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -612,8 +609,8 @@
         new LinkedHashSet<AttributeValue>(1);
    String valueString = intValue + " " + unit;
    valueSet.add(new AttributeValue(new ASN1OctetString(valueString),
                                    new ASN1OctetString(valueString)));
    valueSet.add(AttributeValues.create(ByteString.valueOf(valueString),
        ByteString.valueOf(valueString)));
    return valueSet;
  }
@@ -656,7 +653,7 @@
                                   StringBuilder rejectReason)
  {
    // Get a string representation of the value and convert it to lowercase.
    String lowerValue = value.getStringValue().toLowerCase();
    String lowerValue = value.getValue().toString().toLowerCase();
    return valueIsAcceptable(lowerValue, rejectReason);
  }
@@ -833,8 +830,8 @@
      }
      valueSet.add(new AttributeValue(new ASN1OctetString(valueString),
                                      new ASN1OctetString(valueString)));
      valueSet.add(AttributeValues.create(ByteString.valueOf(valueString),
          ByteString.valueOf(valueString)));
    }
@@ -956,7 +953,7 @@
          {
            Iterator<AttributeValue> iterator = a.iterator();
            String valueString = iterator.next().getStringValue();
            String valueString = iterator.next().getValue().toString();
            if (iterator.hasNext())
            {
@@ -1041,7 +1038,7 @@
        {
          Iterator<AttributeValue> iterator = a.iterator();
          String valueString = iterator.next().getStringValue();
          String valueString = iterator.next().getValue().toString();
          if (iterator.hasNext())
          {
opends/src/server/org/opends/server/config/JMXMBean.java
@@ -56,14 +56,6 @@
import org.opends.server.api.MonitorProvider;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.jmx.Credential;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.InvokableMethod;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchScope;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.loggers.ErrorLogger.*;
@@ -72,12 +64,10 @@
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import org.opends.server.protocols.jmx.JmxClientConnection;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.protocols.internal.InternalSearchOperation ;
import org.opends.server.types.LDAPException;
import org.opends.server.types.*;
/**
@@ -448,12 +438,12 @@
          if (iterator.hasNext())
          {
            ArrayList<String> stringValues = new ArrayList<String>();
            stringValues.add(value.getStringValue());
            stringValues.add(value.getValue().toString());
            while (iterator.hasNext())
            {
              value = iterator.next();
              stringValues.add(value.getStringValue());
              stringValues.add(value.getValue().toString());
            }
            String[] valueArray = new String[stringValues.size()];
@@ -462,7 +452,7 @@
          }
          else
          {
            return new Attribute(name, value.getStringValue());
            return new Attribute(name, value.getValue().toString());
          }
        }
      }
@@ -522,12 +512,12 @@
    InternalSearchOperation op=null;
    if (clientConnection instanceof JmxClientConnection) {
        op = ((JmxClientConnection)clientConnection).processSearch(
             new ASN1OctetString(configEntryDN.toString()),
            ByteString.valueOf(configEntryDN.toString()),
             SearchScope.BASE_OBJECT, filter);
    }
    else if (clientConnection instanceof InternalClientConnection) {
        op = ((InternalClientConnection)clientConnection).processSearch(
             new ASN1OctetString(configEntryDN.toString()),
            ByteString.valueOf(configEntryDN.toString()),
             SearchScope.BASE_OBJECT, filter);
    }
    // BUG : op may be null
@@ -616,12 +606,12 @@
    InternalSearchOperation op=null;
    if (clientConnection instanceof JmxClientConnection) {
      op = ((JmxClientConnection)clientConnection).processSearch(
        new ASN1OctetString(configEntryDN.toString()),
          ByteString.valueOf(configEntryDN.toString()),
        SearchScope.BASE_OBJECT, filter);
    }
    else if (clientConnection instanceof InternalClientConnection) {
      op = ((InternalClientConnection)clientConnection).processSearch(
        new ASN1OctetString(configEntryDN.toString()),
          ByteString.valueOf(configEntryDN.toString()),
        SearchScope.BASE_OBJECT, filter);
    }
    // BUG: op may be null
@@ -681,12 +671,12 @@
            if (iterator.hasNext())
            {
              ArrayList<String> stringValues = new ArrayList<String>();
              stringValues.add(value.getStringValue());
              stringValues.add(value.getValue().toString());
              while (iterator.hasNext())
              {
                value = iterator.next();
                stringValues.add(value.getStringValue());
                stringValues.add(value.getValue().toString());
              }
              String[] valueArray = new String[stringValues.size()];
@@ -696,7 +686,7 @@
            }
            else
            {
              attrList.add(new Attribute(name, value.getStringValue()));
              attrList.add(new Attribute(name, value.getValue().toString()));
              break monitorLoop;
            }
          }
opends/src/server/org/opends/server/config/MultiChoiceConfigAttribute.java
@@ -40,10 +40,7 @@
import org.opends.server.api.AttributeSyntax;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -512,8 +509,8 @@
      }
      AttributeValue attrValue =
           new AttributeValue(new ASN1OctetString(value),
                              new ASN1OctetString(value));
          AttributeValues.create(ByteString.valueOf(value),
              ByteString.valueOf(value));
      if (valueSet.contains(attrValue))
      {
@@ -554,8 +551,8 @@
    LinkedHashSet<AttributeValue> valueSet =
         new LinkedHashSet<AttributeValue>(1);
    valueSet.add(new AttributeValue(new ASN1OctetString(value),
                                    new ASN1OctetString(value)));
    valueSet.add(AttributeValues.create(ByteString.valueOf(value),
        ByteString.valueOf(value)));
    return valueSet;
  }
@@ -581,8 +578,8 @@
    for (String value : values)
    {
      valueSet.add(new AttributeValue(new ASN1OctetString(value),
                                      new ASN1OctetString(value)));
      valueSet.add(AttributeValues.create(ByteString.valueOf(value),
          ByteString.valueOf(value)));
    }
    return valueSet;
@@ -626,7 +623,7 @@
    // Make sure that the value is non-empty.
    String stringValue;
    if ((value == null) ||
        ((stringValue = value.getStringValue()).length() == 0))
        ((stringValue = value.getValue().toString()).length() == 0))
    {
      rejectReason.append(ERR_CONFIG_ATTR_EMPTY_STRING_VALUE.get(getName()));
      return false;
@@ -727,8 +724,8 @@
        }
      }
      valueSet.add(new AttributeValue(new ASN1OctetString(valueString),
                                      new ASN1OctetString(valueString)));
      valueSet.add(AttributeValues.create(ByteString.valueOf(valueString),
          ByteString.valueOf(valueString)));
    }
@@ -860,16 +857,16 @@
            pendingValues = new ArrayList<String>(numValues);
            for (AttributeValue v : a)
            {
              String lowerValue = v.getStringValue().toLowerCase();
              String lowerValue = v.getValue().toString().toLowerCase();
              if (! allowedValues.contains(lowerValue))
              {
                // This is illegal -- the value is not allowed.
                Message message = ERR_CONFIG_ATTR_VALUE_NOT_ALLOWED.get(
                    v.getStringValue(), a.getName());
                    v.getValue().toString(), a.getName());
                throw new ConfigException(message);
              }
              pendingValues.add(v.getStringValue());
              pendingValues.add(v.getValue().toString());
            }
          }
        }
@@ -922,16 +919,16 @@
          activeValues = new ArrayList<String>(numValues);
          for (AttributeValue v : a)
          {
            String lowerValue = v.getStringValue().toLowerCase();
            String lowerValue = v.getValue().toString().toLowerCase();
            if (! allowedValues.contains(lowerValue))
            {
              // This is illegal -- the value is not allowed.
              Message message = ERR_CONFIG_ATTR_VALUE_NOT_ALLOWED.get(
                  v.getStringValue(), a.getName());
                  v.getValue().toString(), a.getName());
              throw new ConfigException(message);
            }
            activeValues.add(v.getStringValue());
            activeValues.add(v.getValue().toString());
          }
        }
      }
opends/src/server/org/opends/server/config/ReadOnlyConfigAttribute.java
@@ -38,9 +38,10 @@
import org.opends.server.api.AttributeSyntax;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
import org.opends.server.types.AttributeValues;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.messages.ConfigMessages.*;
@@ -280,8 +281,8 @@
    LinkedHashSet<AttributeValue> valueSet =
         new LinkedHashSet<AttributeValue>(1);
    valueSet.add(new AttributeValue(new ASN1OctetString(value),
                                    new ASN1OctetString(value)));
    valueSet.add(AttributeValues.create(ByteString.valueOf(value),
        ByteString.valueOf(value)));
    return valueSet;
  }
@@ -307,8 +308,8 @@
    for (String value : values)
    {
      valueSet.add(new AttributeValue(new ASN1OctetString(value),
                                      new ASN1OctetString(value)));
      valueSet.add(AttributeValues.create(ByteString.valueOf(value),
          ByteString.valueOf(value)));
    }
    return valueSet;
@@ -383,8 +384,8 @@
         new LinkedHashSet<AttributeValue>(numValues);
    for (String valueString : valueStrings)
    {
      valueSet.add(new AttributeValue(new ASN1OctetString(valueString),
                                      new ASN1OctetString(valueString)));
      valueSet.add(AttributeValues.create(ByteString.valueOf(valueString),
          ByteString.valueOf(valueString)));
    }
opends/src/server/org/opends/server/config/StringConfigAttribute.java
@@ -40,10 +40,7 @@
import org.opends.server.api.AttributeSyntax;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -451,8 +448,8 @@
      }
      AttributeValue attrValue =
           new AttributeValue(new ASN1OctetString(value),
                              new ASN1OctetString(value));
          AttributeValues.create(ByteString.valueOf(value),
              ByteString.valueOf(value));
      if (valueSet.contains(attrValue))
      {
@@ -493,8 +490,8 @@
    LinkedHashSet<AttributeValue> valueSet =
         new LinkedHashSet<AttributeValue>(1);
    valueSet.add(new AttributeValue(new ASN1OctetString(value),
                                    new ASN1OctetString(value)));
    valueSet.add(AttributeValues.create(ByteString.valueOf(value),
        ByteString.valueOf(value)));
    return valueSet;
  }
@@ -520,8 +517,8 @@
    for (String value : values)
    {
      valueSet.add(new AttributeValue(new ASN1OctetString(value),
                                      new ASN1OctetString(value)));
      valueSet.add(AttributeValues.create(ByteString.valueOf(value),
          ByteString.valueOf(value)));
    }
    return valueSet;
@@ -563,7 +560,7 @@
                                   StringBuilder rejectReason)
  {
    // The only requirement is that the value is not null or empty.
    if ((value == null) || (value.getStringValue().length() == 0))
    if ((value == null) || (value.getValue().toString().length() == 0))
    {
      rejectReason.append(ERR_CONFIG_ATTR_EMPTY_STRING_VALUE.get(getName()));
      return false;
@@ -641,8 +638,8 @@
        }
      }
      valueSet.add(new AttributeValue(new ASN1OctetString(valueString),
                                      new ASN1OctetString(valueString)));
      valueSet.add(AttributeValues.create(ByteString.valueOf(valueString),
          ByteString.valueOf(valueString)));
    }
@@ -774,7 +771,7 @@
            pendingValues = new ArrayList<String>(numValues);
            for (AttributeValue v : a)
            {
              pendingValues.add(v.getStringValue());
              pendingValues.add(v.getValue().toString());
            }
          }
        }
@@ -827,7 +824,7 @@
          activeValues = new ArrayList<String>(numValues);
          for (AttributeValue v : a)
          {
            activeValues.add(v.getStringValue());
            activeValues.add(v.getValue().toString());
          }
        }
      }
opends/src/server/org/opends/server/controls/AccountUsableRequestControl.java
@@ -29,13 +29,16 @@
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.types.ByteString;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ResultCode;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import java.io.IOException;
/**
@@ -46,8 +49,41 @@
public class AccountUsableRequestControl
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private static final class Decoder
      implements ControlDecoder<AccountUsableRequestControl>
  {
    /**
     * {@inheritDoc}
     */
    public AccountUsableRequestControl decode(boolean isCritical,
                                              ByteString value)
           throws DirectoryException
    {
      if (value != null)
      {
        Message message = ERR_ACCTUSABLEREQ_CONTROL_HAS_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      return new AccountUsableRequestControl(isCritical);
    }
    public String getOID()
    {
      return OID_ACCOUNT_USABLE_CONTROL;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<AccountUsableRequestControl> DECODER =
    new Decoder();
  /**
   * Creates a new instance of the account usable request control with the
@@ -55,67 +91,32 @@
   */
  public AccountUsableRequestControl()
  {
    super(OID_ACCOUNT_USABLE_CONTROL, false);
    this(false);
  }
  /**
   * Creates a new instance of the account usable request control with the
   * provided information.
   * default settings.
   *
   * @param  oid         The OID to use for this control.
   * @param  isCritical  Indicates whether support for this control should be
   *                     considered a critical part of the client processing.
   * @param  isCritical  Indicates whether this control should be
   *                     considered critical in processing the
   *                     request.
   */
  public AccountUsableRequestControl(String oid, boolean isCritical)
  public AccountUsableRequestControl(boolean isCritical)
  {
    super(oid, isCritical);
    super(OID_ACCOUNT_USABLE_CONTROL, isCritical);
  }
  /**
   * Creates a new account usable request control from the contents of the
   * provided control.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this account usable request control.
   *
   * @return  The account usable request control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         account usable request control.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public static AccountUsableRequestControl decodeControl(Control control)
         throws LDAPException
  {
    if (control.hasValue())
    {
      Message message = ERR_ACCTUSABLEREQ_CONTROL_HAS_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    return new AccountUsableRequestControl(control.getOID(),
                                           control.isCritical());
  }
  /**
   * Retrieves a string representation of this account usable request control.
   *
   * @return  A string representation of this account usable request control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  protected void writeValue(ASN1Writer writer) throws IOException {
    // No value element.
  }
opends/src/server/org/opends/server/controls/AccountUsableResponseControl.java
@@ -28,19 +28,12 @@
import org.opends.messages.Message;
import java.io.IOException;
import java.util.ArrayList;
import org.opends.server.protocols.asn1.ASN1Boolean;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1Integer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.Control;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.types.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
@@ -69,9 +62,120 @@
 * </PRE>
 */
public class AccountUsableResponseControl
       extends Control
    extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<AccountUsableResponseControl>
  {
    /**
     * {@inheritDoc}
     */
    public AccountUsableResponseControl decode(boolean isCritical,
                                               ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        // The response control must always have a value.
        Message message = ERR_ACCTUSABLERES_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      try
      {
        ASN1Reader reader = ASN1.getReader(value);
        switch (reader.peekType())
        {
          case TYPE_SECONDS_BEFORE_EXPIRATION:
            int secondsBeforeExpiration = (int)reader.readInteger();
            return new AccountUsableResponseControl(isCritical,
                secondsBeforeExpiration);
          case TYPE_MORE_INFO:
            boolean isInactive = false;
            boolean isReset = false;
            boolean isExpired = false;
            boolean isLocked = false;
            int     remainingGraceLogins = -1;
            int     secondsBeforeUnlock = 0;
            reader.readStartSequence();
            while(reader.hasNextElement())
            {
              switch (reader.peekType())
              {
                case TYPE_INACTIVE:
                  isInactive = reader.readBoolean();
                  break;
                case TYPE_RESET:
                  isReset = reader.readBoolean();
                  break;
                case TYPE_EXPIRED:
                  isExpired = reader.readBoolean();
                  break;
                case TYPE_REMAINING_GRACE_LOGINS:
                  remainingGraceLogins = (int)reader.readInteger();
                  break;
                case TYPE_SECONDS_BEFORE_UNLOCK:
                  isLocked = true;
                  secondsBeforeUnlock = (int)reader.readInteger();
                  break;
                default:
                  Message message = ERR_ACCTUSABLERES_UNKNOWN_UNAVAILABLE_TYPE.
                      get(byteToHex(reader.peekType()));
                  throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
                      message);
              }
            }
            reader.readEndSequence();
            return new AccountUsableResponseControl(isCritical,
                isInactive, isReset,
                isExpired,
                remainingGraceLogins,
                isLocked,
                secondsBeforeUnlock);
          default:
            Message message = ERR_ACCTUSABLERES_UNKNOWN_VALUE_ELEMENT_TYPE.get(
                byteToHex(reader.peekType()));
            throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
        }
      }
      catch (DirectoryException de)
      {
        throw de;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message =
            ERR_ACCTUSABLERES_DECODE_ERROR.get(getExceptionMessage(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
    }
    public String getOID()
    {
      return OID_ACCOUNT_USABLE_CONTROL;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<AccountUsableResponseControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -175,8 +279,26 @@
   */
  public AccountUsableResponseControl(int secondsBeforeExpiration)
  {
    super(OID_ACCOUNT_USABLE_CONTROL, false,
          encodeValue(secondsBeforeExpiration));
    this(false, secondsBeforeExpiration);
  }
  /**
   * Creates a new account usability response control that may be used to
   * indicate that the account is available and provide the number of seconds
   * until expiration.  It will use the default OID and criticality.
   *
   * @param  isCritical  Indicates whether this control should be
   *                     considered critical in processing the
   *                     request.
   * @param  secondsBeforeExpiration  The length of time in seconds until the
   *                                  user's password expires, or -1 if the
   *                                  user's password will not expire or the
   *                                  expiration time is unknown.
   */
  public AccountUsableResponseControl(boolean isCritical,
                                      int secondsBeforeExpiration)
  {
    super(OID_ACCOUNT_USABLE_CONTROL, isCritical);
    this.secondsBeforeExpiration = secondsBeforeExpiration;
@@ -194,37 +316,50 @@
  /**
   * Creates a new account usability response control that may be used to
   * indicate that the account is available and provide the number of seconds
   * until expiration.
   * indicate that the account is not available and provide information about
   * the underlying reason.  It will use the default OID and criticality.
   *
   * @param  oid                      The OID for this account usability
   *                                  response control.
   * @param  isCritical               Indicates whether this control should be
   *                                  marked critical.
   * @param  secondsBeforeExpiration  The length of time in seconds until the
   *                                  user's password expires, or -1 if the
   *                                  user's password will not expire or the
   *                                  expiration time is unknown.
   * @param  isCritical  Indicates whether this control should be
   *                     considered critical in processing the
   *                     request.
   * @param  isInactive            Indicates whether the user's account has been
   *                               inactivated by an administrator.
   * @param  isReset               Indicates whether the user's password has
   *                               been reset by an administrator.
   * @param  isExpired             Indicates whether the user's password is
   *                               expired.
   * @param  remainingGraceLogins  The number of grace logins remaining.  A
   *                               value of zero indicates that there are none
   *                               remaining.  A value of -1 indicates that
   *                               grace login functionality is not enabled.
   * @param  isLocked              Indicates whether the user's account is
   *                               currently locked out.
   * @param  secondsBeforeUnlock   The length of time in seconds until the
   *                               account is unlocked.  A value of -1 indicates
   *                               that the account will not be automatically
   *                               unlocked and must be reset by an
   *                               administrator.
   */
  public AccountUsableResponseControl(String oid, boolean isCritical,
                                      int secondsBeforeExpiration)
  public AccountUsableResponseControl(boolean isCritical, boolean isInactive,
                                      boolean isReset,
                                      boolean isExpired,
                                      int remainingGraceLogins,
                                      boolean isLocked, int secondsBeforeUnlock)
  {
    super(oid, isCritical, encodeValue(secondsBeforeExpiration));
    super(OID_ACCOUNT_USABLE_CONTROL, isCritical);
    this.secondsBeforeExpiration = secondsBeforeExpiration;
    this.isInactive           = isInactive;
    this.isReset              = isReset;
    this.isExpired            = isExpired;
    this.remainingGraceLogins = remainingGraceLogins;
    this.isLocked             = isLocked;
    this.secondsBeforeUnlock  = secondsBeforeUnlock;
    isUsable             = true;
    isInactive           = false;
    isReset              = false;
    isExpired            = false;
    remainingGraceLogins = -1;
    isLocked             = false;
    secondsBeforeUnlock  = 0;
    isUsable                = false;
    secondsBeforeExpiration = -1;
  }
  /**
   * Creates a new account usability response control that may be used to
   * indicate that the account is not available and provide information about
@@ -253,342 +388,63 @@
                                      int remainingGraceLogins,
                                      boolean isLocked, int secondsBeforeUnlock)
  {
    super(OID_ACCOUNT_USABLE_CONTROL, false,
          encodeValue(isInactive, isReset, isExpired, remainingGraceLogins,
                      isLocked, secondsBeforeUnlock));
    this.isInactive           = isInactive;
    this.isReset              = isReset;
    this.isExpired            = isExpired;
    this.remainingGraceLogins = remainingGraceLogins;
    this.isLocked             = isLocked;
    this.secondsBeforeUnlock  = secondsBeforeUnlock;
    isUsable                = false;
    secondsBeforeExpiration = -1;
    this(false, isInactive, isReset, isExpired, remainingGraceLogins,
        isLocked, secondsBeforeUnlock);
  }
  /**
   * Creates a new account usability response control that may be used to
   * indicate that the account is not available and provide information about
   * the underlying reason.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  oid                   The OID for this account usability response
   *                               control.
   * @param  isCritical            Indicates whether this control should be
   *                               marked critical.
   * @param  isInactive            Indicates whether the user's account has been
   *                               inactivated by an administrator.
   * @param  isReset               Indicates whether the user's password has
   *                               been reset by an administrator.
   * @param  isExpired             Indicates whether the user's password is
   *                               expired.
   * @param  remainingGraceLogins  The number of grace logins remaining.  A
   *                               value of zero indicates that there are none
   *                               remaining.  A value of -1 indicates that
   *                               grace login functionality is not enabled.
   * @param  isLocked              Indicates whether the user's account is
   *                               currently locked out.
   * @param  secondsBeforeUnlock   The length of time in seconds until the
   *                               account is unlocked.  A value of -1 indicates
   *                               that the account will not be automatically
   *                               unlocked and must be reset by an
   *                               administrator.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public AccountUsableResponseControl(String oid, boolean isCritical,
                                      boolean isInactive, boolean isReset,
                                      boolean isExpired,
                                      int remainingGraceLogins,
                                      boolean isLocked, int secondsBeforeUnlock)
  {
    super(oid, isCritical,
          encodeValue(isInactive, isReset, isExpired, remainingGraceLogins,
                      isLocked, secondsBeforeUnlock));
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    this.isInactive           = isInactive;
    this.isReset              = isReset;
    this.isExpired            = isExpired;
    this.remainingGraceLogins = remainingGraceLogins;
    this.isLocked             = isLocked;
    this.secondsBeforeUnlock  = secondsBeforeUnlock;
    isUsable                = false;
    secondsBeforeExpiration = -1;
  }
  /**
   * Creates a new account usability response control using the provided
   * information.  This version of the constructor is only intended for internal
   * use.
   *
   * @param  oid                      The OID for this account usability
   *                                  response control.
   * @param  isCritical               Indicates whether this control should be
   *                                  marked critical.
   * @param  isAvailable              Indicates whether the user's account is
   *                                  available for use.
   * @param  secondsBeforeExpiration  The length of time in seconds until the
   *                                  user's password expires, or -1 if the
   *                                  user's password will not expire or the
   *                                  expiration time is unknown.
   * @param  isInactive               Indicates whether the user's account has
   *                                  been inactivated by an administrator.
   * @param  isReset                  Indicates whether the user's password has
   *                                  been reset by an administrator.
   * @param  isExpired                Indicates whether the user's password is
   *                                  expired.
   * @param  remainingGraceLogins     The number of grace logins remaining.  A
   *                                  value of zero indicates that there are
   *                                  none remaining.  A value of -1 indicates
   *                                  that grace login functionality is not
   *                                  enabled.
   * @param  isLocked                 Indicates whether the user's account is
   *                                  currently locked out.
   * @param  secondsBeforeUnlock      The length of time in seconds until the
   *                                  account is unlocked.  A value of -1
   *                                  indicates that the account will not be
   *                                  automatically unlocked and must be reset
   *                                  by an administrator.
   * @param  encodedValue             The pre-encoded value for this account
   *                                  usable response control.
   */
  private AccountUsableResponseControl(String oid, boolean isCritical,
                                             boolean isAvailable,
                                             int secondsBeforeExpiration,
                                             boolean isInactive,
                                             boolean isReset, boolean isExpired,
                                             int remainingGraceLogins,
                                             boolean isLocked,
                                             int secondsBeforeUnlock,
                                             ASN1OctetString encodedValue)
  {
    super(oid, isCritical, encodedValue);
    this.isUsable                = isAvailable;
    this.secondsBeforeExpiration = secondsBeforeExpiration;
    this.isInactive              = isInactive;
    this.isReset                 = isReset;
    this.isExpired               = isExpired;
    this.remainingGraceLogins    = remainingGraceLogins;
    this.isLocked                = isLocked;
    this.secondsBeforeUnlock     = secondsBeforeUnlock;
  }
  /**
   * Encodes the provided information into an ASN.1 octet string suitable for
   * use as the value for an account usable response control in which the use's
   * account is available.
   *
   * @param  secondsBeforeExpiration  The length of time in seconds until the
   *                                  user's password expires, or -1 if the
   *                                  user's password will not expire or the
   *                                  expiration time is unknown.
   *
   * @return  An ASN.1 octet string containing the encoded control value.
   */
  private static ASN1OctetString encodeValue(int secondsBeforeExpiration)
  {
    ASN1Integer sbeInteger = new ASN1Integer(TYPE_SECONDS_BEFORE_EXPIRATION,
                                             secondsBeforeExpiration);
    return new ASN1OctetString(sbeInteger.encode());
  }
  /**
   * Encodes the provided information into an ASN.1 octet string suitable for
   * use as the value for an account usable response control in which the user's
   * account is not available.
   *
   *
   * @param  isInactive            Indicates whether the user's account has been
   *                               inactivated by an administrator.
   * @param  isReset               Indicates whether the user's password has
   *                               been reset by an administrator.
   * @param  isExpired             Indicates whether the user's password is
   *                               expired.
   * @param  remainingGraceLogins  The number of grace logins remaining.  A
   *                               value of zero indicates that there are none
   *                               remaining.  A value of -1 indicates that
   *                               grace login functionality is not enabled.
   * @param  isLocked              Indicates whether the user's account is
   *                               currently locked out.
   * @param  secondsBeforeUnlock   The length of time in seconds until the
   *                               account is unlocked.  A value of -1 indicates
   *                               that the account will not be automatically
   *                               unlocked and must be reset by an
   *                               administrator.
   *
   * @return  An ASN.1 octet string containing the encoded control value.
   */
  private static ASN1OctetString encodeValue(boolean isInactive,
                                             boolean isReset, boolean isExpired,
                                             int remainingGraceLogins,
                                             boolean isLocked,
                                             int secondsBeforeUnlock)
  {
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(5);
    if (isInactive)
    if(secondsBeforeExpiration < 0)
    {
      elements.add(new ASN1Boolean(TYPE_INACTIVE, true));
      writer.writeInteger(TYPE_SECONDS_BEFORE_EXPIRATION,
          secondsBeforeExpiration);
    }
    if (isReset)
    else
    {
      elements.add(new ASN1Boolean(TYPE_RESET, true));
    }
    if (isExpired)
    {
      elements.add(new ASN1Boolean(TYPE_EXPIRED, true));
      if (remainingGraceLogins >= 0)
      writer.writeStartSequence(TYPE_MORE_INFO);
      if (isInactive)
      {
        elements.add(new ASN1Integer(TYPE_REMAINING_GRACE_LOGINS,
                                     remainingGraceLogins));
      }
    }
    if (isLocked)
    {
      elements.add(new ASN1Integer(TYPE_SECONDS_BEFORE_UNLOCK,
                                   secondsBeforeUnlock));
    }
    ASN1Sequence moreInfoSequence = new ASN1Sequence(TYPE_MORE_INFO,
                                                     elements);
    return new ASN1OctetString(moreInfoSequence.encode());
  }
  /**
   * Creates a new account usable response control from the contents of the
   * provided control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this account usable response control.
   *
   * @return  The account usable response control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         account usable response control.
   */
  public static AccountUsableResponseControl decodeControl(Control control)
         throws LDAPException
  {
    ASN1OctetString controlValue = control.getValue();
    if (controlValue == null)
    {
      // The response control must always have a value.
      Message message = ERR_ACCTUSABLERES_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    try
    {
      ASN1Element valueElement = ASN1Element.decode(controlValue.value());
      switch (valueElement.getType())
      {
        case TYPE_SECONDS_BEFORE_EXPIRATION:
          int secondsBeforeExpiration =
                   valueElement.decodeAsInteger().intValue();
          return new AccountUsableResponseControl(control.getOID(),
                                                  control.isCritical(), true,
                                                  secondsBeforeExpiration,
                                                  false, false, false, -1,
                                                  false, 0, controlValue);
        case TYPE_MORE_INFO:
          boolean isInactive = false;
          boolean isReset = false;
          boolean isExpired = false;
          boolean isLocked = false;
          int     remainingGraceLogins = -1;
          int     secondsBeforeUnlock = 0;
          for (ASN1Element e : valueElement.decodeAsSequence().elements())
          {
            switch (e.getType())
            {
              case TYPE_INACTIVE:
                isInactive = e.decodeAsBoolean().booleanValue();
                break;
              case TYPE_RESET:
                isReset = e.decodeAsBoolean().booleanValue();
                break;
              case TYPE_EXPIRED:
                isExpired = e.decodeAsBoolean().booleanValue();
                break;
              case TYPE_REMAINING_GRACE_LOGINS:
                remainingGraceLogins = e.decodeAsInteger().intValue();
                break;
              case TYPE_SECONDS_BEFORE_UNLOCK:
                isLocked = true;
                secondsBeforeUnlock = e.decodeAsInteger().intValue();
                break;
              default:
                Message message = ERR_ACCTUSABLERES_UNKNOWN_UNAVAILABLE_TYPE.
                    get(byteToHex(e.getType()));
                throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
            }
          }
          return new AccountUsableResponseControl(control.getOID(),
                                                  control.isCritical(), false,
                                                  -1, isInactive, isReset,
                                                  isExpired,
                                                  remainingGraceLogins,
                                                  isLocked, secondsBeforeUnlock,
                                                  controlValue);
        default:
          Message message = ERR_ACCTUSABLERES_UNKNOWN_VALUE_ELEMENT_TYPE.get(
              byteToHex(valueElement.getType()));
          throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
      }
    }
    catch (LDAPException le)
    {
      throw le;
    }
    catch (ASN1Exception ae)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ae);
        writer.writeBoolean(TYPE_INACTIVE, true);
      }
      Message message = ERR_ACCTUSABLERES_DECODE_ERROR.get(ae.getMessage());
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    catch (Exception e)
    {
      if (debugEnabled())
      if (isReset)
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
        writer.writeBoolean(TYPE_RESET, true);
      }
      Message message =
          ERR_ACCTUSABLERES_DECODE_ERROR.get(getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
      if (isExpired)
      {
        writer.writeBoolean(TYPE_EXPIRED, true);
        if (remainingGraceLogins >= 0)
        {
          writer.writeInteger(TYPE_REMAINING_GRACE_LOGINS,
              remainingGraceLogins);
        }
      }
      if (isLocked)
      {
        writer.writeInteger(TYPE_SECONDS_BEFORE_UNLOCK,
            secondsBeforeUnlock);
      }
      writer.writeEndSequence();
    }
    writer.writeEndSequence();
  }
  /**
   * Indicates whether the associated user account is available for use.
   *
@@ -703,20 +559,6 @@
  /**
   * Retrieves a string representation of this password policy response control.
   *
   * @return  A string representation of this password policy response control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this password policy response control to
   * the provided buffer.
   *
opends/src/server/org/opends/server/controls/AuthorizationIdentityResponseControl.java
@@ -29,15 +29,13 @@
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.Control;
import org.opends.server.types.DN;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import java.io.IOException;
/**
@@ -49,7 +47,50 @@
public class AuthorizationIdentityResponseControl
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<AuthorizationIdentityResponseControl>
  {
    /**
     * {@inheritDoc}
     */
    public AuthorizationIdentityResponseControl decode(boolean isCritical,
                                                       ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        Message message = ERR_AUTHZIDRESP_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      try
      {
        String authID = value.toString();
        return new AuthorizationIdentityResponseControl(isCritical,
            authID);
      }
      catch(Exception e)
      {
        // TODO: message.
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, Message.EMPTY);
      }
    }
    public String getOID()
    {
      return OID_AUTHZID_RESPONSE;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<AuthorizationIdentityResponseControl>
      DECODER = new Decoder();
  // The authorization ID for this control.
@@ -63,8 +104,20 @@
   */
  public AuthorizationIdentityResponseControl()
  {
    super(OID_AUTHZID_RESPONSE, false, new ASN1OctetString());
    this(false);
  }
  /**
   * Creates a new authorization identity response control using the default
   * settings to indicate an anonymous authentication.
   *
   * @param  isCritical  Indicates whether this control should be
   *                     considered critical in processing the
   *                     request.
   */
  public AuthorizationIdentityResponseControl(boolean isCritical)
  {
    super(OID_AUTHZID_RESPONSE, isCritical);
  }
@@ -77,7 +130,23 @@
   */
  public AuthorizationIdentityResponseControl(String authorizationID)
  {
    super(OID_AUTHZID_RESPONSE, false, encodeValue(authorizationID));
    this(false, authorizationID);
  }
  /**
   * Creates a new authorization identity response control with the provided
   * information.
   *
   * @param  isCritical  Indicates whether this control should be
   *                     considered critical in processing the
   *                     request.
   * @param  authorizationID  The authorization ID for this control.
   */
  public AuthorizationIdentityResponseControl(boolean isCritical,
                                              String authorizationID)
  {
    super(OID_AUTHZID_RESPONSE, isCritical);
    this.authorizationID = authorizationID;
@@ -85,6 +154,7 @@
  /**
   * Creates a new authorization identity response control with the provided
   * information.
@@ -93,7 +163,7 @@
   */
  public AuthorizationIdentityResponseControl(DN authorizationDN)
  {
    super(OID_AUTHZID_RESPONSE, false, encodeValue(authorizationDN));
    super(OID_AUTHZID_RESPONSE, false);
    if (authorizationDN == null)
@@ -109,142 +179,14 @@
  /**
   * Creates a new authorization identity response control with the provided
   * information.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  oid              The OID to use for this control.
   * @param  isCritical       Indicates whether this control should be
   *                          considered a critical part of the response
   *                          processing.
   * @param  authorizationID  The authorization ID for this control.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public AuthorizationIdentityResponseControl(String oid, boolean isCritical,
                                              String authorizationID)
  {
    super(oid, isCritical, encodeValue(authorizationID));
    this.authorizationID = authorizationID;
  }
  /**
   * Creates a new authorization identity response control with the provided
   * information.
   *
   * @param  oid              The OID to use for this control.
   * @param  isCritical       Indicates whether this control should be
   *                          considered a critical part of the response
   *                          processing.
   * @param  authorizationDN  The authorization DN for this control.
   */
  public AuthorizationIdentityResponseControl(String oid, boolean isCritical,
                                              DN authorizationDN)
  {
    super(oid, isCritical, encodeValue(authorizationDN));
    if (authorizationDN == null)
    {
      this.authorizationID = "dn:";
    }
    else
    {
      this.authorizationID = "dn:" + authorizationDN.toString();
    }
  }
  /**
   * Creates a new authorization identity response control with the provided
   * information.
   *
   * @param  oid              The OID to use for this control.
   * @param  isCritical       Indicates whether this control should be
   *                          considered a critical part of the response
   *                          processing.
   * @param  authorizationID  The authorization ID for this control.
   * @param  encodedValue     The encoded value for the control.
   */
  private AuthorizationIdentityResponseControl(String oid, boolean isCritical,
                                               String authorizationID,
                                               ASN1OctetString encodedValue)
  {
    super(oid, isCritical, encodedValue);
    this.authorizationID = authorizationID;
  }
  /**
   * Encodes the provided information into an ASN.1 octet string suitable for
   * use as the control value.
   *
   * @param  authorizationID  The authorization ID for this authorization ID
   *                          response control.
   *
   * @return  An ASN.1 octet string containing the encoded information.
   */
  private static ASN1OctetString encodeValue(String authorizationID)
  {
    return new ASN1OctetString(authorizationID);
  }
  /**
   * Encodes the provided information into an ASN.1 octet string suitable for
   * use as the control value.
   *
   * @param  authorizationDN  The authorization DN for this authorization ID
   *                          response control.
   *
   * @return  An ASN.1 octet string containing the encoded information.
   */
  private static ASN1OctetString encodeValue(DN authorizationDN)
  {
    if (authorizationDN == null)
    {
      return new ASN1OctetString("dn:");
    }
    else
    {
      return new ASN1OctetString("dn:" + authorizationDN.toString());
    }
  }
  /**
   * Creates a new authorization identity response control from the contents of
   * the provided control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this authorization identity response control.
   *
   * @return  The authorization identity response control decoded from the
   *          provided control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         authorization identity response control.
   */
  public static AuthorizationIdentityResponseControl decodeControl(
                                                          Control control)
         throws LDAPException
  {
    if (! control.hasValue())
    {
      Message message = ERR_AUTHZIDRESP_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    return new AuthorizationIdentityResponseControl(control.getOID(),
                    control.isCritical(), control.getValue().stringValue(),
                    control.getValue());
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeOctetString(authorizationID);
  }
@@ -264,37 +206,6 @@
  /**
   * Specifies the authorization ID for this authorization identity response
   * control.
   *
   * @param  authorizationID  The authorization ID for this authorization
   *                          identity response control.
   */
  public void setAuthorizationID(String authorizationID)
  {
    this.authorizationID = authorizationID;
    setValue(encodeValue(authorizationID));
  }
  /**
   * Retrieves a string representation of this authorization identity response
   * control.
   *
   * @return  A string representation of this authorization identity response
   *          control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this authorization identity response
   * control to the provided buffer.
   *
opends/src/server/org/opends/server/controls/ControlDecoder.java
New file
@@ -0,0 +1,68 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 */
package org.opends.server.controls;
import org.opends.server.types.ByteString;
import org.opends.server.types.Control;
import org.opends.server.types.DirectoryException;
/**
 * An interface for decoding controls.
 *
 * @param <T>
 *          The type of control decoded by this decoder.
 */
public interface ControlDecoder<T extends Control>
{
  /**
   * Decodes the provided control.
   *
   * @param isCritical
   *          Indicates whether the control should be considered
   *          critical.
   * @param value
   *          The value for the control.
   * @return The decoded control.
   * @throws DirectoryException
   *           If the control could not be decoded.
   */
  T decode(boolean isCritical, ByteString value) throws DirectoryException;
  /**
   * Gets the OID of the control decoded by this decoded.
   *
   * @return The OID of the control decoded by this decoded.
   */
  String getOID();
}
opends/src/server/org/opends/server/controls/EntryChangeNotificationControl.java
@@ -28,20 +28,12 @@
import org.opends.messages.Message;
import java.io.IOException;
import java.util.ArrayList;
import org.opends.server.protocols.asn1.ASN1Constants;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Enumerated;
import org.opends.server.protocols.asn1.ASN1Long;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.Control;
import org.opends.server.types.DN;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.types.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
@@ -60,6 +52,94 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<EntryChangeNotificationControl>
  {
    /**
     * {@inheritDoc}
     */
    public EntryChangeNotificationControl decode(
        boolean isCritical, ByteString value) throws DirectoryException
    {
      if (value == null)
      {
        Message message = ERR_ECN_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      DN                         previousDN   = null;
      long                       changeNumber = -1;
      PersistentSearchChangeType changeType;
      ASN1Reader reader = ASN1.getReader(value);
      try
      {
        reader.readStartSequence();
        int changeTypeValue = (int)reader.readInteger();
        changeType = PersistentSearchChangeType.valueOf(changeTypeValue);
        while(reader.hasNextElement()) {
          switch(reader.peekType()) {
            case ASN1Constants.UNIVERSAL_OCTET_STRING_TYPE :
              if (changeType != PersistentSearchChangeType.MODIFY_DN)
              {
                Message message =
                    ERR_ECN_ILLEGAL_PREVIOUS_DN.get(String.valueOf(changeType));
                throw new DirectoryException(
                    ResultCode.PROTOCOL_ERROR, message);
              }
              previousDN = DN.decode(reader.readOctetStringAsString());
              break;
            case ASN1Constants.UNIVERSAL_INTEGER_TYPE :
              changeNumber = reader.readInteger();
              break;
            default :
              Message message =
                  ERR_ECN_INVALID_ELEMENT_TYPE.get(
                      byteToHex(reader.peekType()));
              throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
          }
        }
      }
      catch (DirectoryException de)
      {
        throw de;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message =
            ERR_ECN_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
      }
      return new EntryChangeNotificationControl(isCritical, changeType,
          previousDN, changeNumber);
    }
    public String getOID()
    {
      return OID_ENTRY_CHANGE_NOTIFICATION;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<EntryChangeNotificationControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -77,20 +157,22 @@
  private PersistentSearchChangeType changeType;
  /**
   * Creates a new entry change notification control with the provided
   * information.
   *
   * @param  isCritical  Indicates whether this control should be
   *                     considered critical in processing the
   *                     request.
   * @param  changeType    The change type for this change notification control.
   * @param  changeNumber  The change number for the associated change, or a
   *                       negative value if no change number is available.
   */
  public EntryChangeNotificationControl(PersistentSearchChangeType changeType,
  public EntryChangeNotificationControl(boolean isCritical,
                                        PersistentSearchChangeType changeType,
                                        long changeNumber)
  {
    super(OID_ENTRY_CHANGE_NOTIFICATION, false,
          encodeValue(changeType, null, changeNumber));
    super(OID_ENTRY_CHANGE_NOTIFICATION, isCritical);
    this.changeType   = changeType;
@@ -105,6 +187,49 @@
   * Creates a new entry change notification control with the provided
   * information.
   *
   * @param  isCritical  Indicates whether this control should be
   *                     considered critical in processing the
   *                     request.
   * @param  changeType    The change type for this change notification control.
   * @param  previousDN    The DN that the entry had prior to a modify DN
   *                       operation, or <CODE>null</CODE> if the operation was
   *                       not a modify DN.
   * @param  changeNumber  The change number for the associated change, or a
   *                       negative value if no change number is available.
   */
  public EntryChangeNotificationControl(boolean isCritical,
                                        PersistentSearchChangeType changeType,
                                        DN previousDN, long changeNumber)
  {
    super(OID_ENTRY_CHANGE_NOTIFICATION, isCritical);
    this.changeType   = changeType;
    this.previousDN   = previousDN;
    this.changeNumber = changeNumber;
  }
  /**
   * Creates a new entry change notification control with the provided
   * information.
   *
   * @param  changeType    The change type for this change notification control.
   * @param  changeNumber  The change number for the associated change, or a
   *                       negative value if no change number is available.
   */
  public EntryChangeNotificationControl(PersistentSearchChangeType changeType,
                                        long changeNumber)
  {
    this(false, changeType, changeNumber);
  }
  /**
   * Creates a new entry change notification control with the provided
   * information.
   *
   * @param  changeType    The change type for this change notification control.
   * @param  previousDN    The DN that the entry had prior to a modify DN
   *                       operation, or <CODE>null</CODE> if the operation was
@@ -115,213 +240,36 @@
  public EntryChangeNotificationControl(PersistentSearchChangeType changeType,
                                        DN previousDN, long changeNumber)
  {
    super(OID_ENTRY_CHANGE_NOTIFICATION, false,
          encodeValue(changeType, previousDN, changeNumber));
    this.changeType   = changeType;
    this.previousDN   = previousDN;
    this.changeNumber = changeNumber;
    this(false, changeType, previousDN, changeNumber);
  }
  /**
   * Creates a new entry change notification control with the provided
   * information.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  oid           The OID to use for this control.
   * @param  isCritical    Indicates whether this control should be considered
   *                       critical to the operation processing.
   * @param  changeType    The change type for this change notification control.
   * @param  previousDN    The DN that the entry had prior to a modify DN
   *                       operation, or <CODE>null</CODE> if the operation was
   *                       not a modify DN.
   * @param  changeNumber  The change number for the associated change, or a
   *                       negative value if no change number is available.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public EntryChangeNotificationControl(String oid, boolean isCritical,
                                        PersistentSearchChangeType changeType,
                                        DN previousDN, long changeNumber)
  {
    super(oid, isCritical, encodeValue(changeType, previousDN, changeNumber));
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    this.changeType   = changeType;
    this.previousDN   = previousDN;
    this.changeNumber = changeNumber;
  }
  /**
   * Creates a new entry change notification control with the provided
   * information.
   *
   * @param  oid           The OID to use for this control.
   * @param  isCritical    Indicates whether this control should be considered
   *                       critical to the operation processing.
   * @param  changeType    The change type for this change notification control.
   * @param  previousDN    The DN that the entry had prior to a modify DN
   *                       operation, or <CODE>null</CODE> if the operation was
   *                       not a modify DN.
   * @param  changeNumber  The change number for the associated change, or a
   *                       negative value if no change number is available.
   * @param  encodedValue  The pre-encoded value for this change notification
   *                       control.
   */
  private EntryChangeNotificationControl(String oid, boolean isCritical,
                                         PersistentSearchChangeType changeType,
                                         DN previousDN, long changeNumber,
                                         ASN1OctetString encodedValue)
  {
    super(oid, isCritical, encodedValue);
    this.changeType   = changeType;
    this.previousDN   = previousDN;
    this.changeNumber = changeNumber;
  }
  /**
   * Encodes the provided information into an ASN.1 octet string suitable for
   * use as the control value.
   *
   * @param  changeType    The change type for this change notification control.
   * @param  previousDN    The DN that the entry had prior to a modify DN
   *                       operation, or <CODE>null</CODE> if the operation was
   *                       not a modify DN.
   * @param  changeNumber  The change number for the associated change, or a
   *                       negative value if no change number is available.
   *
   * @return  An ASN.1 octet string containing the encoded information.
   */
  private static ASN1OctetString encodeValue(PersistentSearchChangeType
                                                  changeType,
                                             DN previousDN, long changeNumber)
  {
    ArrayList<ASN1Element> elements =
         new ArrayList<ASN1Element>(3);
    elements.add(new ASN1Enumerated(changeType.intValue()));
    writer.writeStartSequence();
    writer.writeInteger(changeType.intValue());
    if (previousDN != null)
    {
      elements.add(new ASN1OctetString(previousDN.toString()));
      writer.writeOctetString(previousDN.toString());
    }
    if (changeNumber > 0)
    {
      elements.add(new ASN1Long(changeNumber));
      writer.writeInteger(changeNumber);
    }
    writer.writeEndSequence();
    return new ASN1OctetString(new ASN1Sequence(elements).encode());
  }
  /**
   * Creates a new entry change notification control from the contents of the
   * provided control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this entry change notification control.
   *
   * @return  The entry change notification control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         entry change notification control.
   */
  public static EntryChangeNotificationControl decodeControl(Control control)
         throws LDAPException
  {
    if (! control.hasValue())
    {
      Message message = ERR_ECN_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    DN                         previousDN   = null;
    long                       changeNumber = -1;
    PersistentSearchChangeType changeType;
    try
    {
      ArrayList<ASN1Element> elements =
           ASN1Sequence.decodeAsSequence(control.getValue().value()).elements();
      if ((elements.size() < 1) || (elements.size() > 3))
      {
        Message message = ERR_ECN_INVALID_ELEMENT_COUNT.get(elements.size());
        throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
      }
      int changeTypeValue = elements.get(0).decodeAsEnumerated().intValue();
      changeType = PersistentSearchChangeType.valueOf(changeTypeValue);
      if (elements.size() == 2)
      {
        ASN1Element e = elements.get(1);
        if (e.getType() == ASN1Constants.UNIVERSAL_OCTET_STRING_TYPE)
        {
          if (changeType != PersistentSearchChangeType.MODIFY_DN)
          {
            Message message =
                ERR_ECN_ILLEGAL_PREVIOUS_DN.get(String.valueOf(changeType));
            throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
          }
          ASN1OctetString rawPreviousDN = e.decodeAsOctetString();
          previousDN = DN.decode(rawPreviousDN);
        }
        else if (e.getType() == ASN1Constants.UNIVERSAL_INTEGER_TYPE)
        {
          changeNumber = e.decodeAsLong().longValue();
        }
        else
        {
          Message message =
              ERR_ECN_INVALID_ELEMENT_TYPE.get(byteToHex(e.getType()));
          throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
        }
      }
      else if (elements.size() == 3)
      {
        if (changeType != PersistentSearchChangeType.MODIFY_DN)
        {
          Message message =
              ERR_ECN_ILLEGAL_PREVIOUS_DN.get(String.valueOf(changeType));
          throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
        }
        ASN1OctetString rawPreviousDN = elements.get(1).decodeAsOctetString();
        previousDN = DN.decode(rawPreviousDN);
        changeNumber = elements.get(2).decodeAsLong().longValue();
      }
    }
    catch (LDAPException le)
    {
      throw le;
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message = ERR_ECN_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, e);
    }
    return new EntryChangeNotificationControl(control.getOID(),
                                              control.isCritical(), changeType,
                                              previousDN, changeNumber,
                                              control.getValue());
    writer.writeEndSequence();
  }
@@ -337,22 +285,6 @@
  }
  /**
   * Sets the change type for this entry change notification control.
   *
   * @param  changeType  The change type for this entry change notification
   *                     control.
   */
  public void setChangeType(PersistentSearchChangeType changeType)
  {
    this.changeType = changeType;
    setValue(encodeValue(changeType, previousDN, changeNumber));
  }
  /**
   * Retrieves the previous DN for this entry change notification control.
   *
@@ -367,21 +299,6 @@
  /**
   * Specifies the previous DN for this entry change notification control.
   *
   * @param  previousDN  The previous DN for this entry change notification
   *                     control.
   */
  public void setPreviousDN(DN previousDN)
  {
    this.previousDN = previousDN;
    setValue(encodeValue(changeType, previousDN, changeNumber));
  }
  /**
   * Retrieves the change number for this entry change notification control.
   *
   * @return  The change number for this entry change notification control, or a
@@ -395,36 +312,6 @@
  /**
   * Specifies the change number for this entry change notification control.
   *
   * @param  changeNumber  The change number for this entry change notification
   *                       control.
   */
  public void setChangeNumber(long changeNumber)
  {
    this.changeNumber = changeNumber;
    setValue(encodeValue(changeType, previousDN, changeNumber));
  }
  /**
   * Retrieves a string representation of this entry change notification
   * control.
   *
   * @return  A string representation of this entry change notification control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this entry change notification control
   * to the provided buffer.
   *
opends/src/server/org/opends/server/controls/GetEffectiveRights.java
File was deleted
opends/src/server/org/opends/server/controls/GetEffectiveRightsRequestControl.java
New file
@@ -0,0 +1,287 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 */
package org.opends.server.controls;
import org.opends.messages.Message;
import org.opends.server.types.*;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import static org.opends.server.util.ServerConstants.OID_GET_EFFECTIVE_RIGHTS;
import org.opends.server.core.DirectoryServer;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import java.util.List;
import java.util.LinkedList;
import java.io.IOException;
/**
 * This class partially implements the geteffectiverights control as defined
 * in draft-ietf-ldapext-acl-model-08.txt. The main differences are:
 *
 *  - The response control is not supported. Instead the dseecompat
 *    geteffectiverights control implementation creates attributes containing
 *    right information strings and adds those attributes to the
 *    entry being returned. The attribute type names are dynamically created;
 *    see the dseecompat's AciGetEffectiveRights class for details.
 *
 *  - The dseecompat implementation allows additional attribute types
 *    in the request control for which rights information can be returned.
 *    These are known as the specified attribute types.
 *
 * The dseecompat request control value is the following:
 *
 * <BR>
 * <PRE>
 *  GetRightsControl ::= SEQUENCE {
 *    authzId    authzId
 *    attributes  SEQUENCE OF AttributeType
 *  }
 *
 *   -- Only the "dn:DN form is supported.
 *
 * </PRE>
 *
 **/
public class GetEffectiveRightsRequestControl extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private static final class Decoder
      implements ControlDecoder<GetEffectiveRightsRequestControl>
  {
    /**
     * {@inheritDoc}
     */
    public GetEffectiveRightsRequestControl decode(boolean isCritical,
        ByteString value) throws DirectoryException
    {
      // If the value is null create a GetEffectiveRightsRequestControl
      // class with null authzDN and attribute list, else try to
      // decode the value.
      if (value == null)
        return new GetEffectiveRightsRequestControl(isCritical, (DN)null,
            (List<AttributeType>)null);
      else
      {
        ASN1Reader reader = ASN1.getReader(value);
        DN authzDN;
        List<AttributeType> attrs=null;
        String authzIDString="";
        try {
          reader.readStartSequence();
          authzIDString = reader.readOctetStringAsString();
          String lowerAuthzIDString = authzIDString.toLowerCase();
          //Make sure authzId starts with "dn:" and is a valid DN.
          if (lowerAuthzIDString.startsWith("dn:"))
            authzDN = DN.decode(authzIDString.substring(3));
          else {
            Message message = INFO_GETEFFECTIVERIGHTS_INVALID_AUTHZID.get(
                lowerAuthzIDString);
            throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
          }
          //There is an sequence containing an attribute list, try to decode it.
          if(reader.hasNextElement()) {
            AttributeType attributeType;
            attrs = new LinkedList<AttributeType>();
            reader.readStartSequence();
            while(reader.hasNextElement()) {
              //Decode as an octet string.
              String attrStr = reader.readOctetStringAsString();
              //Get an attribute type for it and add to the list.
              if((attributeType =
                  DirectoryServer.getAttributeType(attrStr)) == null)
                attributeType =
                    DirectoryServer.getDefaultAttributeType(attrStr);
              attrs.add(attributeType);
            }
            reader.readEndSequence();
          }
          reader.readEndSequence();
        } catch (ASN1Exception e) {
          if (debugEnabled()) {
            TRACER.debugCaught(DebugLogLevel.ERROR, e);
          }
          Message message =
              INFO_GETEFFECTIVERIGHTS_DECODE_ERROR.get(e.getMessage());
          throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
        }
        return new GetEffectiveRightsRequestControl(isCritical,
            authzDN, attrs);
      }
    }
    public String getOID()
    {
      return OID_GET_EFFECTIVE_RIGHTS;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<GetEffectiveRightsRequestControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
  //The DN representing the authzId. May be null.
  private DN authzDN=null;
  //The raw DN representing the authzId. May be null.
  private String rawAuthzDN=null;
  //The list of additional attribute types to return rights for. May be null.
  private List<AttributeType> attrs=null;
  //The raw DN representing the authzId. May be null.
  private List<String> rawAttrs=null;
  /**
   * Create a new geteffectiverights control with the specified authzDN and
   * an attribute list.
   *
   * @param authzDN  The authzDN.
   *
   * @param attrs  The list of additional attributes to be returned.
   */
  public GetEffectiveRightsRequestControl(DN authzDN,
                            List<AttributeType> attrs) {
    this(true, authzDN, attrs);
  }
  /**
   * Create a new geteffectiverights control with the specified authzDN and
   * an attribute list.
   *
   * @param  isCritical  Indicates whether this control should be
   *                     considered critical in processing the
   *                     request.
   * @param authzDN  The authzDN.
   * @param attrs  The list of additional attributes to be returned.
   */
  public GetEffectiveRightsRequestControl(boolean isCritical, DN authzDN,
                                          List<AttributeType> attrs) {
    super(OID_GET_EFFECTIVE_RIGHTS, isCritical);
    this.authzDN=authzDN;
    this.attrs=attrs;
  }
  /**
   * Create a new geteffectiverights control with the specified raw
   * authzDN and an attribute list.
   *
   * @param  isCritical  Indicates whether this control should be
   *                     considered critical in processing the
   *                     request.
   * @param authzDN  The authzDN.
   * @param attrs  The list of additional attributes to be returned.
   */
  public GetEffectiveRightsRequestControl(boolean isCritical,
                                          String authzDN,
                                          List<String> attrs)
  {
    super(OID_GET_EFFECTIVE_RIGHTS, isCritical);
    this.rawAuthzDN=authzDN;
    this.rawAttrs=attrs;
  }
  /**
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  @Override
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    writer.writeStartSequence();
    if(authzDN != null)
    {
      writer.writeOctetString("dn:" + authzDN.toString());
    }
    else if(rawAuthzDN != null)
    {
      writer.writeOctetString("dn:" + rawAuthzDN);
    }
    if(attrs != null)
    {
      writer.writeStartSequence();
      for(AttributeType attr : attrs)
      {
        writer.writeOctetString(attr.getNameOrOID());
      }
      writer.writeEndSequence();
    }
    else if(rawAttrs != null)
    {
      writer.writeStartSequence();
      for(String attr : rawAttrs)
      {
        writer.writeOctetString(attr);
      }
      writer.writeEndSequence();
    }
    writer.writeEndSequence();
    writer.writeEndSequence();
  }
  /**
   * Return the authzDN parsed from the control.
   *
   * @return The DN representing the authzId.
   */
  public DN getAuthzDN () {
    return authzDN;
    // TODO: what if rawAuthzDN is not null?
  }
  /**
   * Return the requested additional attributes parsed from the control. Known
   * as the specified attributes.
   *
   * @return  The list containing any additional attributes to return rights
   *          about.
   */
  public List<AttributeType> getAttributes() {
    return attrs;
  }
}
opends/src/server/org/opends/server/controls/LDAPAssertionRequestControl.java
@@ -28,23 +28,16 @@
import org.opends.messages.Message;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.Control;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.LDAPException;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import java.io.IOException;
/**
@@ -55,13 +48,54 @@
 * control.
 */
public class LDAPAssertionRequestControl
       extends Control
    extends Control
{
  /**
   * The tracer object for the debug logger.
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private static final DebugTracer TRACER = getTracer();
  private final static class Decoder
      implements ControlDecoder<LDAPAssertionRequestControl>
  {
    /**
     * {@inheritDoc}
     */
    public LDAPAssertionRequestControl decode(boolean isCritical,
                                              ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        Message message = ERR_LDAPASSERT_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      LDAPFilter filter;
      try
      {
        filter = LDAPFilter.decode(reader);
      }
      catch (LDAPException e)
      {
        throw new DirectoryException(ResultCode.valueOf(e.getResultCode()), e
            .getMessageObject(), e.getCause());
      }
      return new LDAPAssertionRequestControl(isCritical, filter);
    }
    public String getOID()
    {
      return OID_LDAP_ASSERTION;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<LDAPAssertionRequestControl> DECODER =
    new Decoder();
@@ -84,8 +118,7 @@
   */
  public LDAPAssertionRequestControl(boolean isCritical, LDAPFilter rawFilter)
  {
    super(OID_LDAP_ASSERTION, isCritical,
          new ASN1OctetString(rawFilter.encode().encode()));
    super(OID_LDAP_ASSERTION, isCritical);
    this.rawFilter = rawFilter;
@@ -96,98 +129,17 @@
  /**
   * Creates a new instance of this LDAP assertion request control with the
   * provided information.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  oid         The OID to use for this control.
   * @param  isCritical  Indicates whether support for this control should be
   *                     considered a critical part of the server processing.
   * @param  rawFilter   The unparsed LDAP search filter contained in the
   *                     request from the client.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public LDAPAssertionRequestControl(String oid, boolean isCritical,
                                     LDAPFilter rawFilter)
  {
    super(oid, isCritical, new ASN1OctetString(rawFilter.encode().encode()));
    this.rawFilter = rawFilter;
    filter = null;
  }
  /**
   * Creates a new instance of this LDAP assertion request control with the
   * provided information.
   *
   * @param  oid           The OID to use for this control.
   * @param  isCritical    Indicates whether support for this control should be
   *                       considered a critical part of the server processing.
   * @param  rawFilter     The unparsed LDAP search filter contained in the
   *                       request from the client.
   * @param  encodedValue  The pre-encoded value for this control.
   */
  private LDAPAssertionRequestControl(String oid, boolean isCritical,
                                      LDAPFilter rawFilter,
                                      ASN1OctetString encodedValue)
  {
    super(oid, isCritical, encodedValue);
    this.rawFilter = rawFilter;
    filter = null;
  }
  /**
   * Creates a new LDAP assertion request control from the contents of the
   * provided control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this LDAP assertion request control.
   *
   * @return  The LDAP assertion control decoded from the provided control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid LDAP
   *                         assertion control.
   */
  public static LDAPAssertionRequestControl decodeControl(Control control)
         throws LDAPException
  {
    if (! control.hasValue())
    {
      Message message = ERR_LDAPASSERT_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    ASN1Element valueElement;
    try
    {
      valueElement = ASN1Element.decode(control.getValue().value());
    }
    catch (ASN1Exception ae)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ae);
      }
      Message message =
          ERR_LDAPASSERT_INVALID_CONTROL_VALUE.get(ae.getMessage());
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message,
                              ae);
    }
    return new LDAPAssertionRequestControl(control.getOID(),
                                           control.isCritical(),
                                           LDAPFilter.decode(valueElement),
                                           control.getValue());
  @Override
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    rawFilter.write(writer);
    writer.writeEndSequence();
  }
@@ -203,23 +155,6 @@
  }
  /**
   * Sets the raw, unparsed filter from the request control.  This method should
   * only be called by pre-parse plugins.
   *
   * @param  rawFilter  The raw, unparsed filter from the request control.
   */
  public void setRawFilter(LDAPFilter rawFilter)
  {
    this.rawFilter = rawFilter;
    this.filter    = null;
    setValue(new ASN1OctetString(rawFilter.encode().encode()));
  }
  /**
   * Retrieves the processed search filter for this control.
   *
@@ -242,25 +177,12 @@
  /**
   * Retrieves a string representation of this LDAP assertion request control.
   *
   * @return  A string representation of this LDAP assertion request control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this LDAP assertion request control to
   * the provided buffer.
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("LDAPAssertionRequestControl(criticality=");
opends/src/server/org/opends/server/controls/LDAPPostReadRequestControl.java
@@ -28,25 +28,19 @@
import org.opends.messages.Message;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.io.IOException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.AttributeType;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.opends.server.types.ObjectClass;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
@@ -63,6 +57,68 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<LDAPPostReadRequestControl>
  {
    /**
     * {@inheritDoc}
     */
    public LDAPPostReadRequestControl decode(boolean isCritical,
                                             ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        Message message = ERR_POSTREADREQ_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      LinkedHashSet<String> rawAttributes = new LinkedHashSet<String>();
      try
      {
        reader.readStartSequence();
        while(reader.hasNextElement())
        {
          rawAttributes.add(reader.readOctetStringAsString());
        }
        reader.readEndSequence();
      }
      catch (Exception ae)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ae);
        }
        Message message =
            ERR_POSTREADREQ_CANNOT_DECODE_VALUE.get(ae.getMessage());
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message,
            ae);
      }
      return new LDAPPostReadRequestControl(isCritical,
          rawAttributes);
    }
    public String getOID()
    {
      return OID_LDAP_READENTRY_POSTREAD;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<LDAPPostReadRequestControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -79,10 +135,10 @@
  private boolean returnAllUserAttrs;
  // The set of raw attributes to return in the entry.
  private LinkedHashSet<String> rawAttributes;
  private Set<String> rawAttributes;
  // The set of processed attributes to return in the entry.
  private LinkedHashSet<AttributeType> requestedAttributes;
  private Set<AttributeType> requestedAttributes;
@@ -97,10 +153,9 @@
   *                        attributes should be returned.
   */
  public LDAPPostReadRequestControl(boolean isCritical,
                                    LinkedHashSet<String> rawAttributes)
                                    Set<String> rawAttributes)
  {
    super(OID_LDAP_READENTRY_POSTREAD, isCritical,
          encodeAttributes(rawAttributes));
    super(OID_LDAP_READENTRY_POSTREAD, isCritical);
    if (rawAttributes == null)
@@ -131,9 +186,9 @@
   *                        attributes should be returned.
   */
  public LDAPPostReadRequestControl(String oid, boolean isCritical,
                                    LinkedHashSet<String> rawAttributes)
                                    Set<String> rawAttributes)
  {
    super(oid, isCritical, encodeAttributes(rawAttributes));
    super(oid, isCritical);
    if (rawAttributes == null)
@@ -150,126 +205,31 @@
    returnAllUserAttrs        = false;
  }
  /**
   * Creates a new instance of this LDAP post-read request control with the
   * provided information.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  oid            The OID to use for this control.
   * @param  isCritical     Indicates whether support for this control should be
   *                        considered a critical part of the server processing.
   * @param  rawAttributes  The set of raw attributes to return in the entry.
   *                        A null or empty set will indicates that all user
   *                        attributes should be returned.
   * @param  encodedValue   The post-encoded value for this control.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  private LDAPPostReadRequestControl(String oid, boolean isCritical,
                                     LinkedHashSet<String> rawAttributes,
                                     ASN1OctetString encodedValue)
  {
    super(oid, isCritical, encodedValue);
  @Override
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    if (rawAttributes == null)
    writer.writeStartSequence();
    if (rawAttributes != null)
    {
      this.rawAttributes = new LinkedHashSet<String>(0);
    }
    else
    {
      this.rawAttributes = rawAttributes;
    }
    requestedAttributes       = null;
    returnAllOperationalAttrs = false;
    returnAllUserAttrs        = false;
  }
  /**
   * Creates a new LDAP post-read request control from the contents of the
   * provided control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this LDAP post-read request control.
   *
   * @return  The LDAP post-read request control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid LDAP
   *                         post-read request control.
   */
  public static LDAPPostReadRequestControl decodeControl(Control control)
         throws LDAPException
  {
    if (! control.hasValue())
    {
      Message message = ERR_POSTREADREQ_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    LinkedHashSet<String> rawAttributes = new LinkedHashSet<String>();
    try
    {
      ASN1Sequence attrSequence =
           ASN1Sequence.decodeAsSequence(control.getValue().value());
      for (ASN1Element e : attrSequence.elements())
      for (String attr : rawAttributes)
      {
        rawAttributes.add(e.decodeAsOctetString().stringValue());
        writer.writeOctetString(attr);
      }
    }
    catch (ASN1Exception ae)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ae);
      }
    writer.writeEndSequence();
      Message message =
          ERR_POSTREADREQ_CANNOT_DECODE_VALUE.get(ae.getMessage());
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message,
                              ae);
    }
    return new LDAPPostReadRequestControl(control.getOID(),
                                          control.isCritical(),
                                          rawAttributes, control.getValue());
    writer.writeEndSequence();
  }
  /**
   * Encodes the provided set of raw, unprocessed attribute names to an
   * ASN.1 octet string suitable for use as the value of this control.
   *
   * @param  rawAttributes  The set of attributes to encoded in the encoded
   *                        control value.
   *
   * @return  The ASN.1 octet string containing the encoded attribute set.
   */
  private static ASN1OctetString encodeAttributes(LinkedHashSet<String>
                                                       rawAttributes)
  {
    if (rawAttributes == null)
    {
      return new ASN1OctetString(new ASN1Sequence().encode());
    }
    ArrayList<ASN1Element> elements =
         new ArrayList<ASN1Element>(rawAttributes.size());
    for (String attr : rawAttributes)
    {
      elements.add(new ASN1OctetString(attr));
    }
    return new ASN1OctetString(new ASN1Sequence(elements).encode());
  }
  /**
   * Retrieves the raw, unprocessed set of requested attributes.  It must not
   * be altered by the caller without calling <CODE>setRawAttributes</CODE> with
@@ -277,36 +237,12 @@
   *
   * @return  The raw, unprocessed set of attributes.
   */
  public LinkedHashSet<String> getRawAttributes()
  public Set<String> getRawAttributes()
  {
    return rawAttributes;
  }
  /**
   * Specifies the raw, unprocessed set of requested attributes.  A null or
   * empty set indicates that all user attributes should be returned.
   *
   * @param  rawAttributes  The raw, unprocessed set of requested attributes.
   */
  public void setRawAttributes(LinkedHashSet<String> rawAttributes)
  {
    if (rawAttributes == null)
    {
      this.rawAttributes = new LinkedHashSet<String>();
    }
    else
    {
      this.rawAttributes = rawAttributes;
    }
    setValue(encodeAttributes(rawAttributes));
    requestedAttributes = null;
  }
  /**
   * Retrieves the set of processed attributes that have been requested for
   * inclusion in the entry that is returned.
@@ -314,7 +250,7 @@
   * @return  The set of processed attributes that have been requested for
   *          inclusion in the entry that is returned.
   */
  public LinkedHashSet<AttributeType> getRequestedAttributes()
  public Set<AttributeType> getRequestedAttributes()
  {
    if (requestedAttributes == null)
    {
@@ -441,25 +377,12 @@
  /**
   * Retrieves a string representation of this LDAP post-read request control.
   *
   * @return  A string representation of this LDAP post-read request control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this LDAP post-read request control to
   * the provided buffer.
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("LDAPPostReadRequestControl(criticality=");
opends/src/server/org/opends/server/controls/LDAPPostReadResponseControl.java
@@ -28,22 +28,18 @@
import org.opends.messages.Message;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.protocols.ldap.SearchResultEntryProtocolOp;
import org.opends.server.types.Control;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.protocols.ldap.*;
import org.opends.server.types.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import java.io.IOException;
/**
@@ -52,9 +48,68 @@
 * entry immediately before an add, modify, or modify DN operation.
 */
public class LDAPPostReadResponseControl
       extends Control
    extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<LDAPPostReadResponseControl>
  {
    /**
     * {@inheritDoc}
     */
    public LDAPPostReadResponseControl decode(boolean isCritical,
                                              ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        Message message = ERR_POSTREADRESP_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      SearchResultEntry searchEntry;
      try
      {
        SearchResultEntryProtocolOp searchResultEntryProtocolOp =
            LDAPReader.readSearchEntry(reader);
        searchEntry = searchResultEntryProtocolOp.toSearchResultEntry();
      }
      catch (LDAPException le)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, le);
        }
        Message message =
            ERR_POSTREADRESP_CANNOT_DECODE_VALUE.get(le.getMessage());
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message,
            le);
      }
      return new LDAPPostReadResponseControl(isCritical, searchEntry);
    }
    public String getOID()
    {
      return OID_LDAP_READENTRY_POSTREAD;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<LDAPPostReadResponseControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -76,11 +131,7 @@
   */
  public LDAPPostReadResponseControl(SearchResultEntry searchEntry)
  {
    super(OID_LDAP_READENTRY_POSTREAD, false,
          encodeEntry(searchEntry));
    this.searchEntry = searchEntry;
    this(false, searchEntry);
  }
@@ -89,122 +140,36 @@
   * Creates a new instance of this LDAP post-read response control with the
   * provided information.
   *
   * @param  oid          The OID to use for this control.
   * @param  isCritical   Indicates whether support for this control should be
   *                      considered a critical part of the server processing.
   * @param  searchEntry  The search result entry to include in the response
   *                      control.
   */
  public LDAPPostReadResponseControl(String oid, boolean isCritical,
                                    SearchResultEntry searchEntry)
  {
    super(oid, isCritical, encodeEntry(searchEntry));
    this.searchEntry = searchEntry;
  }
  /**
   * Creates a new instance of this LDAP post-read response control with the
   * provided information.
   *
   * @param  oid           The OID to use for this control.
   * @param  isCritical    Indicates whether support for this control should be
   *                       considered a critical part of the server processing.
   * @param  searchEntry   The search result entry to include in the response
   *                       control.
   * @param  encodedValue  The pre-encoded value for this control.
   */
  private LDAPPostReadResponseControl(String oid, boolean isCritical,
                                      SearchResultEntry searchEntry,
                                      ASN1OctetString encodedValue)
  public LDAPPostReadResponseControl(boolean isCritical,
                                     SearchResultEntry searchEntry)
  {
    super(oid, isCritical, encodedValue);
    super(OID_LDAP_READENTRY_POSTREAD, isCritical);
    this.searchEntry = searchEntry;
  }
  /**
   * Creates a new LDAP post-read response control from the contents of the
   * provided control.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this LDAP post-read response control.
   *
   * @return  The LDAP post-read response control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid LDAP
   *                         post-read response control.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public static LDAPPostReadResponseControl decodeControl(Control control)
         throws LDAPException
  {
    if (! control.hasValue())
    {
      Message message = ERR_POSTREADRESP_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
  @Override
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    ASN1OctetString controlValue = control.getValue();
    SearchResultEntry searchEntry;
    try
    {
      ASN1Element element = ASN1Element.decode(controlValue.value());
      SearchResultEntryProtocolOp searchResultEntryProtocolOp =
           SearchResultEntryProtocolOp.decodeSearchEntry(element);
      searchEntry = searchResultEntryProtocolOp.toSearchResultEntry();
    }
    catch (ASN1Exception ae)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ae);
      }
      Message message =
          ERR_POSTREADRESP_CANNOT_DECODE_VALUE.get(ae.getMessage());
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message,
                              ae);
    }
    catch (LDAPException le)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, le);
      }
      Message message =
          ERR_POSTREADRESP_CANNOT_DECODE_VALUE.get(le.getMessage());
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message,
                              le);
    }
    return new LDAPPostReadResponseControl(control.getOID(),
                                           control.isCritical(), searchEntry,
                                           controlValue);
  }
  /**
   * Encodes the provided search result entry for use as an attribute value.
   *
   * @param  searchEntry  The search result entry to be encoded.
   *
   * @return  The ASN.1 octet string containing the encoded control value.
   */
  private static ASN1OctetString encodeEntry(SearchResultEntry searchEntry)
  {
    SearchResultEntryProtocolOp protocolOp =
         new SearchResultEntryProtocolOp(searchEntry);
    return new ASN1OctetString(protocolOp.encode().encode());
        new SearchResultEntryProtocolOp(searchEntry);
    protocolOp.write(writer);
    writer.writeEndSequence();
  }
@@ -224,40 +189,12 @@
  /**
   * Specifies the search result entry for use with this post-read response
   * control.
   *
   * @param  searchEntry  The search result entry for use with this post-read
   *                      response control.
   */
  public void setSearchEntry(SearchResultEntry searchEntry)
  {
    this.searchEntry = searchEntry;
    setValue(encodeEntry(searchEntry));
  }
  /**
   * Retrieves a string representation of this LDAP post-read response control.
   *
   * @return  A string representation of this LDAP post-read response control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this LDAP post-read response control to
   * the provided buffer.
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("LDAPPostReadResponseControl(criticality=");
opends/src/server/org/opends/server/controls/LDAPPreReadRequestControl.java
@@ -28,22 +28,16 @@
import org.opends.messages.Message;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.io.IOException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.AttributeType;
import org.opends.server.types.Control;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.types.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
@@ -63,6 +57,67 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<LDAPPreReadRequestControl>
  {
    /**
     * {@inheritDoc}
     */
    public LDAPPreReadRequestControl decode(boolean isCritical,
                                            ByteString value)
        throws DirectoryException
    {
     if (value == null)
      {
        Message message = ERR_PREREADREQ_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      LinkedHashSet<String> rawAttributes = new LinkedHashSet<String>();
      try
      {
        reader.readStartSequence();
        while(reader.hasNextElement())
        {
          rawAttributes.add(reader.readOctetStringAsString());
        }
        reader.readEndSequence();
      }
      catch (Exception ae)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ae);
        }
        Message message =
            ERR_PREREADREQ_CANNOT_DECODE_VALUE.get(ae.getMessage());
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message,
            ae);
      }
      return new LDAPPreReadRequestControl(isCritical,
          rawAttributes);
    }
    public String getOID()
    {
      return OID_LDAP_READENTRY_PREREAD;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<LDAPPreReadRequestControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -79,10 +134,10 @@
  private boolean returnAllUserAttrs;
  // The set of raw attributes to return in the entry.
  private LinkedHashSet<String> rawAttributes;
  private Set<String> rawAttributes;
  // The set of processed attributes to return in the entry.
  private LinkedHashSet<AttributeType> requestedAttributes;
  private Set<AttributeType> requestedAttributes;
@@ -97,10 +152,9 @@
   *                        attributes should be returned.
   */
  public LDAPPreReadRequestControl(boolean isCritical,
                                   LinkedHashSet<String> rawAttributes)
                                   Set<String> rawAttributes)
  {
    super(OID_LDAP_READENTRY_PREREAD, isCritical,
          encodeAttributes(rawAttributes));
    super(OID_LDAP_READENTRY_PREREAD, isCritical);
    if (rawAttributes == null)
@@ -120,150 +174,27 @@
  /**
   * Creates a new instance of this LDAP pre-read request control with the
   * provided information.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  oid            The OID to use for this control.
   * @param  isCritical     Indicates whether support for this control should be
   *                        considered a critical part of the server processing.
   * @param  rawAttributes  The set of raw attributes to return in the entry.
   *                        A null or empty set will indicates that all user
   *                        attributes should be returned.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public LDAPPreReadRequestControl(String oid, boolean isCritical,
                                   LinkedHashSet<String> rawAttributes)
  {
    super(oid, isCritical, encodeAttributes(rawAttributes));
  @Override
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    if (rawAttributes == null)
    writer.writeStartSequence();
    if (rawAttributes != null)
    {
      this.rawAttributes = new LinkedHashSet<String>(0);
    }
    else
    {
      this.rawAttributes = rawAttributes;
    }
    requestedAttributes       = null;
    returnAllOperationalAttrs = false;
    returnAllUserAttrs        = false;
  }
  /**
   * Creates a new instance of this LDAP pre-read request control with the
   * provided information.
   *
   * @param  oid            The OID to use for this control.
   * @param  isCritical     Indicates whether support for this control should be
   *                        considered a critical part of the server processing.
   * @param  rawAttributes  The set of raw attributes to return in the entry.
   *                        A null or empty set will indicates that all user
   *                        attributes should be returned.
   * @param  encodedValue   The pre-encoded value for this control.
   */
  private LDAPPreReadRequestControl(String oid, boolean isCritical,
                                    LinkedHashSet<String> rawAttributes,
                                    ASN1OctetString encodedValue)
  {
    super(oid, isCritical, encodedValue);
    if (rawAttributes == null)
    {
      this.rawAttributes = new LinkedHashSet<String>(0);
    }
    else
    {
      this.rawAttributes = rawAttributes;
    }
    requestedAttributes       = null;
    returnAllOperationalAttrs = false;
    returnAllUserAttrs        = false;
  }
  /**
   * Creates a new LDAP pre-read request control from the contents of the
   * provided control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this LDAP pre-read request control.
   *
   * @return  The LDAP pre-read request control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid LDAP
   *                         pre-read request control.
   */
  public static LDAPPreReadRequestControl decodeControl(Control control)
         throws LDAPException
  {
    if (! control.hasValue())
    {
      Message message = ERR_PREREADREQ_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    LinkedHashSet<String> rawAttributes = new LinkedHashSet<String>();
    try
    {
      ASN1Sequence attrSequence =
           ASN1Sequence.decodeAsSequence(control.getValue().value());
      for (ASN1Element e : attrSequence.elements())
      for (String attr : rawAttributes)
      {
        rawAttributes.add(e.decodeAsOctetString().stringValue());
        writer.writeOctetString(attr);
      }
    }
    catch (ASN1Exception ae)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ae);
      }
    writer.writeEndSequence();
      Message message = ERR_PREREADREQ_CANNOT_DECODE_VALUE.get(ae.getMessage());
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message,
                              ae);
    }
    return new LDAPPreReadRequestControl(control.getOID(), control.isCritical(),
                                         rawAttributes, control.getValue());
  }
  /**
   * Encodes the provided set of raw, unprocessed attribute names to an
   * ASN.1 octet string suitable for use as the value of this control.
   *
   * @param  rawAttributes  The set of attributes to encoded in the encoded
   *                        control value.
   *
   * @return  The ASN.1 octet string containing the encoded attribute set.
   */
  private static ASN1OctetString encodeAttributes(LinkedHashSet<String>
                                                       rawAttributes)
  {
    if (rawAttributes == null)
    {
      return new ASN1OctetString(new ASN1Sequence().encode());
    }
    ArrayList<ASN1Element> elements =
         new ArrayList<ASN1Element>(rawAttributes.size());
    for (String attr : rawAttributes)
    {
      elements.add(new ASN1OctetString(attr));
    }
    return new ASN1OctetString(new ASN1Sequence(elements).encode());
    writer.writeEndSequence();
  }
@@ -275,7 +206,7 @@
   *
   * @return  The raw, unprocessed set of attributes.
   */
  public LinkedHashSet<String> getRawAttributes()
  public Set<String> getRawAttributes()
  {
    return rawAttributes;
  }
@@ -283,36 +214,13 @@
  /**
   * Specifies the raw, unprocessed set of requested attributes.  A null or
   * empty set indicates that all user attributes should be returned.
   *
   * @param  rawAttributes  The raw, unprocessed set of requested attributes.
   */
  public void setRawAttributes(LinkedHashSet<String> rawAttributes)
  {
    if (rawAttributes == null)
    {
      this.rawAttributes = new LinkedHashSet<String>();
    }
    else
    {
      this.rawAttributes = rawAttributes;
    }
    setValue(encodeAttributes(rawAttributes));
    requestedAttributes = null;
  }
  /**
   * Retrieves the set of processed attributes that have been requested for
   * inclusion in the entry that is returned.
   *
   * @return  The set of processed attributes that have been requested for
   *          inclusion in the entry that is returned.
   */
  public LinkedHashSet<AttributeType> getRequestedAttributes()
  public Set<AttributeType> getRequestedAttributes()
  {
    if (requestedAttributes == null)
    {
@@ -439,25 +347,12 @@
  /**
   * Retrieves a string representation of this LDAP pre-read request control.
   *
   * @return  A string representation of this LDAP pre-read request control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this LDAP pre-read request control to
   * the provided buffer.
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("LDAPPreReadRequestControl(criticality=");
opends/src/server/org/opends/server/controls/LDAPPreReadResponseControl.java
@@ -28,22 +28,19 @@
import org.opends.messages.Message;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.protocols.ldap.SearchResultEntryProtocolOp;
import org.opends.server.types.Control;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.ldap.LDAPReader;
import org.opends.server.types.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import java.io.IOException;
/**
@@ -55,6 +52,63 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<LDAPPreReadResponseControl>
  {
    /**
     * {@inheritDoc}
     */
    public LDAPPreReadResponseControl decode(boolean isCritical,
                                             ByteString value)
        throws DirectoryException
    {
     if (value == null)
      {
        Message message = ERR_PREREADRESP_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      SearchResultEntry searchEntry;
      try
      {
        SearchResultEntryProtocolOp searchResultEntryProtocolOp =
            LDAPReader.readSearchEntry(reader);
        searchEntry = searchResultEntryProtocolOp.toSearchResultEntry();
      }
      catch (LDAPException le)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, le);
        }
        Message message =
            ERR_PREREADRESP_CANNOT_DECODE_VALUE.get(le.getMessage());
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message,
            le);
      }
      return new LDAPPreReadResponseControl(isCritical, searchEntry);
    }
    public String getOID()
    {
      return OID_LDAP_READENTRY_PREREAD;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<LDAPPreReadResponseControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -76,11 +130,7 @@
   */
  public LDAPPreReadResponseControl(SearchResultEntry searchEntry)
  {
    super(OID_LDAP_READENTRY_PREREAD, false,
          encodeEntry(searchEntry));
    this.searchEntry = searchEntry;
    this(false, searchEntry);
  }
@@ -89,16 +139,15 @@
   * Creates a new instance of this LDAP pre-read response control with the
   * provided information.
   *
   * @param  oid          The OID to use for this control.
   * @param  isCritical   Indicates whether support for this control should be
   *                      considered a critical part of the server processing.
   * @param  searchEntry  The search result entry to include in the response
   *                      control.
   */
  public LDAPPreReadResponseControl(String oid, boolean isCritical,
  public LDAPPreReadResponseControl(boolean isCritical,
                                    SearchResultEntry searchEntry)
  {
    super(oid, isCritical, encodeEntry(searchEntry));
    super(OID_LDAP_READENTRY_PREREAD, isCritical);
    this.searchEntry = searchEntry;
@@ -107,104 +156,21 @@
  /**
   * Creates a new instance of this LDAP pre-read response control with the
   * provided information.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  oid           The OID to use for this control.
   * @param  isCritical    Indicates whether support for this control should be
   *                       considered a critical part of the server processing.
   * @param  searchEntry   The search result entry to include in the response
   *                       control.
   * @param  encodedValue  The pre-encoded value for this control.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  private LDAPPreReadResponseControl(String oid, boolean isCritical,
                                     SearchResultEntry searchEntry,
                                     ASN1OctetString encodedValue)
  {
    super(oid, isCritical, encodedValue);
  @Override
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    this.searchEntry = searchEntry;
  }
  /**
   * Creates a new LDAP pre-read response control from the contents of the
   * provided control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this LDAP pre-read response control.
   *
   * @return  The LDAP pre-read response control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid LDAP
   *                         pre-read response control.
   */
  public static LDAPPreReadResponseControl decodeControl(Control control)
         throws LDAPException
  {
    if (! control.hasValue())
    {
      Message message = ERR_PREREADRESP_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    ASN1OctetString controlValue = control.getValue();
    SearchResultEntry searchEntry;
    try
    {
      ASN1Element element = ASN1Element.decode(controlValue.value());
      SearchResultEntryProtocolOp searchResultEntryProtocolOp =
           SearchResultEntryProtocolOp.decodeSearchEntry(element);
      searchEntry = searchResultEntryProtocolOp.toSearchResultEntry();
    }
    catch (ASN1Exception ae)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ae);
      }
      Message message =
          ERR_PREREADRESP_CANNOT_DECODE_VALUE.get(ae.getMessage());
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message,
                              ae);
    }
    catch (LDAPException le)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, le);
      }
      Message message =
          ERR_PREREADRESP_CANNOT_DECODE_VALUE.get(le.getMessage());
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message,
                              le);
    }
    return new LDAPPreReadResponseControl(control.getOID(),
                                          control.isCritical(), searchEntry,
                                          controlValue);
  }
  /**
   * Encodes the provided search result entry for use as an attribute value.
   *
   * @param  searchEntry  The search result entry to be encoded.
   *
   * @return  The ASN.1 octet string containing the encoded control value.
   */
  private static ASN1OctetString encodeEntry(SearchResultEntry searchEntry)
  {
    SearchResultEntryProtocolOp protocolOp =
         new SearchResultEntryProtocolOp(searchEntry);
    return new ASN1OctetString(protocolOp.encode().encode());
        new SearchResultEntryProtocolOp(searchEntry);
    protocolOp.write(writer);
    writer.writeEndSequence();
  }
@@ -224,40 +190,12 @@
  /**
   * Specifies the search result entry for use with this pre-read response
   * control.
   *
   * @param  searchEntry  The search result entry for use with this pre-read
   *                      response control.
   */
  public void setSearchEntry(SearchResultEntry searchEntry)
  {
    this.searchEntry = searchEntry;
    setValue(encodeEntry(searchEntry));
  }
  /**
   * Retrieves a string representation of this LDAP pre-read response control.
   *
   * @return  A string representation of this LDAP pre-read response control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this LDAP pre-read response control to
   * the provided buffer.
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("LDAPPreReadResponseControl(criticality=");
opends/src/server/org/opends/server/controls/MatchedValuesControl.java
@@ -30,16 +30,12 @@
import java.util.ArrayList;
import java.io.IOException;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.Control;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.types.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
@@ -59,6 +55,75 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<MatchedValuesControl>
  {
    /**
     * {@inheritDoc}
     */
    public MatchedValuesControl decode(boolean isCritical, ByteString value)
        throws DirectoryException
    {
      ArrayList<MatchedValuesFilter> filters;
      if (value == null)
      {
        Message message = ERR_MATCHEDVALUES_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      try
      {
        reader.readStartSequence();
        if (!reader.hasNextElement())
        {
          Message message = ERR_MATCHEDVALUES_NO_FILTERS.get();
          throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
        }
        filters = new ArrayList<MatchedValuesFilter>();
        while(reader.hasNextElement())
        {
          filters.add(MatchedValuesFilter.decode(reader));
        }
        reader.readEndSequence();
      }
      catch (DirectoryException e)
      {
        throw e;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message = ERR_MATCHEDVALUES_CANNOT_DECODE_VALUE_AS_SEQUENCE.get(
            getExceptionMessage(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      return new MatchedValuesControl(isCritical,filters);
    }
    public String getOID()
    {
      return OID_MATCHED_VALUES;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<MatchedValuesControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -67,7 +132,7 @@
  // The set of matched values filters for this control.
  ArrayList<MatchedValuesFilter> filters;
  private final ArrayList<MatchedValuesFilter> filters;
@@ -83,7 +148,7 @@
  public MatchedValuesControl(boolean isCritical,
                              ArrayList<MatchedValuesFilter> filters)
  {
    super(OID_MATCHED_VALUES, isCritical, encodeValue(filters));
    super(OID_MATCHED_VALUES, isCritical);
    this.filters = filters;
@@ -92,136 +157,27 @@
  /**
   * Creates a new matched values control using the default OID and the provided
   * criticality and set of filters.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  oid         The OID for this matched values control.
   * @param  isCritical  Indicates whether this control should be considered
   *                     critical to the operation processing.
   * @param  filters     The set of filters to use to determine which values to
   *                     return.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public MatchedValuesControl(String oid, boolean isCritical,
                              ArrayList<MatchedValuesFilter> filters)
  {
    super(oid, isCritical, encodeValue(filters));
  @Override
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    this.filters = filters;
  }
  /**
   * Creates a new matched values control using the default OID and the provided
   * criticality and set of filters.
   *
   * @param  oid           The OID for this matched values control.
   * @param  isCritical    Indicates whether this control should be considered
   *                       critical to the operation processing.
   * @param  filters       The set of filters to use to determine which values
   *                       to return.
   * @param  encodedValue  The pre-encoded value for this matched values
   *                       control.
   */
  private MatchedValuesControl(String oid, boolean isCritical,
                               ArrayList<MatchedValuesFilter> filters,
                               ASN1OctetString encodedValue)
  {
    super(oid, isCritical, encodedValue);
    this.filters = filters;
  }
  /**
   * Encodes the provided information into an ASN.1 octet string suitable for
   * use as the control value.
   *
   * @param  filters  The set of filters to include in the control value.
   *
   * @return  An ASN.1 octet string containing the encoded information.
   */
  private static ASN1OctetString
                      encodeValue(ArrayList<MatchedValuesFilter> filters)
  {
    ArrayList<ASN1Element> elements =
         new ArrayList<ASN1Element>(filters.size());
    writer.writeStartSequence();
    for (MatchedValuesFilter f : filters)
    {
      elements.add(f.encode());
      f.encode(writer);
    }
    writer.writeEndSequence();
    return new ASN1OctetString(new ASN1Sequence(elements).encode());
    writer.writeEndSequence();
  }
  /**
   * Creates a new matched values control from the contents of the provided
   * control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this matched values control.
   *
   * @return  The matched values control decoded from the provided control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         matched values control.
   */
  public static MatchedValuesControl decodeControl(Control control)
         throws LDAPException
  {
    if (! control.hasValue())
    {
      Message message = ERR_MATCHEDVALUES_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    ArrayList<ASN1Element> elements;
    try
    {
      elements =
           ASN1Sequence.decodeAsSequence(control.getValue().value()).elements();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message = ERR_MATCHEDVALUES_CANNOT_DECODE_VALUE_AS_SEQUENCE.get(
          getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    if (elements.isEmpty())
    {
      Message message = ERR_MATCHEDVALUES_NO_FILTERS.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    ArrayList<MatchedValuesFilter> filters =
         new ArrayList<MatchedValuesFilter>(elements.size());
    for (ASN1Element e : elements)
    {
      filters.add(MatchedValuesFilter.decode(e));
    }
    return new MatchedValuesControl(control.getOID(), control.isCritical(),
                                    filters, control.getValue());
  }
  /**
   * Retrieves the set of filters associated with this matched values control.
   *
@@ -271,27 +227,12 @@
  /**
   * Retrieves a string representation of this authorization identity response
   * control.
   *
   * @return  A string representation of this authorization identity response
   *          control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this authorization identity response
   * control to the provided buffer.
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    if (filters.size() == 1)
opends/src/server/org/opends/server/controls/MatchedValuesFilter.java
@@ -31,6 +31,7 @@
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import org.opends.server.api.ApproximateMatchingRule;
import org.opends.server.api.EqualityMatchingRule;
@@ -38,21 +39,13 @@
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.api.SubstringMatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.asn1.*;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.LDAPException;
import org.opends.server.types.RawFilter;
import org.opends.server.util.Validator;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.protocols.ldap.LDAPConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -130,19 +123,19 @@
  private ApproximateMatchingRule approximateMatchingRule;
  // The normalized subFinal value for this matched values filter.
  private ASN1OctetString normalizedSubFinal;
  private ByteString normalizedSubFinal;
  // The normalized subInitial value for this matched values filter.
  private ASN1OctetString normalizedSubInitial;
  private ByteString normalizedSubInitial;
  // The raw, unprocessed assertion value for this matched values filter.
  private ByteString rawAssertionValue;
  private final ByteString rawAssertionValue;
  // The subFinal value for this matched values filter.
  private ByteString subFinal;
  private final ByteString subFinal;
  // The subInitial value for this matched values filter.
  private ByteString subInitial;
  private final ByteString subInitial;
  // The processed attribute type for this matched values filter.
  private AttributeType attributeType;
@@ -155,16 +148,16 @@
  private boolean decoded;
  // The match type for this matched values filter.
  private byte matchType;
  private final byte matchType;
  // The equality matching rule for this matched values filter.
  private EqualityMatchingRule equalityMatchingRule;
  // The set of normalized subAny values for this matched values filter.
  private List<ASN1OctetString> normalizedSubAny;
  private List<ByteString> normalizedSubAny;
  // The set of subAny values for this matched values filter.
  private List<ByteString> subAny;
  private final List<ByteString> subAny;
  // The matching rule for this matched values filter.
  private MatchingRule matchingRule;
@@ -173,10 +166,10 @@
  private OrderingMatchingRule orderingMatchingRule;
  // The matching rule ID for this matched values filter.
  private String matchingRuleID;
  private final String matchingRuleID;
  // The raw, unprocessed attribute type for this matched values filter.
  private String rawAttributeType;
  private final String rawAttributeType;
  // The substring matching rule for this matched values filter.
  private SubstringMatchingRule substringMatchingRule;
@@ -256,8 +249,7 @@
  {
    Validator.ensureNotNull(attributeType, assertionValue);
    String rawAttributeType = attributeType.getNameOrOID();
    ASN1OctetString rawAssertionValue = assertionValue.getValue()
        .toASN1OctetString();
    ByteString rawAssertionValue = assertionValue.getValue();
    MatchedValuesFilter filter =
         new MatchedValuesFilter(EQUALITY_MATCH_TYPE, rawAttributeType,
@@ -357,8 +349,7 @@
    Validator.ensureNotNull(attributeType, assertionValue);
    String          rawAttributeType  = attributeType.getNameOrOID();
    ASN1OctetString rawAssertionValue =
         assertionValue.getValue().toASN1OctetString();
    ByteString rawAssertionValue = assertionValue.getValue();
    MatchedValuesFilter filter =
         new MatchedValuesFilter(GREATER_OR_EQUAL_TYPE, rawAttributeType,
@@ -405,8 +396,7 @@
    Validator.ensureNotNull(attributeType, assertionValue);
    String          rawAttributeType = attributeType.getNameOrOID();
    ASN1OctetString rawAssertionValue =
         assertionValue.getValue().toASN1OctetString();
    ByteString rawAssertionValue = assertionValue.getValue();
    MatchedValuesFilter filter =
         new MatchedValuesFilter(LESS_OR_EQUAL_TYPE, rawAttributeType,
@@ -492,8 +482,7 @@
  {
    Validator.ensureNotNull(attributeType,assertionValue);
    String          rawAttributeType  = attributeType.getNameOrOID();
    ASN1OctetString rawAssertionValue =
         assertionValue.getValue().toASN1OctetString();
    ByteString rawAssertionValue = assertionValue.getValue();
    MatchedValuesFilter filter =
         new MatchedValuesFilter(APPROXIMATE_MATCH_TYPE, rawAttributeType,
@@ -546,8 +535,7 @@
    Validator.ensureNotNull(attributeType, matchingRule, assertionValue);
    String rawAttributeType = attributeType.getNameOrOID();
    String matchingRuleID = matchingRule.getOID();
    ASN1OctetString rawAssertionValue =
         assertionValue.getValue().toASN1OctetString();
    ByteString rawAssertionValue = assertionValue.getValue();
    MatchedValuesFilter filter =
         new MatchedValuesFilter(EXTENSIBLE_MATCH_TYPE, rawAttributeType,
@@ -651,14 +639,13 @@
    }
  }
  /**
   * Encodes this matched values filter as an ASN.1 element.
   *
   * @return  The ASN.1 element containing the encoded matched values filter.
   * @param writer The ASN1Writer to use to encode this matched values filter.
   * @throws IOException if an error occurs while encoding.
   */
  public ASN1Element encode()
  public void encode(ASN1Writer writer) throws IOException
  {
    switch (matchType)
    {
@@ -667,89 +654,90 @@
      case LESS_OR_EQUAL_TYPE:
      case APPROXIMATE_MATCH_TYPE:
        // These will all be encoded in the same way.
        ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2);
        elements.add(new ASN1OctetString(rawAttributeType));
        elements.add(rawAssertionValue.toASN1OctetString());
        return new ASN1Sequence(matchType, elements);
        writer.writeStartSequence(matchType);
        writer.writeOctetString(rawAttributeType);
        writer.writeOctetString(rawAssertionValue);
        writer.writeEndSequence();
        return;
      case SUBSTRINGS_TYPE:
        ArrayList<ASN1Element> subElements = new ArrayList<ASN1Element>();
        writer.writeStartSequence(matchType);
        writer.writeOctetString(rawAttributeType);
        writer.writeStartSequence();
        if (subInitial != null)
        {
          ASN1OctetString subInitialOS = subInitial.toASN1OctetString();
          subInitialOS.setType(TYPE_SUBINITIAL);
          subElements.add(subInitialOS);
          writer.writeOctetString(TYPE_SUBINITIAL, subInitial);
        }
        if (subAny != null)
        {
          for (ByteString s : subAny)
          {
            ASN1OctetString os = s.toASN1OctetString();
            os.setType(TYPE_SUBANY);
            subElements.add(os);
            writer.writeOctetString(TYPE_SUBANY, s);
          }
        }
        if (subFinal != null)
        {
          ASN1OctetString subFinalOS = subFinal.toASN1OctetString();
          subFinalOS.setType(TYPE_SUBFINAL);
          subElements.add(subFinalOS);
          writer.writeOctetString(TYPE_SUBFINAL, subFinal);
        }
        writer.writeEndSequence();
        elements = new ArrayList<ASN1Element>(2);
        elements.add(new ASN1OctetString(rawAttributeType));
        elements.add(new ASN1Sequence(subElements));
        return new ASN1Sequence(matchType, elements);
        writer.writeEndSequence();
        return;
      case PRESENT_TYPE:
        return new ASN1OctetString(matchType, rawAttributeType);
        writer.writeOctetString(matchType, rawAttributeType);
        return;
      case EXTENSIBLE_MATCH_TYPE:
        elements = new ArrayList<ASN1Element>(3);
        writer.writeStartSequence(matchType);
        if (matchingRuleID != null)
        {
          elements.add(new ASN1OctetString(TYPE_MATCHING_RULE_ID,
                                           matchingRuleID));
          writer.writeOctetString(TYPE_MATCHING_RULE_ID, matchingRuleID);
        }
        if (rawAttributeType != null)
        {
          elements.add(new ASN1OctetString(TYPE_MATCHING_RULE_TYPE,
                                           rawAttributeType));
          writer.writeOctetString(TYPE_MATCHING_RULE_TYPE, rawAttributeType);
        }
        ASN1OctetString valueOS = rawAssertionValue.toASN1OctetString();
        valueOS.setType(TYPE_MATCHING_RULE_VALUE);
        elements.add(valueOS);
        return new ASN1Sequence(matchType, elements);
        writer.writeOctetString(TYPE_MATCHING_RULE_VALUE, rawAssertionValue);
        writer.writeEndSequence();
        return;
      default:
        return null;
    }
  }
  /**
    /**
   * Decodes the provided ASN.1 element as a matched values filter item.
   *
   * @param  element  The ASN.1 element to be decoded.
   * @param  reader The ASN.1 reader.
   *
   * @return  The decoded matched values filter.
   *
   * @throws  LDAPException  If a problem occurs while attempting to decode the
   *                         filter item.
   */
  public static MatchedValuesFilter decode(ASN1Element element)
  public static MatchedValuesFilter decode(ASN1Reader reader)
         throws LDAPException
  {
    switch (element.getType())
    byte type;
    try
    {
      type = reader.peekType();
    }
    catch(Exception e)
    {
      // TODO: Need a better message.
      Message message =
          ERR_MVFILTER_INVALID_ELEMENT_TYPE.get(e.toString());
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    switch (type)
    {
      case EQUALITY_MATCH_TYPE:
      case GREATER_OR_EQUAL_TYPE:
@@ -759,25 +747,12 @@
        // sequence consisting of the attribute type and assertion value.
        try
        {
          ArrayList<ASN1Element> elements =
               element.decodeAsSequence().elements();
          if (elements.size() != 2)
          {
            Message message =
                ERR_MVFILTER_INVALID_AVA_SEQUENCE_SIZE.get(elements.size());
            throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
          }
          String rawAttributeType =
                      elements.get(0).decodeAsOctetString().stringValue();
          return new MatchedValuesFilter(element.getType(), rawAttributeType,
                                         elements.get(1).decodeAsOctetString(),
                                         null, null, null, null);
        }
        catch (LDAPException le)
        {
          throw le;
          reader.readStartSequence();
          String rawAttributeType = reader.readOctetStringAsString();
          ByteString rawAssertionValue = reader.readOctetString();
          reader.readEndSequence();
          return new MatchedValuesFilter(type, rawAttributeType,
              rawAssertionValue, null, null, null, null);
        }
        catch (Exception e)
        {
@@ -798,37 +773,27 @@
        // sequence of substring types.
        try
        {
          ArrayList<ASN1Element> elements =
               element.decodeAsSequence().elements();
          if (elements.size() != 2)
          {
            Message message = ERR_MVFILTER_INVALID_SUBSTRING_SEQUENCE_SIZE.get(
                elements.size());
            throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
          }
          reader.readStartSequence();
          String rawAttributeType = reader.readOctetStringAsString();
          ArrayList<ASN1Element> subElements =
               elements.get(1).decodeAsSequence().elements();
          if (subElements.isEmpty())
          reader.readStartSequence();
          if(!reader.hasNextElement())
          {
            Message message = ERR_MVFILTER_NO_SUBSTRING_ELEMENTS.get();
            throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
          }
          String rawAttributeType =
                      elements.get(0).decodeAsOctetString().stringValue();
          ByteString subInitial        = null;
          ArrayList<ByteString> subAny = null;
          ByteString subFinal          = null;
          for (ASN1Element e : subElements)
          while(reader.hasNextElement())
          {
            switch (e.getType())
            switch(reader.peekType())
            {
              case TYPE_SUBINITIAL:
             case TYPE_SUBINITIAL:
                if (subInitial == null)
                {
                  subInitial = e.decodeAsOctetString();
                  subInitial = reader.readOctetString();
                }
                else
                {
@@ -844,13 +809,13 @@
                  subAny = new ArrayList<ByteString>();
                }
                subAny.add(e.decodeAsOctetString());
                subAny.add(reader.readOctetString());
                break;
              case TYPE_SUBFINAL:
                if (subFinal == null)
                {
                  subFinal = e.decodeAsOctetString();
                  subFinal = reader.readOctetString();
                }
                else
                {
@@ -862,12 +827,15 @@
              default:
                Message message = ERR_MVFILTER_INVALID_SUBSTRING_ELEMENT_TYPE.
                    get(byteToHex(e.getType()));
                    get(byteToHex(reader.peekType()));
                throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
            }
          }
          reader.readEndSequence();
          return new MatchedValuesFilter(element.getType(), rawAttributeType,
          reader.readEndSequence();
          return new MatchedValuesFilter(type, rawAttributeType,
                                         null, subInitial, subAny, subFinal,
                                         null);
        }
@@ -893,9 +861,9 @@
        // The element must be an ASN.1 octet string holding the attribute type.
        try
        {
          String rawAttributeType = element.decodeAsOctetString().stringValue();
          String rawAttributeType = reader.readOctetStringAsString();
          return new MatchedValuesFilter(element.getType(), rawAttributeType,
          return new MatchedValuesFilter(type, rawAttributeType,
                                         null, null, null, null, null);
        }
        catch (Exception e)
@@ -918,27 +886,19 @@
        // the first element(s).
        try
        {
          ArrayList<ASN1Element> elements =
               element.decodeAsSequence().elements();
          if ((elements.size() < 2) || (elements.size() > 3))
          {
            Message message = ERR_MVFILTER_INVALID_EXTENSIBLE_SEQUENCE_SIZE.get(
                elements.size());
            throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
          }
          reader.readStartSequence();
          String          rawAttributeType  = null;
          String          matchingRuleID    = null;
          ASN1OctetString rawAssertionValue = null;
          for (ASN1Element e : elements)
          ByteString rawAssertionValue = null;
          while(reader.hasNextElement())
          {
            switch (e.getType())
            switch (reader.peekType())
            {
              case TYPE_MATCHING_RULE_ID:
                if (matchingRuleID == null)
                {
                  matchingRuleID = e.decodeAsOctetString().stringValue();
                  matchingRuleID = reader.readOctetStringAsString();
                }
                else
                {
@@ -952,7 +912,7 @@
              case TYPE_MATCHING_RULE_TYPE:
                if (rawAttributeType == null)
                {
                  rawAttributeType = e.decodeAsOctetString().stringValue();
                  rawAttributeType = reader.readOctetStringAsString();
                }
                else
                {
@@ -965,7 +925,7 @@
              case TYPE_MATCHING_RULE_VALUE:
                if (rawAssertionValue == null)
                {
                  rawAssertionValue = e.decodeAsOctetString();
                  rawAssertionValue = reader.readOctetString();
                }
                else
                {
@@ -978,13 +938,13 @@
              default:
                Message message = ERR_MVFILTER_INVALID_EXTENSIBLE_ELEMENT_TYPE.
                    get(byteToHex(e.getType()));
                    get(byteToHex(reader.peekType()));
                throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
            }
          }
          reader.readEndSequence();
          return new MatchedValuesFilter(element.getType(), rawAttributeType,
          return new MatchedValuesFilter(type, rawAttributeType,
                                         rawAssertionValue, null, null, null,
                                         matchingRuleID);
        }
@@ -1008,7 +968,7 @@
      default:
        Message message =
            ERR_MVFILTER_INVALID_ELEMENT_TYPE.get(byteToHex(element.getType()));
            ERR_MVFILTER_INVALID_ELEMENT_TYPE.get(byteToHex(type));
        throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
  }
@@ -1040,28 +1000,6 @@
  }
  /**
   * Specifies the raw, unprocessed attribute type for this matched values
   * filter.
   *
   * @param  rawAttributeType  The raw, unprocessed attribute type for this
   *                           matched values filter.
   */
  public void setRawAttributeType(String rawAttributeType)
  {
    this.rawAttributeType = rawAttributeType;
    decoded                 = false;
    attributeType           = null;
    approximateMatchingRule = null;
    equalityMatchingRule    = null;
    orderingMatchingRule    = null;
    substringMatchingRule   = null;
  }
  /**
   * Retrieves the attribute type for this matched values filter.
   *
@@ -1088,34 +1026,6 @@
  }
  /**
   * Specifies the attribute type for this matched values filter.
   *
   * @param  attributeType  The attribute type for this matched values filter.
   */
  public void setAttributeType(AttributeType attributeType)
  {
    this.attributeType = attributeType;
    if (attributeType == null)
    {
      rawAttributeType = null;
    }
    else
    {
      rawAttributeType = attributeType.getNameOrOID();
    }
    decoded                 = false;
    approximateMatchingRule = null;
    equalityMatchingRule    = null;
    orderingMatchingRule    = null;
    substringMatchingRule   = null;
  }
  /**
   * Retrieves the raw, unprocessed assertion value for this matched values
   * filter.
@@ -1131,23 +1041,6 @@
  /**
   * Specifies the raw, unprocessed assertion value for this matched values
   * filter.
   *
   * @param  rawAssertionValue  The raw, unprocessed assertion value for this
   *                            matched values filter.
   */
  public void setRawAssertionValue(ByteString rawAssertionValue)
  {
    this.rawAssertionValue = rawAssertionValue;
    decoded        = false;
    assertionValue = null;
  }
  /**
   * Retrieves the assertion value for this matched values filter.
   *
   * @return  The assertion value for this matched values filter, or
@@ -1159,8 +1052,8 @@
    {
      if (rawAssertionValue != null)
      {
        assertionValue = new AttributeValue(getAttributeType(),
                                            rawAssertionValue);
        assertionValue = AttributeValues.create(
            getAttributeType(), rawAssertionValue);
      }
    }
@@ -1170,29 +1063,6 @@
  /**
   * Specifies the assertion value for this matched values filter.
   *
   * @param  assertionValue  The assertion value for this matched values filter.
   */
  public void setAssertionValue(AttributeValue assertionValue)
  {
    this.assertionValue = assertionValue;
    if (assertionValue == null)
    {
      rawAssertionValue = null;
    }
    else
    {
      rawAssertionValue = assertionValue.getValue().toASN1OctetString();
    }
    decoded = false;
  }
  /**
   * Retrieves the subInitial element for this matched values filter.
   *
   * @return  The subInitial element for this matched values filter, or
@@ -1205,18 +1075,7 @@
  /**
   * Specifies the subInitial element for this matched values filter.
   *
   * @param  subInitial  The subInitial element for this matched values filter.
   */
  public void setSubInitialElement(ByteString subInitial)
  {
    this.subInitial = subInitial;
    decoded              = false;
    normalizedSubInitial = null;
  }
@@ -1226,7 +1085,7 @@
   * @return  The normalized form of the subInitial element, or
   *          <CODE>null</CODE> if there is none.
   */
  public ASN1OctetString getNormalizedSubInitialElement()
  public ByteString getNormalizedSubInitialElement()
  {
    if (normalizedSubInitial == null)
    {
@@ -1235,8 +1094,7 @@
        try
        {
          normalizedSubInitial =
               getSubstringMatchingRule().normalizeSubstring(subInitial).
                    toASN1OctetString();
               getSubstringMatchingRule().normalizeSubstring(subInitial);
        }
        catch (Exception e)
        {
@@ -1268,21 +1126,6 @@
  /**
   * Specifies the set of subAny elements for this matched values filter.
   *
   * @param  subAny  The set of subAny elements for this matched values filter.
   */
  public void setSubAnyElements(List<ByteString> subAny)
  {
    this.subAny = subAny;
    decoded          = false;
    normalizedSubAny = null;
  }
  /**
   * Retrieves the set of normalized subAny elements for this matched values
   * filter.
   *
@@ -1291,13 +1134,13 @@
   *          problem occurs while attempting to perform the normalization, then
   *          <CODE>null</CODE> will be returned.
   */
  public List<ASN1OctetString> getNormalizedSubAnyElements()
  public List<ByteString> getNormalizedSubAnyElements()
  {
    if (normalizedSubAny == null)
    {
      if ((subAny == null) || (subAny.isEmpty()))
      {
        normalizedSubAny = new ArrayList<ASN1OctetString>(0);
        normalizedSubAny = new ArrayList<ByteString>(0);
      }
      else
      {
@@ -1306,14 +1149,13 @@
          return null;
        }
        normalizedSubAny = new ArrayList<ASN1OctetString>();
        normalizedSubAny = new ArrayList<ByteString>();
        try
        {
          for (ByteString s : subAny)
          {
            normalizedSubAny.add(
                 substringMatchingRule.normalizeSubstring(s).
                      toASN1OctetString());
                 substringMatchingRule.normalizeSubstring(s));
          }
        }
        catch (Exception e)
@@ -1347,27 +1189,12 @@
  /**
   * Specifies the subFinal element for this matched values filter.
   *
   * @param  subFinal  The subFinal element for this matched values filter.
   */
  public void setSubFinalElement(ByteString subFinal)
  {
    this.subFinal = subFinal;
    decoded            = false;
    normalizedSubFinal = null;
  }
  /**
   * Retrieves the normalized form of the subFinal element.
   *
   * @return  The normalized form of the subFinal element, or <CODE>null</CODE>
   *          if there is none.
   */
  public ASN1OctetString getNormalizedSubFinalElement()
  public ByteString getNormalizedSubFinalElement()
  {
    if (normalizedSubFinal == null)
    {
@@ -1376,8 +1203,7 @@
        try
        {
          normalizedSubFinal =
               getSubstringMatchingRule().normalizeSubstring(subFinal).
                    toASN1OctetString();
               getSubstringMatchingRule().normalizeSubstring(subFinal);
        }
        catch (Exception e)
        {
@@ -1408,22 +1234,6 @@
  /**
   * Specifies the matching rule ID for this matched values filter.
   *
   * @param  matchingRuleID  The matching rule ID for this matched values
   *                         filter.
   */
  public void setMatchingRuleID(String matchingRuleID)
  {
    this.matchingRuleID = matchingRuleID;
    decoded      = false;
    matchingRule = null;
  }
  /**
   * Retrieves the matching rule for this matched values filter.
   *
   * @return  The matching rule for this matched values filter, or
@@ -1446,29 +1256,6 @@
  /**
   * Specifies the matching rule for this matched values filter.
   *
   * @param  matchingRule  The matching rule for this matched values filter.
   */
  public void setMatchingRule(MatchingRule matchingRule)
  {
    this.matchingRule = matchingRule;
    if (matchingRule == null)
    {
      matchingRuleID = null;
    }
    else
    {
      matchingRuleID = matchingRule.getNameOrOID();
    }
    decoded = false;
  }
  /**
   * Retrieves the approximate matching rule that should be used for this
   * matched values filter.
   *
@@ -1635,8 +1422,8 @@
        {
          try
          {
            ArrayList<ByteString> normalizedSubAnyBS =
                 new ArrayList<ByteString>(normalizedSubAny);
            ArrayList<ByteSequence> normalizedSubAnyBS =
                 new ArrayList<ByteSequence>(normalizedSubAny);
            return substringMatchingRule.valueMatchesSubstring(
                 value.getNormalizedValue(), normalizedSubInitial,
@@ -1762,12 +1549,10 @@
          try
          {
            ASN1OctetString nv1 =
                 matchingRule.normalizeValue(value.getValue()).
                      toASN1OctetString();
            ASN1OctetString nv2 =
                 matchingRule.normalizeValue(assertionValue.getValue()).
                      toASN1OctetString();
            ByteString nv1 =
                 matchingRule.normalizeValue(value.getValue());
            ByteString nv2 =
                 matchingRule.normalizeValue(assertionValue.getValue());
            return (matchingRule.valuesMatch(nv1, nv2) == ConditionResult.TRUE);
          }
@@ -1819,6 +1604,7 @@
   *
   * @return  A string representation of this matched values filter.
   */
  @Override
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
opends/src/server/org/opends/server/controls/PagedResultsControl.java
@@ -29,19 +29,15 @@
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.protocols.ldap.LDAPResultCode.PROTOCOL_ERROR;
import static org.opends.server.util.ServerConstants.OID_PAGED_RESULTS_CONTROL;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Integer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.types.*;
import java.util.ArrayList;
import java.io.IOException;
/**
 * This class represents a paged results control value as defined in
@@ -61,6 +57,107 @@
public class PagedResultsControl extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<PagedResultsControl>
  {
    /**
     * {@inheritDoc}
     */
    public PagedResultsControl decode(boolean isCritical, ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        Message message = ERR_LDAP_PAGED_RESULTS_DECODE_NULL.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      try
      {
        reader.readStartSequence();
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message =
            ERR_LDAP_PAGED_RESULTS_DECODE_SEQUENCE.get(String.valueOf(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
      }
      int size;
      try
      {
        size = (int)reader.readInteger();
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message =
            ERR_LDAP_PAGED_RESULTS_DECODE_SIZE.get(String.valueOf(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
      }
      ByteString cookie;
      try
      {
        cookie = reader.readOctetString();
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message =
            ERR_LDAP_PAGED_RESULTS_DECODE_COOKIE.get(String.valueOf(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
      }
      try
      {
        reader.readEndSequence();
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message =
            ERR_LDAP_PAGED_RESULTS_DECODE_SEQUENCE.get(String.valueOf(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
      }
      return new PagedResultsControl(isCritical, size, cookie);
    }
    public String getOID()
    {
      return OID_PAGED_RESULTS_CONTROL;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final  ControlDecoder<PagedResultsControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -77,7 +174,7 @@
  /**
   * The control value cookie element.
   */
  private ASN1OctetString cookie;
  private ByteString cookie;
  /**
@@ -89,112 +186,36 @@
   * @param  cookie      The cookie element.
   */
  public PagedResultsControl(boolean isCritical, int size,
                             ASN1OctetString cookie)
                             ByteString cookie)
  {
    super(OID_PAGED_RESULTS_CONTROL, isCritical);
    this.size   = size;
    this.cookie = cookie;
    this.setValue(encode());
    if(cookie == null)
        this.cookie=ByteString.empty();
    else
        this.cookie = cookie;
  }
  /**
   * Creates a new paged results control by decoding the given information.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  isCritical  Indicates whether the control is considered
   *                     critical in processing the request.
   * @param  value       The value of the control.
   *
   * @throws  LDAPException  If a problem occurs while attempting to decode the
   *                         provided information as a paged results control.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public PagedResultsControl(boolean isCritical, ASN1OctetString value)
       throws LDAPException
  {
    super(OID_PAGED_RESULTS_CONTROL, isCritical, value);
  @Override
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    if (value == null)
    {
      Message message = ERR_LDAP_PAGED_RESULTS_DECODE_NULL.get();
      throw new LDAPException(PROTOCOL_ERROR, message);
    }
    writer.writeStartSequence();
    writer.writeInteger(size);
    writer.writeOctetString(cookie);
    writer.writeEndSequence();
    ArrayList<ASN1Element> elements;
    try
    {
      ASN1Element sequence = ASN1Element.decode(value.value());
      elements = sequence.decodeAsSequence().elements();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message =
          ERR_LDAP_PAGED_RESULTS_DECODE_SEQUENCE.get(String.valueOf(e));
      throw new LDAPException(PROTOCOL_ERROR, message, e);
    }
    int numElements = elements.size();
    if (numElements != 2)
    {
      Message message =
          ERR_LDAP_PAGED_RESULTS_DECODE_INVALID_ELEMENT_COUNT.get(numElements);
      throw new LDAPException(PROTOCOL_ERROR, message);
    }
    try
    {
      size = elements.get(0).decodeAsInteger().intValue();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message =
          ERR_LDAP_PAGED_RESULTS_DECODE_SIZE.get(String.valueOf(e));
      throw new LDAPException(PROTOCOL_ERROR, message, e);
    }
    try
    {
      cookie = elements.get(1).decodeAsOctetString();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message =
          ERR_LDAP_PAGED_RESULTS_DECODE_COOKIE.get(String.valueOf(e));
      throw new LDAPException(PROTOCOL_ERROR, message, e);
    }
  }
  /**
   * Encodes this control value to an ASN.1 element.
   *
   * @return  The ASN.1 element containing the encoded control value.
   */
  public ASN1OctetString encode()
  {
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2);
    elements.add(new ASN1Integer(size));
    elements.add(cookie);
    ASN1Sequence sequence = new ASN1Sequence(elements);
    return new ASN1OctetString(sequence.encode());
    writer.writeEndSequence();
  }
@@ -214,7 +235,7 @@
   * Get the control value cookie element.
   * @return The control value cookie element.
   */
  public ASN1OctetString getCookie()
  public ByteString getCookie()
  {
    return cookie;
  }
opends/src/server/org/opends/server/controls/PasswordExpiredControl.java
@@ -29,14 +29,16 @@
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.types.ByteString;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ResultCode;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import java.io.IOException;
/**
@@ -48,75 +50,77 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<PasswordExpiredControl>
  {
    /**
     * {@inheritDoc}
     */
    public PasswordExpiredControl decode(boolean isCritical, ByteString value)
        throws DirectoryException
    {
      if (value != null)
      {
        try
        {
          Integer.parseInt(value.toString());
        }
        catch (Exception e)
        {
          Message message = ERR_PWEXPIRED_CONTROL_INVALID_VALUE.get();
          throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
        }
      }
      return new PasswordExpiredControl(isCritical);
    }
    public String getOID()
    {
      return OID_NS_PASSWORD_EXPIRED;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<PasswordExpiredControl> DECODER =
    new Decoder();
  /**
   * Creates a new instance of the password expired control with the default
   * settings.
   */
  public PasswordExpiredControl()
  {
    super(OID_NS_PASSWORD_EXPIRED, false, new ASN1OctetString("0"));
    this(false);
  }
  /**
   * Creates a new instance of the password expired control with the provided
   * information.
   *
   * @param  oid         The OID to use for this control.
   * @param  isCritical  Indicates whether support for this control should be
   *                     considered a critical part of the client processing.
   */
  public PasswordExpiredControl(String oid, boolean isCritical)
  public PasswordExpiredControl(boolean isCritical)
  {
    super(oid, isCritical, new ASN1OctetString("0"));
    super(OID_NS_PASSWORD_EXPIRED, isCritical);
  }
  /**
   * Creates a new password expired control from the contents of the provided
   * control.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this password expired control.
   *
   * @return  The password expired control decoded from the provided control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         password expired control.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public static PasswordExpiredControl decodeControl(Control control)
         throws LDAPException
  {
    if (control.hasValue())
    {
      String valueStr = control.getValue().stringValue();
      try
      {
        Integer.parseInt(valueStr);
      }
      catch (Exception e)
      {
        Message message = ERR_PWEXPIRED_CONTROL_INVALID_VALUE.get();
        throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
      }
    }
    return new PasswordExpiredControl(control.getOID(), control.isCritical());
  }
  /**
   * Retrieves a string representation of this password expired control.
   *
   * @return  A string representation of this password expired control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  @Override
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeOctetString("0");
  }
@@ -127,6 +131,7 @@
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("PasswordExpiredControl()");
opends/src/server/org/opends/server/controls/PasswordExpiringControl.java
@@ -29,11 +29,8 @@
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.Control;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.types.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
@@ -41,6 +38,7 @@
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import java.io.IOException;
/**
@@ -53,6 +51,60 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<PasswordExpiringControl>
  {
    /**
     * {@inheritDoc}
     */
    public PasswordExpiringControl decode(boolean isCritical, ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        Message message = ERR_PWEXPIRING_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      int secondsUntilExpiration;
      try
      {
        secondsUntilExpiration =
            Integer.parseInt(value.toString());
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message = ERR_PWEXPIRING_CANNOT_DECODE_SECONDS_UNTIL_EXPIRATION.
            get(getExceptionMessage(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      return new PasswordExpiringControl(isCritical,
          secondsUntilExpiration);
    }
    public String getOID()
    {
      return OID_NS_PASSWORD_EXPIRING;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<PasswordExpiringControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -74,11 +126,7 @@
   */
  public PasswordExpiringControl(int secondsUntilExpiration)
  {
    super(OID_NS_PASSWORD_EXPIRING, false,
          new ASN1OctetString(String.valueOf(secondsUntilExpiration)));
    this.secondsUntilExpiration = secondsUntilExpiration;
    this(false, secondsUntilExpiration);
  }
@@ -87,93 +135,31 @@
   * Creates a new instance of the password expiring control with the provided
   * information.
   *
   * @param  oid                     The OID to use for this control.
   * @param  isCritical              Indicates whether support for this control
   *                                 should be considered a critical part of the
   *                                 client processing.
   * @param  secondsUntilExpiration  The length of time in seconds until the
   *                                 password actually expires.
   */
  public PasswordExpiringControl(String oid, boolean isCritical,
                                 int secondsUntilExpiration)
  public PasswordExpiringControl(boolean isCritical, int secondsUntilExpiration)
  {
    super(oid, isCritical,
          new ASN1OctetString(String.valueOf(secondsUntilExpiration)));
    super(OID_NS_PASSWORD_EXPIRING, isCritical);
    this.secondsUntilExpiration = secondsUntilExpiration;
  }
  /**
   * Creates a new instance of the password expiring control with the provided
   * information.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  oid                     The OID to use for this control.
   * @param  isCritical              Indicates whether support for this control
   *                                 should be considered a critical part of the
   *                                 client processing.
   * @param  secondsUntilExpiration  The length of time in seconds until the
   *                                 password actually expires.
   * @param  encodedValue            The pre-encoded value for this control.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  private PasswordExpiringControl(String oid, boolean isCritical,
                                  int secondsUntilExpiration,
                                  ASN1OctetString encodedValue)
  {
    super(oid, isCritical, encodedValue);
    this.secondsUntilExpiration = secondsUntilExpiration;
  }
  /**
   * Creates a new password expiring control from the contents of the provided
   * control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this password expiring control.
   *
   * @return  The password expiring control decoded from the provided control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         password expiring control.
   */
  public static PasswordExpiringControl decodeControl(Control control)
         throws LDAPException
  {
    if (! control.hasValue())
    {
      Message message = ERR_PWEXPIRING_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    int secondsUntilExpiration;
    try
    {
      secondsUntilExpiration =
           Integer.parseInt(control.getValue().stringValue());
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message = ERR_PWEXPIRING_CANNOT_DECODE_SECONDS_UNTIL_EXPIRATION.
          get(getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    return new PasswordExpiringControl(control.getOID(), control.isCritical(),
                                       secondsUntilExpiration,
                                       control.getValue());
  @Override
  public void writeValue(ASN1Writer writer) throws IOException {
    writer.writeOctetString(String.valueOf(secondsUntilExpiration));
  }
@@ -192,25 +178,12 @@
  /**
   * Retrieves a string representation of this password expiring control.
   *
   * @return  A string representation of this password expiring control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this password expiring control to the
   * provided buffer.
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("PasswordExpiringControl(secondsUntilExpiration=");
opends/src/server/org/opends/server/controls/PasswordPolicyRequestControl.java
@@ -29,13 +29,16 @@
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.types.ByteString;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ResultCode;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import java.io.IOException;
/**
@@ -45,8 +48,42 @@
public class PasswordPolicyRequestControl
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<PasswordPolicyRequestControl>
  {
    /**
     * {@inheritDoc}
     */
    public PasswordPolicyRequestControl decode(boolean isCritical,
                                               ByteString value)
        throws DirectoryException
    {
      if (value != null)
      {
        Message message = ERR_PWPOLICYREQ_CONTROL_HAS_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      return new PasswordPolicyRequestControl(isCritical);
    }
    public String getOID()
    {
      return OID_PASSWORD_POLICY_CONTROL;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<PasswordPolicyRequestControl> DECODER =
    new Decoder();
  /**
   * Creates a new instance of the password policy request control with the
@@ -54,7 +91,7 @@
   */
  public PasswordPolicyRequestControl()
  {
    super(OID_PASSWORD_POLICY_CONTROL, false);
    this(false);
  }
@@ -64,57 +101,27 @@
   * Creates a new instance of the password policy request control with the
   * provided information.
   *
   * @param  oid         The OID to use for this control.
   * @param  isCritical  Indicates whether support for this control should be
   *                     considered a critical part of the client processing.
   */
  public PasswordPolicyRequestControl(String oid, boolean isCritical)
  public PasswordPolicyRequestControl(boolean isCritical)
  {
    super(oid, isCritical);
    super(OID_PASSWORD_POLICY_CONTROL, isCritical);
  }
  /**
   * Creates a new password policy request control from the contents of the
   * provided control.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this password policy request control.
   *
   * @return  The password policy request control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         password policy request control.
   * @param writer The ASN.1 output stream to write to.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public static PasswordPolicyRequestControl decodeControl(Control control)
         throws LDAPException
  {
    if (control.hasValue())
    {
      Message message = ERR_PWPOLICYREQ_CONTROL_HAS_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    return new PasswordPolicyRequestControl(control.getOID(),
                                            control.isCritical());
  }
  /**
   * Retrieves a string representation of this password policy request control.
   *
   * @return  A string representation of this password policy request control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  @Override
  public void writeValue(ASN1Writer writer) throws IOException {
    // No value element.
  }
@@ -125,6 +132,7 @@
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("PasswordPolicyRequestControl()");
opends/src/server/org/opends/server/controls/PasswordPolicyResponseControl.java
@@ -29,21 +29,15 @@
import java.util.ArrayList;
import java.io.IOException;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Enumerated;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1Integer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -59,6 +53,112 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<PasswordPolicyResponseControl>
  {
    /**
     * {@inheritDoc}
     */
    public PasswordPolicyResponseControl decode(boolean isCritical,
                                                ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        // The response control must always have a value.
        Message message = ERR_PWPOLICYRES_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      try
      {
        PasswordPolicyWarningType warningType  = null;
        PasswordPolicyErrorType   errorType    = null;
        int                       warningValue = -1;
        reader.readStartSequence();
        while(reader.hasNextElement())
        {
          switch (reader.peekType())
          {
            case TYPE_WARNING_ELEMENT:
              // Its a CHOICE element. Read as sequence to retrieve
              // nested element.
              reader.readStartSequence();
              warningType =
                  PasswordPolicyWarningType.valueOf(reader.peekType());
              warningValue = (int)reader.readInteger();
              if (warningType == null)
              {
                Message message = ERR_PWPOLICYRES_INVALID_WARNING_TYPE.get(
                    byteToHex(reader.peekType()));
                throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
                    message);
              }
              reader.readEndSequence();
              break;
            case TYPE_ERROR_ELEMENT:
              int errorValue = (int)reader.readInteger();
              errorType = PasswordPolicyErrorType.valueOf(errorValue);
              if (errorType == null)
              {
                Message message =
                    ERR_PWPOLICYRES_INVALID_ERROR_TYPE.get(errorValue);
                throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
                    message);
              }
              break;
            default:
              Message message = ERR_PWPOLICYRES_INVALID_ELEMENT_TYPE.get(
                  byteToHex(reader.peekType()));
              throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
          }
        }
        reader.readEndSequence();
        return new PasswordPolicyResponseControl(isCritical,
            warningType, warningValue,
            errorType);
      }
      catch (DirectoryException de)
      {
        throw de;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message =
            ERR_PWPOLICYRES_DECODE_ERROR.get(getExceptionMessage(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
    }
    public String getOID()
    {
      return OID_ACCOUNT_USABLE_CONTROL;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<PasswordPolicyResponseControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -97,7 +197,7 @@
   */
  public PasswordPolicyResponseControl()
  {
    super(OID_PASSWORD_POLICY_CONTROL, false, encodeValue(null, -1, null));
    super(OID_PASSWORD_POLICY_CONTROL, false);
    warningType  = null;
@@ -125,13 +225,7 @@
                                       int warningValue,
                                       PasswordPolicyErrorType errorType)
  {
    super(OID_PASSWORD_POLICY_CONTROL, false,
          encodeValue(warningType, warningValue, errorType));
    this.warningType  = warningType;
    this.warningValue = warningValue;
    this.errorType    = errorType;
    this(false, warningType, warningValue, errorType);
  }
@@ -140,7 +234,6 @@
   * Creates a new instance of the password policy request control with the
   * provided information.
   *
   * @param  oid           The OID to use for this control.
   * @param  isCritical    Indicates whether support for this control should be
   *                       considered a critical part of the client processing.
   * @param  warningType   The warning type to use for this password policy
@@ -152,13 +245,12 @@
   *                       response control, or <CODE>null</CODE> if there
   *                       should not be an error flag.
   */
  public PasswordPolicyResponseControl(String oid, boolean isCritical,
  public PasswordPolicyResponseControl(boolean isCritical,
                                       PasswordPolicyWarningType warningType,
                                       int warningValue,
                                       PasswordPolicyErrorType errorType)
  {
    super(oid, isCritical, encodeValue(warningType, warningValue, errorType));
    super(OID_PASSWORD_POLICY_CONTROL, isCritical);
    this.warningType  = warningType;
    this.warningValue = warningValue;
@@ -168,182 +260,35 @@
  /**
   * Creates a new instance of the password policy request control with the
   * provided information.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  oid           The OID to use for this control.
   * @param  isCritical    Indicates whether support for this control should be
   *                       considered a critical part of the client processing.
   * @param  warningType   The warning type to use for this password policy
   *                       response control, or <CODE>null</CODE> if there
   *                       should not be a warning flag.
   * @param  warningValue  The warning value to use for this password policy
   *                       response control, if applicable.
   * @param  errorType     The error type to use for this password policy
   *                       response control, or <CODE>null</CODE> if there
   *                       should not be an error flag.
   * @param  encodedValue  The pre-encoded value to use for this control.
   * @param writer The ASN.1 writer to use.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  private PasswordPolicyResponseControl(String oid, boolean isCritical,
                                        PasswordPolicyWarningType warningType,
                                        int warningValue,
                                        PasswordPolicyErrorType errorType,
                                        ASN1OctetString encodedValue)
  {
    super(oid, isCritical, encodedValue);
  @Override
  protected void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    this.warningType  = warningType;
    this.warningValue = warningValue;
    this.errorType    = errorType;
  }
  /**
   * Encodes the provided information into an ASN.1 octet string suitable for
   * use as the value for this control.
   *
   * @param  warningType   The warning type to use for this password policy
   *                       response control, or <CODE>null</CODE> if there
   *                       should not be a warning flag.
   * @param  warningValue  The warning value to use for this password policy
   *                       response control, if applicable.
   * @param  errorType     The error type to use for this password policy
   *                       response control, or <CODE>null</CODE> if there
   *                       should not be an error flag.
   *
   * @return  An ASN.1 octet string containing the encoded control value.
   */
  private static ASN1OctetString encodeValue(
                                      PasswordPolicyWarningType warningType,
                                      int warningValue,
                                      PasswordPolicyErrorType errorType)
  {
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2);
    writer.writeStartSequence();
    if (warningType != null)
    {
      ASN1Integer warningInteger = new ASN1Integer(warningType.getType(),
                                                   warningValue);
      elements.add(new ASN1Element(TYPE_WARNING_ELEMENT,
                                   warningInteger.encode()));
      // Just write the CHOICE element as a single element SEQUENCE.
      writer.writeStartSequence(TYPE_WARNING_ELEMENT);
      writer.writeInteger(warningType.getType(), warningValue);
      writer.writeEndSequence();
    }
    if (errorType != null)
    {
      elements.add(new ASN1Enumerated(TYPE_ERROR_ELEMENT,
                                      errorType.intValue()));
      writer.writeInteger(TYPE_ERROR_ELEMENT, errorType.intValue());
    }
    writer.writeEndSequence();
    ASN1Sequence valueSequence = new ASN1Sequence(elements);
    return new ASN1OctetString(valueSequence.encode());
    writer.writeEndSequence();
  }
  /**
   * Creates a new password policy response control from the contents of the
   * provided control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this password policy response control.
   *
   * @return  The password policy response control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         password policy response control.
   */
  public static PasswordPolicyResponseControl decodeControl(Control control)
         throws LDAPException
  {
    ASN1OctetString controlValue = control.getValue();
    if (controlValue == null)
    {
      // The response control must always have a value.
      Message message = ERR_PWPOLICYRES_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    try
    {
      PasswordPolicyWarningType warningType  = null;
      PasswordPolicyErrorType   errorType    = null;
      int                       warningValue = -1;
      ASN1Sequence valueSequence =
           ASN1Sequence.decodeAsSequence(controlValue.value());
      for (ASN1Element e : valueSequence.elements())
      {
        switch (e.getType())
        {
          case TYPE_WARNING_ELEMENT:
            ASN1Integer integerElement = ASN1Integer.decodeAsInteger(e.value());
            warningValue = integerElement.intValue();
            warningType =
                 PasswordPolicyWarningType.valueOf(integerElement.getType());
            if (warningType == null)
            {
              Message message = ERR_PWPOLICYRES_INVALID_WARNING_TYPE.get(
                  byteToHex(integerElement.getType()));
              throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
            }
            break;
          case TYPE_ERROR_ELEMENT:
            int errorValue = e.decodeAsEnumerated().intValue();
            errorType = PasswordPolicyErrorType.valueOf(errorValue);
            if (errorType == null)
            {
              Message message =
                  ERR_PWPOLICYRES_INVALID_ERROR_TYPE.get(errorValue);
              throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
            }
            break;
          default:
            Message message = ERR_PWPOLICYRES_INVALID_ELEMENT_TYPE.get(
                byteToHex(e.getType()));
            throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
        }
      }
      return new PasswordPolicyResponseControl(control.getOID(),
                                               control.isCritical(),
                                               warningType, warningValue,
                                               errorType, controlValue);
    }
    catch (LDAPException le)
    {
      throw le;
    }
    catch (ASN1Exception ae)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ae);
      }
      Message message = ERR_PWPOLICYRES_DECODE_ERROR.get(ae.getMessage());
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message =
          ERR_PWPOLICYRES_DECODE_ERROR.get(getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
  }
  /**
   * Retrieves the password policy warning type contained in this control.
   *
@@ -384,25 +329,12 @@
  /**
   * Retrieves a string representation of this password policy response control.
   *
   * @return  A string representation of this password policy response control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this password policy response control to
   * the provided buffer.
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("PasswordPolicyResponseControl(");
opends/src/server/org/opends/server/controls/PersistentSearchControl.java
@@ -28,22 +28,16 @@
import org.opends.messages.Message;
import java.util.ArrayList;
import java.util.Set;
import java.io.IOException;
import org.opends.server.protocols.asn1.ASN1Boolean;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Integer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -59,6 +53,74 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<PersistentSearchControl>
  {
    /**
     * {@inheritDoc}
     */
    public PersistentSearchControl decode(boolean isCritical, ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        Message message = ERR_PSEARCH_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      boolean                         changesOnly;
      boolean                         returnECs;
      Set<PersistentSearchChangeType> changeTypes;
      try
      {
        reader.readStartSequence();
        int changeTypesValue = (int)reader.readInteger();
        changeTypes = PersistentSearchChangeType.intToTypes(changeTypesValue);
        changesOnly = reader.readBoolean();
        returnECs   = reader.readBoolean();
        reader.readEndSequence();
      }
      catch (LDAPException le)
      {
        throw new DirectoryException(ResultCode.valueOf(le.getResultCode()), le
            .getMessageObject());
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message =
            ERR_PSEARCH_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
      }
      return new PersistentSearchControl(isCritical,
          changeTypes, changesOnly, returnECs);
    }
    public String getOID()
    {
      return OID_PERSISTENT_SEARCH;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<PersistentSearchControl> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -94,13 +156,7 @@
  public PersistentSearchControl(Set<PersistentSearchChangeType> changeTypes,
                                 boolean changesOnly, boolean returnECs)
  {
    super(OID_PERSISTENT_SEARCH, true,
          encodeValue(changeTypes, changesOnly, returnECs));
    this.changeTypes = changeTypes;
    this.changesOnly = changesOnly;
    this.returnECs   = returnECs;
    this(true, changeTypes, changesOnly, returnECs);
  }
@@ -108,7 +164,6 @@
  /**
   * Creates a new persistent search control with the provided information.
   *
   * @param  oid          The OID to use for the control.
   * @param  isCritical   Indicates whether the control should be considered
   *                      critical for the operation processing.
   * @param  changeTypes  The set of change types for which to provide
@@ -120,11 +175,11 @@
   *                      notification control in updated entries that match the
   *                      associated search criteria.
   */
  public PersistentSearchControl(String oid, boolean isCritical,
  public PersistentSearchControl(boolean isCritical,
                                 Set<PersistentSearchChangeType> changeTypes,
                                 boolean changesOnly, boolean returnECs)
  {
    super(oid, isCritical, encodeValue(changeTypes, changesOnly, returnECs));
    super(OID_PERSISTENT_SEARCH, isCritical);
    this.changeTypes = changeTypes;
@@ -135,130 +190,24 @@
  /**
   * Creates a new persistent search control with the provided information.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  oid           The OID to use for the control.
   * @param  isCritical    Indicates whether the control should be considered
   *                       critical for the operation processing.
   * @param  changeTypes   The set of change types for which to provide
   *                       notification to the client.
   * @param  changesOnly   Indicates whether to only return changes that match
   *                       the associated search criteria, or to also return all
   *                       existing entries that match the filter.
   * @param  returnECs     Indicates whether to include the entry change
   *                       notification control in updated entries that match
   *                       the associated search criteria.
   * @param  encodedValue  The pre-encoded value for the control.
   * @param writer The ASN.1 writer to use.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  private PersistentSearchControl(String oid, boolean isCritical,
                                  Set<PersistentSearchChangeType> changeTypes,
                                  boolean changesOnly, boolean returnECs,
                                  ASN1OctetString encodedValue)
  {
    super(oid, isCritical, encodedValue);
  @Override
  protected void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    writer.writeStartSequence();
    writer.writeInteger(
        PersistentSearchChangeType.changeTypesToInt(changeTypes));
    writer.writeBoolean(changesOnly);
    writer.writeBoolean(returnECs);
    writer.writeEndSequence();
    this.changeTypes = changeTypes;
    this.changesOnly = changesOnly;
    this.returnECs   = returnECs;
  }
  /**
   * Encodes the provided information into an ASN.1 octet string suitable for
   * use as the control value.
   *
   * @param  changeTypes  The set of change types for which to provide
   *                      notification to the client.
   * @param  changesOnly  Indicates whether to only return changes that match
   *                      the associated search criteria, or to also return all
   *                      existing entries that match the filter.
   * @param  returnECs    Indicates whether to include the entry change
   *                      notification control in updated entries that match the
   *                      associated search criteria.
   *
   * @return  An ASN.1 octet string containing the encoded information.
   */
  private static ASN1OctetString encodeValue(Set<PersistentSearchChangeType>
                                                  changeTypes,
                                             boolean changesOnly,
                                             boolean returnECs)
  {
    ArrayList<ASN1Element> elements =
         new ArrayList<ASN1Element>(3);
    elements.add(new ASN1Integer(
         PersistentSearchChangeType.changeTypesToInt(changeTypes)));
    elements.add(new ASN1Boolean(changesOnly));
    elements.add(new ASN1Boolean(returnECs));
    return new ASN1OctetString(new ASN1Sequence(elements).encode());
  }
  /**
   * Creates a new persistent search control from the contents of the provided
   * control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this persistent search control.
   *
   * @return  The persistent search control decoded from the provided control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         persistent search control.
   */
  public static PersistentSearchControl decodeControl(Control control)
         throws LDAPException
  {
    if (! control.hasValue())
    {
      Message message = ERR_PSEARCH_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    boolean                         changesOnly;
    boolean                         returnECs;
    Set<PersistentSearchChangeType> changeTypes;
    try
    {
      ArrayList<ASN1Element> elements =
           ASN1Sequence.decodeAsSequence(control.getValue().value()).elements();
      if (elements.size() != 3)
      {
        Message message =
            ERR_PSEARCH_INVALID_ELEMENT_COUNT.get(elements.size());
        throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
      }
      int changeTypesValue = elements.get(0).decodeAsInteger().intValue();
      changeTypes = PersistentSearchChangeType.intToTypes(changeTypesValue);
      changesOnly = elements.get(1).decodeAsBoolean().booleanValue();
      returnECs   = elements.get(2).decodeAsBoolean().booleanValue();
    }
    catch (LDAPException le)
    {
      throw le;
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message =
          ERR_PSEARCH_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, e);
    }
    return new PersistentSearchControl(control.getOID(), control.isCritical(),
                                       changeTypes, changesOnly, returnECs,
                                       control.getValue());
    writer.writeEndSequence();
  }
@@ -276,21 +225,6 @@
  /**
   * Specifies the set of change types for this persistent search control.
   *
   * @param  changeTypes  The set of change types for this persistent search
   *                      control.
   */
  public void setChangeTypes(Set<PersistentSearchChangeType> changeTypes)
  {
    this.changeTypes = changeTypes;
    setValue(encodeValue(changeTypes, changesOnly, returnECs));
  }
  /**
   * Indicates whether to only return changes that match the associated search
   * criteria, or to also return all existing entries that match the filter.
   *
@@ -306,23 +240,6 @@
  /**
   * Specifies whether to only return changes that match teh associated search
   * criteria, or to also return all existing entries that match the filter.
   *
   * @param  changesOnly  Indicates whether to only return changes that match
   *                      the associated search criteria, or to also return all
   *                      existing entries that match the filter.
   */
  public void setChangesOnly(boolean changesOnly)
  {
    this.changesOnly = changesOnly;
    setValue(encodeValue(changeTypes, changesOnly, returnECs));
  }
  /**
   * Indicates whether to include the entry change notification control in
   * entries returned to the client as the result of a change in the Directory
   * Server data.
@@ -338,43 +255,12 @@
  /**
   * Specifies whether to include the entry change notification control in
   * entries returned to the client as a result of a change in the Directory
   * Server data.
   *
   * @param  returnECs  Indicates whether to include the entry change
   *                    notification control in updated entries that match the
   *                    associated search criteria.
   */
  public void setReturnECs(boolean returnECs)
  {
    this.returnECs = returnECs;
    setValue(encodeValue(changeTypes, changesOnly, returnECs));
  }
  /**
   * Retrieves a string representation of this persistent search control.
   *
   * @return  A string representation of this persistent search control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this persistent search control to the
   * provided buffer.
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("PersistentSearchControl(changeTypes=\"");
opends/src/server/org/opends/server/controls/ProxiedAuthV1Control.java
@@ -28,31 +28,21 @@
import org.opends.messages.Message;
import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.io.IOException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PasswordPolicyState;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.Control;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDAPException;
import org.opends.server.types.LockManager;
import org.opends.server.types.ResultCode;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.util.Validator.*;
@@ -69,6 +59,66 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<ProxiedAuthV1Control>
  {
    /**
     * {@inheritDoc}
     */
    public ProxiedAuthV1Control decode(boolean isCritical, ByteString value)
        throws DirectoryException
    {
      if (!isCritical)
      {
        Message message = ERR_PROXYAUTH1_CONTROL_NOT_CRITICAL.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      if (value == null)
      {
        Message message = ERR_PROXYAUTH1_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      DN authorizationDN;
      try
      {
        reader.readStartSequence();
        authorizationDN = DN.decode(reader.readOctetString());
        reader.readEndSequence();
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message =
            ERR_PROXYAUTH1_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
      }
      return new ProxiedAuthV1Control(isCritical, authorizationDN);
    }
    public String getOID()
    {
      return OID_PROXIED_AUTH_V1;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<ProxiedAuthV1Control> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -77,7 +127,7 @@
  // The raw, unprocessed authorization DN from the control value.
  private ASN1OctetString rawAuthorizationDN;
  private ByteString rawAuthorizationDN;
  // The processed authorization DN from the control value.
  private DN authorizationDN;
@@ -91,14 +141,9 @@
   * @param  rawAuthorizationDN  The raw, unprocessed authorization DN from the
   *                             control value.  It must not be {@code null}.
   */
  public ProxiedAuthV1Control(ASN1OctetString rawAuthorizationDN)
  public ProxiedAuthV1Control(ByteString rawAuthorizationDN)
  {
    super(OID_PROXIED_AUTH_V1, true, encodeValue(rawAuthorizationDN));
    this.rawAuthorizationDN = rawAuthorizationDN;
    authorizationDN = null;
    this(true, rawAuthorizationDN);
  }
@@ -112,13 +157,7 @@
   */
  public ProxiedAuthV1Control(DN authorizationDN)
  {
    super(OID_PROXIED_AUTH_V1, true,
          encodeValue(new ASN1OctetString(authorizationDN.toString())));
    this.authorizationDN = authorizationDN;
    rawAuthorizationDN = new ASN1OctetString(authorizationDN.toString());
    this(true, authorizationDN);
  }
@@ -127,19 +166,15 @@
   * Creates a new instance of the proxied authorization v1 control with the
   * provided information.
   *
   * @param  oid                 The OID to use for this control.
   * @param  isCritical          Indicates whether support for this control
   *                             should be considered a critical part of the
   *                             server processing.
   * @param  controlValue        The encoded value for this control.
   * @param  rawAuthorizationDN  The raw, unprocessed authorization DN from the
   *                             control value.
   */
  private ProxiedAuthV1Control(String oid, boolean isCritical,
                             ASN1OctetString controlValue,
                             ASN1OctetString rawAuthorizationDN)
  public ProxiedAuthV1Control(boolean isCritical, ByteString rawAuthorizationDN)
  {
    super(oid, isCritical, controlValue);
    super(OID_PROXIED_AUTH_V1, isCritical);
    this.rawAuthorizationDN = rawAuthorizationDN;
@@ -150,91 +185,43 @@
  /**
   * Generates an encoded value for this control containing the provided raw
   * authorization DN.
   * Creates a new instance of the proxied authorization v1 control with the
   * provided information.
   *
   * @param  rawAuthorizationDN  The raw, unprocessed authorization DN to use in
   *                             the control value.  It must not be
   *                             {@code null}.
   *
   * @return  The encoded control value.
   * @param  isCritical          Indicates whether support for this control
   *                             should be considered a critical part of the
   *                             server processing.
   * @param  authorizationDN     The authorization DN from the control value.
   *                             It must not be {@code null}.
   */
  private static ASN1OctetString encodeValue(ASN1OctetString rawAuthorizationDN)
  public ProxiedAuthV1Control(boolean isCritical, DN authorizationDN)
  {
    ensureNotNull(rawAuthorizationDN);
    super(OID_PROXIED_AUTH_V1, isCritical);
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(1);
    elements.add(rawAuthorizationDN);
    return new ASN1OctetString(new ASN1Sequence(elements).encode());
    this.authorizationDN = authorizationDN;
    rawAuthorizationDN = ByteString.valueOf(authorizationDN.toString());
  }
  /**
   * Creates a new proxied authorization v1 control from the contents of the
   * provided control.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this proxied authorization v1 control.  It must not
   *                  be {@code null}.
   *
   * @return  The proxied authorization v1 control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         proxied authorization v1 control.
   * @param writer The ASN.1 writer to use.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public static ProxiedAuthV1Control decodeControl(Control control)
         throws LDAPException
  {
    ensureNotNull(control);
  @Override
  protected void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    if (! control.isCritical())
    {
      Message message = ERR_PROXYAUTH1_CONTROL_NOT_CRITICAL.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    writer.writeStartSequence();
    writer.writeOctetString(rawAuthorizationDN);
    writer.writeEndSequence();
    if (! control.hasValue())
    {
      Message message = ERR_PROXYAUTH1_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    ASN1OctetString rawAuthorizationDN;
    try
    {
      ArrayList<ASN1Element> elements =
           ASN1Sequence.decodeAsSequence(control.getValue().value()).elements();
      if (elements.size() != 1)
      {
        Message message =
            ERR_PROXYAUTH1_INVALID_ELEMENT_COUNT.get(elements.size());
        throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
      }
      rawAuthorizationDN = elements.get(0).decodeAsOctetString();
    }
    catch (LDAPException le)
    {
      throw le;
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message =
          ERR_PROXYAUTH1_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, e);
    }
    return new ProxiedAuthV1Control(control.getOID(), control.isCritical(),
                                    control.getValue(), rawAuthorizationDN);
    writer.writeEndSequence();
  }
@@ -244,7 +231,7 @@
   *
   * @return  The raw, unprocessed authorization DN from the control value.
   */
  public ASN1OctetString getRawAuthorizationDN()
  public ByteString getRawAuthorizationDN()
  {
    return rawAuthorizationDN;
  }
@@ -252,23 +239,6 @@
  /**
   * Specifies the raw, unprocessed authorization DN for this proxied auth
   * control.
   *
   * @param  rawAuthorizationDN  The raw, unprocessed authorization DN for this
   *                             proxied auth control.
   */
  public void setRawAuthorizationDN(ASN1OctetString rawAuthorizationDN)
  {
    this.rawAuthorizationDN = rawAuthorizationDN;
    setValue(encodeValue(rawAuthorizationDN));
    authorizationDN = null;
  }
  /**
   * Retrieves the authorization DN from the control value.
   *
   * @return  The authorization DN from the control value.
@@ -290,24 +260,6 @@
  /**
   * Specifies the authorization DN for this proxied auth control.
   *
   * @param  authorizationDN  The authorizationDN for this proxied auth control.
   *                          It must not be {@code null}.
   */
  public void setAuthorizationDN(DN authorizationDN)
  {
    ensureNotNull(authorizationDN);
    this.authorizationDN = authorizationDN;
    rawAuthorizationDN = new ASN1OctetString(authorizationDN.toString());
    setValue(encodeValue(rawAuthorizationDN));
  }
  /**
   * Retrieves the authorization entry for this proxied authorization V1
   * control.  It will also perform any necessary password policy checks to
   * ensure that the associated user account is suitable for use in performing
@@ -396,29 +348,16 @@
  /**
   * Retrieves a string representation of this proxied auth v1 control.
   *
   * @return  A string representation of this proxied auth v1 control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this proxied auth v1 control to the
   * provided buffer.
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("ProxiedAuthorizationV1Control(authorizationDN=\"");
    rawAuthorizationDN.toString(buffer);
    buffer.append(rawAuthorizationDN);
    buffer.append("\")");
  }
}
opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java
@@ -30,29 +30,20 @@
import java.util.concurrent.locks.Lock;
import java.io.IOException;
import org.opends.server.api.IdentityMapper;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PasswordPolicyState;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.Control;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDAPException;
import org.opends.server.types.LockManager;
import org.opends.server.types.ResultCode;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.util.Validator.*;
import static org.opends.server.util.Validator.ensureNotNull;
/**
@@ -67,6 +58,74 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private static final class Decoder
      implements ControlDecoder<ProxiedAuthV2Control>
  {
    /**
     * {@inheritDoc}
     */
    public ProxiedAuthV2Control decode(boolean isCritical, ByteString value)
        throws DirectoryException
    {
      if (!isCritical)
      {
        Message message = ERR_PROXYAUTH2_CONTROL_NOT_CRITICAL.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      if (value == null)
      {
        Message message = ERR_PROXYAUTH2_NO_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      ByteString authorizationID;
      try
      {
        // Try the legacy encoding where the value is wrapped by an
        // extra octet string
        authorizationID = reader.readOctetString();
      }
      catch (Exception e)
      {
        // Try just getting the value.
        authorizationID = value;
        String lowerAuthZIDStr = toLowerCase(authorizationID.toString());
        if (!lowerAuthZIDStr.startsWith("dn:") &&
            !lowerAuthZIDStr.startsWith("u:"))
        {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, e);
          }
          Message message =
              ERR_PROXYAUTH2_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
          throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message,
              e);
        }
      }
      return new ProxiedAuthV2Control(isCritical, authorizationID);
    }
    public String getOID()
    {
      return OID_PROXIED_AUTH_V2;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<ProxiedAuthV2Control> DECODER =
    new Decoder();
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -75,7 +134,7 @@
  // The authorization ID from the control value.
  private ASN1OctetString authorizationID;
  private ByteString authorizationID;
@@ -85,13 +144,9 @@
   *
   * @param  authorizationID  The authorization ID from the control value.
   */
  public ProxiedAuthV2Control(ASN1OctetString authorizationID)
  public ProxiedAuthV2Control(ByteString authorizationID)
  {
    super(OID_PROXIED_AUTH_V2, true, authorizationID);
    ensureNotNull(authorizationID);
    this.authorizationID = authorizationID;
    this(true, authorizationID);
  }
@@ -100,17 +155,16 @@
   * Creates a new instance of the proxied authorization v2 control with the
   * provided information.
   *
   * @param  oid              The OID to use for this control.
   * @param  isCritical       Indicates whether support for this control
   *                          should be considered a critical part of the
   *                          server processing.
   * @param  authorizationID  The authorization ID from the control value.
   */
  private ProxiedAuthV2Control(String oid, boolean isCritical,
                             ASN1OctetString authorizationID)
  public ProxiedAuthV2Control(boolean isCritical, ByteString authorizationID)
  {
    super(oid, isCritical, authorizationID);
    super(OID_PROXIED_AUTH_V2, isCritical);
    ensureNotNull(authorizationID);
    this.authorizationID = authorizationID;
  }
@@ -118,76 +172,15 @@
  /**
   * Creates a new proxied authorization v2 control from the contents of the
   * provided control.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this proxied authorization v2 control.  It must not
   *                  be {@code null}.
   *
   * @return  The proxied authorization v2 control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         proxied authorization v2 control.
   * @param writer The ASN.1 writer to use.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  public static ProxiedAuthV2Control decodeControl(Control control)
         throws LDAPException
  {
    ensureNotNull(control);
    if (! control.isCritical())
    {
      Message message = ERR_PROXYAUTH2_CONTROL_NOT_CRITICAL.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    if (! control.hasValue())
    {
      Message message = ERR_PROXYAUTH2_NO_CONTROL_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    ASN1OctetString authorizationID;
    try
    {
      authorizationID =
           ASN1OctetString.decodeAsOctetString(control.getValue().value());
    }
    catch (ASN1Exception ae)
    {
      String lowerAuthZIDStr = toLowerCase(control.getValue().stringValue());
      if (lowerAuthZIDStr.startsWith("dn:") || lowerAuthZIDStr.startsWith("u:"))
      {
        authorizationID = control.getValue();
      }
      else
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ae);
        }
        Message message =
            ERR_PROXYAUTH2_CANNOT_DECODE_VALUE.get(getExceptionMessage(ae));
        throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message,
                                ae);
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message =
          ERR_PROXYAUTH2_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, e);
    }
    return new ProxiedAuthV2Control(control.getOID(), control.isCritical(),
                                    authorizationID);
  @Override
  protected void writeValue(ASN1Writer writer) throws IOException {
    writer.writeOctetString(authorizationID);
  }
@@ -197,7 +190,7 @@
   *
   * @return  The authorization ID for this proxied authorization V2 control.
   */
  public ASN1OctetString getAuthorizationID()
  public ByteString getAuthorizationID()
  {
    return authorizationID;
  }
@@ -205,28 +198,6 @@
  /**
   * Specifies the authorization ID for this proxied authorization V2 control.
   *
   * @param  authorizationID  The authorization ID for this proxied
   *                          authorization V2 control.
   */
  public void setAuthorizationID(ASN1OctetString authorizationID)
  {
    if (authorizationID == null)
    {
      this.authorizationID = new ASN1OctetString();
      setValue(this.authorizationID);
    }
    else
    {
      this.authorizationID = authorizationID;
      setValue(authorizationID);
    }
  }
  /**
   * Retrieves the authorization entry for this proxied authorization V2
   * control.  It will also perform any necessary password policy checks to
   * ensure that the associated user account is suitable for use in performing
@@ -244,7 +215,7 @@
         throws DirectoryException
  {
    // Check for a zero-length value, which would be for an anonymous user.
    if (authorizationID.value().length == 0)
    if (authorizationID.length() == 0)
    {
      return null;
    }
@@ -252,13 +223,12 @@
    // Get a lowercase string representation.  It must start with either "dn:"
    // or "u:".
    String authzID = authorizationID.stringValue();
    String lowerAuthzID = toLowerCase(authzID);
    String lowerAuthzID = toLowerCase(authorizationID.toString());
    if (lowerAuthzID.startsWith("dn:"))
    {
      // It's a DN, so decode it and see if it exists.  If it's the null DN,
      // then just assume that it does.
      DN authzDN = DN.decode(authzID.substring(3));
      DN authzDN = DN.decode(lowerAuthzID.substring(3));
      if (authzDN.isNullDN())
      {
        return null;
@@ -297,7 +267,7 @@
          if (userEntry == null)
          {
            // The requested user does not exist.
            Message message = ERR_PROXYAUTH2_NO_SUCH_USER.get(authzID);
            Message message = ERR_PROXYAUTH2_NO_SUCH_USER.get(lowerAuthzID);
            throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
                                         message);
          }
@@ -339,7 +309,7 @@
      // Use the proxied authorization identity mapper to resolve the username
      // to an entry.
      IdentityMapper proxyMapper =
      IdentityMapper<?> proxyMapper =
           DirectoryServer.getProxiedAuthorizationIdentityMapper();
      if (proxyMapper == null)
      {
@@ -347,10 +317,10 @@
        throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, message);
      }
      Entry userEntry = proxyMapper.getEntryForID(authzID.substring(2));
      Entry userEntry = proxyMapper.getEntryForID(lowerAuthzID.substring(2));
      if (userEntry == null)
      {
        Message message = ERR_PROXYAUTH2_NO_SUCH_USER.get(authzID);
        Message message = ERR_PROXYAUTH2_NO_SUCH_USER.get(lowerAuthzID);
        throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, message);
      }
      else
@@ -376,7 +346,7 @@
    }
    else
    {
      Message message = ERR_PROXYAUTH2_INVALID_AUTHZID.get(authzID);
      Message message = ERR_PROXYAUTH2_INVALID_AUTHZID.get(lowerAuthzID);
      throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
    }
  }
@@ -384,29 +354,16 @@
  /**
   * Retrieves a string representation of this proxied auth v2 control.
   *
   * @return  A string representation of this proxied auth v2 control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this proxied auth v2 control to the
   * provided buffer.
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("ProxiedAuthorizationV2Control(authzID=\"");
    authorizationID.toString(buffer);
    buffer.append(authorizationID);
    buffer.append("\")");
  }
}
opends/src/server/org/opends/server/controls/ServerSideSortRequestControl.java
@@ -31,19 +31,15 @@
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.io.IOException;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1Boolean;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.AttributeType;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.opends.server.types.SortKey;
import org.opends.server.types.SortOrder;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
@@ -53,7 +49,10 @@
/**
 * This class implements the server-side sort request control as defined in RFC
 * 2891 section 1.1.  The ASN.1 description for the control value is:
 * 2891 section 1.1. The subclass ServerSideSortRequestControl.ClientRequest
 * should be used when encoding this control from a sort order string. This is
 * suitable for client tools that want to encode this control without a
 * SortOrder object. The ASN.1 description for the control value is:
 * <BR><BR>
 * <PRE>
 * SortKeyList ::= SEQUENCE OF SEQUENCE {
@@ -63,7 +62,7 @@
 * </PRE>
 */
public class ServerSideSortRequestControl
       extends Control
    extends Control
{
  /**
   * The BER type to use when encoding the orderingRule element.
@@ -78,140 +77,165 @@
  private static final byte TYPE_REVERSE_ORDER = (byte) 0x81;
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<ServerSideSortRequestControl>
  {
    /**
     * {@inheritDoc}
     */
    public ServerSideSortRequestControl decode(boolean isCritical,
                                               ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        Message message = INFO_SORTREQ_CONTROL_NO_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      try
      {
        reader.readStartSequence();
        if (!reader.hasNextElement())
        {
          Message message = INFO_SORTREQ_CONTROL_NO_SORT_KEYS.get();
          throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
        }
        ArrayList<SortKey> sortKeys = new ArrayList<SortKey>();
        while(reader.hasNextElement())
        {
          reader.readStartSequence();
          String attrName = toLowerCase(reader.readOctetStringAsString());
          AttributeType attrType =
              DirectoryServer.getAttributeType(attrName, false);
          if (attrType == null)
          {
            Message message = INFO_SORTREQ_CONTROL_UNDEFINED_ATTR.get(attrName);
            throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
          }
          OrderingMatchingRule orderingRule = null;
          boolean ascending = true;
          while(reader.hasNextElement())
          {
            switch (reader.peekType())
            {
              case TYPE_ORDERING_RULE_ID:
                String orderingRuleID =
                               toLowerCase(reader.readOctetStringAsString());
                orderingRule =
                    DirectoryServer.getOrderingMatchingRule(orderingRuleID);
                if (orderingRule == null)
                {
                  Message message =
                      INFO_SORTREQ_CONTROL_UNDEFINED_ORDERING_RULE.
                          get(orderingRuleID);
                  throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
                      message);
                }
                break;
              case TYPE_REVERSE_ORDER:
                ascending = ! reader.readBoolean();
                break;
              default:
                Message message = INFO_SORTREQ_CONTROL_INVALID_SEQ_ELEMENT_TYPE.
                    get(byteToHex(reader.peekType()));
                throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
                    message);
            }
          }
          if ((orderingRule == null) &&
              (attrType.getOrderingMatchingRule() == null))
          {
            Message message =
                INFO_SORTREQ_CONTROL_NO_ORDERING_RULE_FOR_ATTR.get(attrName);
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                message);
          }
          sortKeys.add(new SortKey(attrType, ascending, orderingRule));
        }
        return new ServerSideSortRequestControl(isCritical,
            new SortOrder(sortKeys.toArray(new SortKey[0])));
      }
      catch (DirectoryException de)
      {
        throw de;
      }
      catch (Exception e)
      {
        Message message =
            INFO_SORTREQ_CONTROL_CANNOT_DECODE_VALUE.get(
                getExceptionMessage(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
      }
    }
    public String getOID()
    {
      return OID_SERVER_SIDE_SORT_REQUEST_CONTROL;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<ServerSideSortRequestControl> DECODER =
      new Decoder();
  // The sort order associated with this control represented by strings.
  private ArrayList<String[]> decodedKeyList;
  // The sort order associated with this control.
  private SortOrder sortOrder;
  /**
   * Creates a new server-side sort request control based on the provided sort
   * order.
   * Creates a new server-side sort request control based on the definition in
   * the provided sort order string.
   *
   * @param  sortOrder  The sort order to use for this control.
   * @param  sortOrderString  The string representation of the sort order to
   *                          use for the control.
   * @throws LDAPException If the provided sort order string could not be
   *                       decoded.
   */
  public ServerSideSortRequestControl(SortOrder sortOrder)
  public ServerSideSortRequestControl(String sortOrderString)
      throws LDAPException
  {
    super(OID_SERVER_SIDE_SORT_REQUEST_CONTROL, false,
          encodeControlValue(sortOrder));
    this.sortOrder = sortOrder;
    this(false, sortOrderString);
  }
  /**
   * Creates a new server-side sort request control based on the definition in
   * the provided sort order string.  This is only intended for client-side use,
   * and controls created with this constructor should not attempt to use the
   * generated sort order for any purpose.
   * the provided sort order string.
   *
   * @param  sortOrderString  The string representation of the sort order to use
   *                          for the control.
   *
   * @throws  LDAPException  If the provided sort order string could not be
   *                         decoded.
   * @param  isCritical    Indicates whether support for this control
   *                       should be considered a critical part of the
   *                       server processing.
   * @param  sortOrderString  The string representation of the sort order to
   *                          use for the control.
   * @throws LDAPException If the provided sort order string could not be
   *                       decoded.
   */
  public ServerSideSortRequestControl(String sortOrderString)
         throws LDAPException
  public ServerSideSortRequestControl(boolean isCritical,
                                      String sortOrderString)
      throws LDAPException
  {
    super(OID_SERVER_SIDE_SORT_REQUEST_CONTROL, false,
          encodeControlValue(sortOrderString));
    super(OID_SERVER_SIDE_SORT_REQUEST_CONTROL, isCritical);
    this.sortOrder = null;
  }
  /**
   * Creates a new server-side sort request control with the provided
   * information.
   *
   * @param  oid           The OID to use for this control.
   * @param  isCritical    Indicates whether support for this control should be
   *                       considered a critical part of the server processing.
   * @param  controlValue  The encoded value for this control.
   * @param  sortOrder     sort order associated with this server-side sort
   *                       control.
   */
  private ServerSideSortRequestControl(String oid, boolean isCritical,
                                       ASN1OctetString controlValue,
                                       SortOrder sortOrder)
  {
    super(oid, isCritical, controlValue);
    this.sortOrder = sortOrder;
  }
  /**
   * Retrieves the sort order for this server-side sort request control.
   *
   * @return  The sort order for this server-side sort request control.
   */
  public SortOrder getSortOrder()
  {
    return sortOrder;
  }
  /**
   * Encodes the provided sort order object in a manner suitable for use as the
   * value of this control.
   *
   * @param  sortOrder  The sort order to be encoded.
   *
   * @return  The ASN.1 octet string containing the encoded sort order.
   */
  private static ASN1OctetString encodeControlValue(SortOrder sortOrder)
  {
    SortKey[] sortKeys = sortOrder.getSortKeys();
    ArrayList<ASN1Element> keyList =
         new ArrayList<ASN1Element>(sortKeys.length);
    for (SortKey sortKey : sortKeys)
    {
      ArrayList<ASN1Element> elementList = new ArrayList<ASN1Element>(3);
      elementList.add(new ASN1OctetString(
                               sortKey.getAttributeType().getNameOrOID()));
      if (sortKey.getOrderingRule() != null)
      {
        elementList.add(new ASN1OctetString(TYPE_ORDERING_RULE_ID,
                                 sortKey.getOrderingRule().getNameOrOID()));
      }
      if (! sortKey.ascending())
      {
        elementList.add(new ASN1Boolean(TYPE_REVERSE_ORDER, true));
      }
      keyList.add(new ASN1Sequence(elementList));
    }
    return new ASN1OctetString(new ASN1Sequence(keyList).encode());
  }
  /**
   * Encodes the provided sort order string in a manner suitable for use as the
   * value of this control.
   *
   * @param  sortOrderString  The sort order string to be encoded.
   *
   * @return  The ASN.1 octet string containing the encoded sort order.
   *
   * @throws  LDAPException  If the provided sort order string cannot be decoded
   *                         to create the control value.
   */
  private static ASN1OctetString encodeControlValue(String sortOrderString)
          throws LDAPException
  {
    StringTokenizer tokenizer = new StringTokenizer(sortOrderString, ",");
    ArrayList<ASN1Element> keyList = new ArrayList<ASN1Element>();
    decodedKeyList = new ArrayList<String[]>();
    while (tokenizer.hasMoreTokens())
    {
      String token = tokenizer.nextToken().trim();
@@ -238,16 +262,11 @@
        if (reverseOrder)
        {
          ArrayList<ASN1Element> elementList = new ArrayList<ASN1Element>(2);
          elementList.add(new ASN1OctetString(token));
          elementList.add(new ASN1Boolean(TYPE_REVERSE_ORDER, reverseOrder));
          keyList.add(new ASN1Sequence(elementList));
          decodedKeyList.add(new String[]{token, null, "r"});
        }
        else
        {
          ArrayList<ASN1Element> elementList = new ArrayList<ASN1Element>(1);
          elementList.add(new ASN1OctetString(token));
          keyList.add(new ASN1Sequence(elementList));
          decodedKeyList.add(new String[]{token, null, null});
        }
      }
      else if (colonPos == 0)
@@ -269,160 +288,91 @@
        if (reverseOrder)
        {
          ArrayList<ASN1Element> elementList = new ArrayList<ASN1Element>(3);
          elementList.add(new ASN1OctetString(attrName));
          elementList.add(new ASN1OctetString(TYPE_ORDERING_RULE_ID, ruleID));
          elementList.add(new ASN1Boolean(TYPE_REVERSE_ORDER, reverseOrder));
          keyList.add(new ASN1Sequence(elementList));
          decodedKeyList.add(new String[]{attrName, ruleID, "r"});
        }
        else
        {
          ArrayList<ASN1Element> elementList = new ArrayList<ASN1Element>(2);
          elementList.add(new ASN1OctetString(attrName));
          elementList.add(new ASN1OctetString(TYPE_ORDERING_RULE_ID, ruleID));
          keyList.add(new ASN1Sequence(elementList));
          decodedKeyList.add(new String[]{attrName, ruleID, null});
        }
      }
    }
    if (keyList.isEmpty())
    if (decodedKeyList.isEmpty())
    {
      Message message = INFO_SORTREQ_CONTROL_NO_SORT_KEYS.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    return new ASN1OctetString(new ASN1Sequence(keyList).encode());
  }
  /**
   * Creates a new server-side sort request control from the contents of the
   * provided control.
   * Creates a new server-side sort request control based on the provided sort
   * order.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this server-side sort request control.  It must not
   *                  be {@code null}.
   *
   * @return  The server-side sort request control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         server-side sort request control.
   * @param  sortOrder  The sort order to use for this control.
   */
  public static ServerSideSortRequestControl decodeControl(Control control)
         throws LDAPException
  public ServerSideSortRequestControl(SortOrder sortOrder)
  {
    ASN1OctetString controlValue = control.getValue();
    if (controlValue == null)
    {
      Message message = INFO_SORTREQ_CONTROL_NO_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    try
    {
      ASN1Sequence orderSequence =
           ASN1Sequence.decodeAsSequence(controlValue.value());
      ArrayList<ASN1Element> orderElements = orderSequence.elements();
      SortKey[] sortKeys = new SortKey[orderElements.size()];
      if (sortKeys.length == 0)
      {
        Message message = INFO_SORTREQ_CONTROL_NO_SORT_KEYS.get();
        throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
      }
      for (int i=0; i < sortKeys.length; i++)
      {
        ASN1Sequence keySequence = orderElements.get(i).decodeAsSequence();
        ArrayList<ASN1Element> keyElements = keySequence.elements();
        String attrName =
             keyElements.get(0).decodeAsOctetString().stringValue().
                  toLowerCase();
        AttributeType attrType = DirectoryServer.getAttributeType(attrName,
                                                                  false);
        if (attrType == null)
        {
          Message message = INFO_SORTREQ_CONTROL_UNDEFINED_ATTR.get(attrName);
          throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
        }
        OrderingMatchingRule orderingRule = null;
        boolean ascending = true;
        for (int j=1; j < keyElements.size(); j++)
        {
          ASN1Element e = keyElements.get(j);
          switch (e.getType())
          {
            case TYPE_ORDERING_RULE_ID:
              String orderingRuleID =
                   e.decodeAsOctetString().stringValue().toLowerCase();
              orderingRule =
                   DirectoryServer.getOrderingMatchingRule(orderingRuleID);
              if (orderingRule == null)
              {
                Message message = INFO_SORTREQ_CONTROL_UNDEFINED_ORDERING_RULE.
                    get(orderingRuleID);
                throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
              }
              break;
            case TYPE_REVERSE_ORDER:
              ascending = ! e.decodeAsBoolean().booleanValue();
              break;
            default:
              Message message = INFO_SORTREQ_CONTROL_INVALID_SEQ_ELEMENT_TYPE.
                  get(byteToHex(e.getType()));
              throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
          }
        }
        if ((orderingRule == null) &&
            (attrType.getOrderingMatchingRule() == null))
        {
          Message message =
              INFO_SORTREQ_CONTROL_NO_ORDERING_RULE_FOR_ATTR.get(attrName);
          throw new LDAPException(LDAPResultCode.CONSTRAINT_VIOLATION, message);
        }
        sortKeys[i] = new SortKey(attrType, ascending, orderingRule);
      }
      return new ServerSideSortRequestControl(control.getOID(),
                                              control.isCritical(),
                                              controlValue,
                                              new SortOrder(sortKeys));
    }
    catch (LDAPException le)
    {
      throw le;
    }
    catch (Exception e)
    {
      Message message =
          INFO_SORTREQ_CONTROL_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, e);
    }
    this(false, sortOrder);
  }
  /**
   * Creates a new server-side sort request control with the provided
   * information.
   *
   * @param  isCritical    Indicates whether support for this control should be
   *                       considered a critical part of the server processing.
   * @param  sortOrder     sort order associated with this server-side sort
   *                       control.
   */
  public ServerSideSortRequestControl(boolean isCritical, SortOrder sortOrder)
  {
    super(OID_SERVER_SIDE_SORT_REQUEST_CONTROL, isCritical);
    this.sortOrder = sortOrder;
  }
  /**
   * Retrieves a string representation of this server-side sort request control.
   * Retrieves the sort order for this server-side sort request control.
   *
   * @return  A string representation of this server-side sort request control.
   * @return  The sort order for this server-side sort request control.
   * @throws  DirectoryException if an error occurs while retriving the
   *          sort order.
   */
  public String toString()
  public SortOrder getSortOrder() throws DirectoryException
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
    if(sortOrder == null)
    {
      sortOrder = decodeSortOrderFromString();
    }
    return sortOrder;
  }
  /**
   * Writes this control's value to an ASN.1 writer. The value (if any) must
   * be written as an ASN1OctetString.
   *
   * @param writer The ASN.1 writer to use.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  @Override
  protected void writeValue(ASN1Writer writer) throws IOException {
    if(decodedKeyList != null)
    {
      // This control was created with a sort order string so encode using
      // that.
      writeValueFromString(writer);
    }
    else
    {
      // This control must have been created with a typed sort order object
      // so encode using that.
      writeValueFromSortOrder(writer);
    }
  }
  /**
   * Appends a string representation of this server-side sort request control
@@ -430,16 +380,160 @@
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("ServerSideSortRequestControl(");
    if(sortOrder == null)
    {
      buffer.append("SortOrder(");
    if (sortOrder != null)
      if (decodedKeyList.size() > 0)
      {
        decodedKeyToString(decodedKeyList.get(0), buffer);
        for (int i=1; i < decodedKeyList.size(); i++)
        {
          buffer.append(",");
          decodedKeyToString(decodedKeyList.get(i), buffer);
        }
      }
      buffer.append(")");
    }
    else
    {
      buffer.append(sortOrder);
    }
    buffer.append(")");
  }
  private void decodedKeyToString(String[] decodedKey, StringBuilder buffer)
  {
    buffer.append("SortKey(");
    if (decodedKey[2] == null)
    {
      buffer.append("+");
    }
    else
    {
      buffer.append("-");
    }
    buffer.append(decodedKey[0]);
    if (decodedKey[1] != null)
    {
      buffer.append(":");
      buffer.append(decodedKey[1]);
    }
    buffer.append(")");
  }
  private SortOrder decodeSortOrderFromString() throws DirectoryException
  {
    ArrayList<SortKey> sortKeys = new ArrayList<SortKey>();
    for(String[] decodedKey : decodedKeyList)
    {
      AttributeType attrType =
          DirectoryServer.getAttributeType(decodedKey[0].toLowerCase(), false);
      if (attrType == null)
      {
        Message message =
            INFO_SORTREQ_CONTROL_UNDEFINED_ATTR.get(decodedKey[0]);
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      OrderingMatchingRule orderingRule = null;
      if(decodedKey[1] != null)
      {
        orderingRule =
            DirectoryServer.getOrderingMatchingRule(
                decodedKey[1].toLowerCase());
        if (orderingRule == null)
        {
          Message message =
              INFO_SORTREQ_CONTROL_UNDEFINED_ORDERING_RULE.
                  get(decodedKey[1]);
          throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
              message);
        }
      }
      boolean ascending = true;
      if(decodedKey[2] != null && decodedKey[2].equals("r"))
      {
        ascending = false;
      }
      if ((orderingRule == null) &&
          (attrType.getOrderingMatchingRule() == null))
      {
        Message message =
            INFO_SORTREQ_CONTROL_NO_ORDERING_RULE_FOR_ATTR.get(
                decodedKey[0]);
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
            message);
      }
      sortKeys.add(new SortKey(attrType, ascending, orderingRule));
    }
    return new SortOrder(sortKeys.toArray(new SortKey[0]));
  }
  private void writeValueFromString(ASN1Writer writer) throws IOException
  {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    writer.writeStartSequence();
    for(String[] strs : decodedKeyList)
    {
      writer.writeStartSequence();
      // Attr name will always be present
      writer.writeOctetString(strs[0]);
      // Rule ID might not be present
      if(strs[1] != null)
      {
        writer.writeOctetString(TYPE_ORDERING_RULE_ID, strs[1]);
      }
      // Reverse if present
      if(strs[2] != null)
      {
        writer.writeBoolean(TYPE_REVERSE_ORDER, true);
      }
      writer.writeEndSequence();
    }
    writer.writeEndSequence();
    writer.writeEndSequence();
  }
  private void writeValueFromSortOrder(ASN1Writer writer) throws IOException
  {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    writer.writeStartSequence();
    for (SortKey sortKey : sortOrder.getSortKeys())
    {
      writer.writeStartSequence();
      writer.writeOctetString(sortKey.getAttributeType().getNameOrOID());
      if (sortKey.getOrderingRule() != null)
      {
        writer.writeOctetString(TYPE_ORDERING_RULE_ID,
            sortKey.getOrderingRule().getNameOrOID());
      }
      if (! sortKey.ascending())
      {
        writer.writeBoolean(TYPE_REVERSE_ORDER, true);
      }
      writer.writeEndSequence();
    }
    writer.writeEndSequence();
    writer.writeEndSequence();
  }
}
opends/src/server/org/opends/server/controls/ServerSideSortResponseControl.java
@@ -28,16 +28,15 @@
import org.opends.messages.Message;
import java.io.IOException;
import java.util.ArrayList;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Enumerated;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ByteString;
import org.opends.server.types.ResultCode;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
@@ -79,6 +78,63 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<ServerSideSortResponseControl>
  {
    /**
     * {@inheritDoc}
     */
    public ServerSideSortResponseControl decode(boolean isCritical,
                                                ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        Message message = INFO_SORTRES_CONTROL_NO_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      try
      {
        reader.readStartSequence();
        int resultCode = (int)reader.readInteger();
        String attributeType = null;
        if(reader.hasNextElement())
        {
          attributeType = reader.readOctetStringAsString();
        }
        return new ServerSideSortResponseControl(isCritical,
            resultCode,
            attributeType);
      }
      catch (Exception e)
      {
        Message message =
            INFO_SORTRES_CONTROL_CANNOT_DECODE_VALUE.get(
                getExceptionMessage(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
      }
    }
    public String getOID()
    {
      return OID_SERVER_SIDE_SORT_RESPONSE_CONTROL;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<ServerSideSortResponseControl> DECODER =
    new Decoder();
  /**
   * The BER type to use when encoding the attribute type element.
   */
  private static final byte TYPE_ATTRIBUTE_TYPE = (byte) 0x80;
@@ -103,11 +159,7 @@
   */
  public ServerSideSortResponseControl(int resultCode, String attributeType)
  {
    super(OID_SERVER_SIDE_SORT_RESPONSE_CONTROL, false,
          encodeControlValue(resultCode, attributeType));
    this.resultCode    = resultCode;
    this.attributeType = attributeType;
    this(false, resultCode, attributeType);
  }
@@ -116,19 +168,16 @@
   * Creates a new server-side sort response control with the provided
   * information.
   *
   * @param  oid            The OID to use for this control.
   * @param  isCritical     Indicates whether support for this control should be
   *                        considered a critical part of the server processing.
   * @param  controlValue   The encoded value for this control.
   * @param  resultCode     The result code for the sort result.
   * @param  attributeType  The attribute type for the sort result.
   */
  private ServerSideSortResponseControl(String oid, boolean isCritical,
                                        ASN1OctetString controlValue,
                                        int resultCode,
                                        String attributeType)
  public ServerSideSortResponseControl(boolean isCritical,
                                       int resultCode,
                                       String attributeType)
  {
    super(oid, isCritical, controlValue);
    super(OID_SERVER_SIDE_SORT_RESPONSE_CONTROL, isCritical);
    this.resultCode    = resultCode;
    this.attributeType = attributeType;
@@ -162,93 +211,25 @@
  /**
   * Encodes the provided set of result codes and attribute types in a manner
   * suitable for use as the value of this control.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  resultCode     The result code for the sort result.
   * @param  attributeType  The attribute type for the sort result, or
   *                        {@code null} if there is none.
   *
   * @return  The ASN.1 octet string containing the encoded sort result.
   * @param writer The ASN.1 writer to use.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  private static ASN1OctetString encodeControlValue(int resultCode,
                                                    String attributeType)
  {
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2);
    elements.add(new ASN1Enumerated(resultCode));
  @Override
  protected void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    writer.writeStartSequence();
    writer.writeInteger(resultCode);
    if (attributeType != null)
    {
      elements.add(new ASN1OctetString(TYPE_ATTRIBUTE_TYPE, attributeType));
      writer.writeOctetString(TYPE_ATTRIBUTE_TYPE, attributeType);
    }
    writer.writeEndSequence();
    return new ASN1OctetString(new ASN1Sequence(elements).encode());
  }
  /**
   * Creates a new server-side sort response control from the contents of the
   * provided control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this server-side sort response control.  It must
   *                  not be {@code null}.
   *
   * @return  The server-side sort response control decoded from the provided
   *          control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid
   *                         server-side sort response control.
   */
  public static ServerSideSortResponseControl decodeControl(Control control)
         throws LDAPException
  {
    ASN1OctetString controlValue = control.getValue();
    if (controlValue == null)
    {
      Message message = INFO_SORTRES_CONTROL_NO_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    try
    {
      ArrayList<ASN1Element> elements =
           ASN1Sequence.decodeAsSequence(control.getValue().value()).elements();
      int resultCode = elements.get(0).decodeAsEnumerated().intValue();
      String attributeType = null;
      if (elements.size() > 1)
      {
        attributeType = elements.get(1).decodeAsOctetString().stringValue();
      }
      return new ServerSideSortResponseControl(control.getOID(),
                                               control.isCritical(),
                                               control.getValue(), resultCode,
                                               attributeType);
    }
    catch (Exception e)
    {
      Message message =
          INFO_SORTRES_CONTROL_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, e);
    }
  }
  /**
   * Retrieves a string representation of this server-side sort response
   * control.
   *
   * @return  A string representation of this server-side sort response control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
    writer.writeEndSequence();
  }
@@ -259,6 +240,7 @@
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("ServerSideSortResponseControl(resultCode=");
opends/src/server/org/opends/server/controls/SubtreeDeleteControl.java
@@ -26,21 +26,103 @@
 */
package org.opends.server.controls;
import org.opends.server.types.Control;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import java.io.IOException;
import org.opends.messages.Message;
import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.types.ByteString;
import org.opends.server.types.Control;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ResultCode;
/**
 * This class implements the subtree delete control.
 * This class implements the subtree delete control defined in
 * draft-armijo-ldap-treedelete. It makes it possible for clients to
 * delete subtrees of entries.
 */
public class SubtreeDeleteControl extends Control
{
  /**
   * Creates a new instance of Subtree Delete control with the
   * default settings.
   * ControlDecoder implementation to decode this control from a
   * ByteString.
   */
  public SubtreeDeleteControl()
  private final static class Decoder implements
      ControlDecoder<SubtreeDeleteControl>
  {
    super(OID_SUBTREE_DELETE_CONTROL, false);
    /**
     * {@inheritDoc}
     */
    public SubtreeDeleteControl decode(boolean isCritical,
        ByteString value) throws DirectoryException
    {
      if (value != null)
      {
        Message message =
            ERR_SUBTREE_DELETE_INVALID_CONTROL_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      return new SubtreeDeleteControl(isCritical);
    }
    public String getOID()
    {
      return OID_SUBTREE_DELETE_CONTROL;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<SubtreeDeleteControl> DECODER =
      new Decoder();
  /**
   * Creates a new subtree delete control.
   *
   * @param isCritical
   *          Indicates whether the control should be considered
   *          critical for the operation processing.
   */
  public SubtreeDeleteControl(boolean isCritical)
  {
    super(OID_SUBTREE_DELETE_CONTROL, isCritical);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  protected void writeValue(ASN1Writer writer) throws IOException
  {
    // Nothing to do.
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("SubtreeDeleteControl()");
  }
}
opends/src/server/org/opends/server/controls/VLVRequestControl.java
@@ -28,17 +28,15 @@
import org.opends.messages.Message;
import java.io.IOException;
import java.util.ArrayList;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Integer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.ByteString;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ByteString;
import org.opends.server.types.ResultCode;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
@@ -67,6 +65,95 @@
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<VLVRequestControl>
  {
    /**
     * {@inheritDoc}
     */
    public VLVRequestControl decode(boolean isCritical, ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        Message message = INFO_VLVREQ_CONTROL_NO_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      try
      {
        reader.readStartSequence();
        int beforeCount = (int)reader.readInteger();
        int afterCount  = (int)reader.readInteger();
        int offset = 0;
        int contentCount = 0;
        ByteString greaterThanOrEqual = null;
        byte targetType = reader.peekType();
        switch (targetType)
        {
          case TYPE_TARGET_BYOFFSET:
            reader.readStartSequence();
            offset = (int)reader.readInteger();
            contentCount = (int)reader.readInteger();
            reader.readEndSequence();
            break;
          case TYPE_TARGET_GREATERTHANOREQUAL:
            greaterThanOrEqual = reader.readOctetString();
            break;
          default:
            Message message = INFO_VLVREQ_CONTROL_INVALID_TARGET_TYPE.get(
                byteToHex(targetType));
            throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
        }
        ByteString contextID = null;
        if (reader.hasNextElement())
        {
          contextID = reader.readOctetString();
        }
        if(targetType == TYPE_TARGET_BYOFFSET)
        {
          return new VLVRequestControl(isCritical, beforeCount,
              afterCount, offset, contentCount, contextID);
        }
        return new VLVRequestControl(isCritical, beforeCount,
            afterCount, greaterThanOrEqual, contextID);
      }
      catch (DirectoryException de)
      {
        throw de;
      }
      catch (Exception e)
      {
        Message message =
            INFO_VLVREQ_CONTROL_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
      }
    }
    public String getOID()
    {
      return OID_VLV_REQUEST_CONTROL;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<VLVRequestControl> DECODER =
    new Decoder();
  /**
   * The BER type to use when encoding the byOffset target element.
   */
  public static final byte TYPE_TARGET_BYOFFSET = (byte) 0xA0;
@@ -119,7 +206,7 @@
  public VLVRequestControl(int beforeCount, int afterCount, int offset,
                           int contentCount)
  {
    this(beforeCount, afterCount, offset, contentCount, null);
    this(false, beforeCount, afterCount, offset, contentCount, null);
  }
@@ -127,6 +214,7 @@
  /**
   * Creates a new VLV request control with the provided information.
   *
   * @param  isCritical    Indicates whether or not the control is critical.
   * @param  beforeCount   The number of entries before the target offset to
   *                       retrieve in the results page.
   * @param  afterCount    The number of entries after the target offset to
@@ -142,12 +230,10 @@
   *                       the server did not include a context ID in the
   *                       last response.
   */
  public VLVRequestControl(int beforeCount, int afterCount, int offset,
                           int contentCount, ByteString contextID)
  public VLVRequestControl(boolean isCritical, int beforeCount, int afterCount,
                           int offset, int contentCount, ByteString contextID)
  {
    super(OID_VLV_REQUEST_CONTROL, false,
          encodeControlValue(beforeCount, afterCount, offset, contentCount,
                             contextID));
    super(OID_VLV_REQUEST_CONTROL, isCritical);
    this.beforeCount  = beforeCount;
    this.afterCount   = afterCount;
@@ -174,7 +260,7 @@
  public VLVRequestControl(int beforeCount, int afterCount,
                           ByteString greaterThanOrEqual)
  {
    this(beforeCount, afterCount, greaterThanOrEqual, null);
    this(false, beforeCount, afterCount, greaterThanOrEqual, null);
  }
@@ -182,6 +268,8 @@
  /**
   * Creates a new VLV request control with the provided information.
   *
   * @param  isCritical          Indicates whether the control should be
   *                             considered critical.
   * @param  beforeCount         The number of entries before the target
   *                             assertion value.
   * @param  afterCount          The number of entries after the target
@@ -195,13 +283,11 @@
   *                             response or the server did not include a
   *                             context ID in the last response.
   */
  public VLVRequestControl(int beforeCount, int afterCount,
  public VLVRequestControl(boolean isCritical, int beforeCount, int afterCount,
                           ByteString greaterThanOrEqual,
                           ByteString contextID)
  {
    super(OID_VLV_REQUEST_CONTROL, false,
          encodeControlValue(beforeCount, afterCount, greaterThanOrEqual,
                             contextID));
    super(OID_VLV_REQUEST_CONTROL, isCritical);
    this.beforeCount        = beforeCount;
    this.afterCount         = afterCount;
@@ -214,46 +300,6 @@
  /**
   * Creates a new VLV request control with the provided information.
   *
   * @param  oid                 The OID for the control.
   * @param  isCritical          Indicates whether the control should be
   *                             considered critical.
   * @param  controlValue        The pre-encoded value for the control.
   * @param  beforeCount         The number of entries before the target
   *                             assertion value.
   * @param  afterCount          The number of entries after the target
   *                             assertion value.
   * @param  greaterThanOrEqual  The greaterThanOrEqual target assertion value
   *                             that indicates where to start the page of
   *                             results.
   * @param  contextID           The context ID provided by the server in the
   *                             last VLV response for the same set of criteria,
   *                             or {@code null} if there was no previous VLV
   *                             response or the server did not include a
   *                             context ID in the last response.
   */
  private VLVRequestControl(String oid, boolean isCritical,
                            ASN1OctetString controlValue, int beforeCount,
                            int afterCount, byte targetType,
                            int offset, int contentCount,
                            ByteString greaterThanOrEqual,
                            ByteString contextID)
  {
    super(oid, isCritical, controlValue);
    this.beforeCount        = beforeCount;
    this.afterCount         = afterCount;
    this.targetType         = targetType;
    this.offset             = offset;
    this.contentCount       = contentCount;
    this.greaterThanOrEqual = greaterThanOrEqual;
    this.contextID          = contextID;
  }
  /**
   * Retrieves the number of entries before the target offset or assertion value
   * to include in the results page.
   *
@@ -358,188 +404,38 @@
  /**
   * Encodes the provided information in a manner suitable for use as the value
   * of this control.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  beforeCount   The number of entries before the target offset to
   *                       retrieve in the results page.
   * @param  afterCount    The number of entries after the target offset to
   *                       retrieve in the results page.
   * @param  offset        The offset in the result set to target for the
   *                       beginning of the page of results.
   * @param  contentCount  The content count returned by the server in the last
   *                       phase of the VLV request, or zero for a new VLV
   *                       request session.
   * @param  contextID     The context ID provided by the server in the last
   *                       VLV response for the same set of criteria, or
   *                       {@code null} if there was no previous VLV response or
   *                       the server did not include a context ID in the
   *                       last response.
   *
   * @return  The ASN.1 octet string containing the encoded sort order.
   * @param writer The ASN.1 writer to use.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  private static ASN1OctetString encodeControlValue(int beforeCount,
                                      int afterCount, int offset,
                                      int contentCount, ByteString contextID)
  {
    ArrayList<ASN1Element> vlvElements = new ArrayList<ASN1Element>(4);
    vlvElements.add(new ASN1Integer(beforeCount));
    vlvElements.add(new ASN1Integer(afterCount));
  @Override
  protected void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    ArrayList<ASN1Element> targetElements = new ArrayList<ASN1Element>(2);
    targetElements.add(new ASN1Integer(offset));
    targetElements.add(new ASN1Integer(contentCount));
    vlvElements.add(new ASN1Sequence(TYPE_TARGET_BYOFFSET, targetElements));
    writer.writeStartSequence();
    writer.writeInteger(beforeCount);
    writer.writeInteger(afterCount);
    if(targetType == TYPE_TARGET_BYOFFSET)
    {
      writer.writeStartSequence(TYPE_TARGET_BYOFFSET);
      writer.writeInteger(offset);
      writer.writeInteger(contentCount);
      writer.writeEndSequence();
    }
    else
    {
      writer.writeOctetString(TYPE_TARGET_GREATERTHANOREQUAL,
          greaterThanOrEqual);
    }
    if (contextID != null)
    {
      vlvElements.add(contextID.toASN1OctetString());
      writer.writeOctetString(contextID);
    }
    writer.writeEndSequence();
    return new ASN1OctetString(new ASN1Sequence(vlvElements).encode());
  }
  /**
   * Encodes the provided information in a manner suitable for use as the value
   * of this control.
   *
   * @param  beforeCount         The number of entries before the target
   *                             assertion value.
   * @param  afterCount          The number of entries after the target
   *                             assertion value.
   * @param  greaterThanOrEqual  The greaterThanOrEqual target assertion value
   *                             that indicates where to start the page of
   *                             results.
   * @param  contextID           The context ID provided by the server in the
   *                             last VLV response for the same set of criteria,
   *                             or {@code null} if there was no previous VLV
   *                             response or the server did not include a
   *                             context ID in the last response.
   *
   * @return  The ASN.1 octet string containing the encoded sort order.
   */
  private static ASN1OctetString encodeControlValue(int beforeCount,
                                      int afterCount,
                                      ByteString greaterThanOrEqual,
                                      ByteString contextID)
  {
    ArrayList<ASN1Element> vlvElements = new ArrayList<ASN1Element>(4);
    vlvElements.add(new ASN1Integer(beforeCount));
    vlvElements.add(new ASN1Integer(afterCount));
    vlvElements.add(new ASN1OctetString(TYPE_TARGET_GREATERTHANOREQUAL,
                                        greaterThanOrEqual.value()));
    if (contextID != null)
    {
      vlvElements.add(contextID.toASN1OctetString());
    }
    return new ASN1OctetString(new ASN1Sequence(vlvElements).encode());
  }
  /**
   * Creates a new VLV request control from the contents of the provided
   * control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this VLV request control.  It must not be
   *                  {@code null}.
   *
   * @return  The VLV request control decoded from the provided control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid VLV
   *                         request control.
   */
  public static VLVRequestControl decodeControl(Control control)
         throws LDAPException
  {
    ASN1OctetString controlValue = control.getValue();
    if (controlValue == null)
    {
      Message message = INFO_VLVREQ_CONTROL_NO_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    try
    {
      ASN1Sequence vlvSequence =
           ASN1Sequence.decodeAsSequence(controlValue.value());
      ArrayList<ASN1Element> elements = vlvSequence.elements();
      if ((elements.size() < 3) || (elements.size() > 4))
      {
        Message message =
            INFO_VLVREQ_CONTROL_INVALID_ELEMENT_COUNT.get(elements.size());
        throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
      }
      int beforeCount = elements.get(0).decodeAsInteger().intValue();
      int afterCount  = elements.get(1).decodeAsInteger().intValue();
      ASN1Element targetElement = elements.get(2);
      int offset = 0;
      int contentCount = 0;
      ASN1OctetString greaterThanOrEqual = null;
      byte targetType = targetElement.getType();
      switch (targetType)
      {
        case TYPE_TARGET_BYOFFSET:
          ArrayList<ASN1Element> targetElements =
               targetElement.decodeAsSequence().elements();
          offset = targetElements.get(0).decodeAsInteger().intValue();
          contentCount = targetElements.get(1).decodeAsInteger().intValue();
          break;
        case TYPE_TARGET_GREATERTHANOREQUAL:
          greaterThanOrEqual = targetElement.decodeAsOctetString();
          break;
        default:
          Message message = INFO_VLVREQ_CONTROL_INVALID_TARGET_TYPE.get(
              byteToHex(targetType));
          throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
      }
      ASN1OctetString contextID = null;
      if (elements.size() == 4)
      {
        contextID = elements.get(3).decodeAsOctetString();
      }
      return new VLVRequestControl(control.getOID(), control.isCritical(),
                                   controlValue, beforeCount, afterCount,
                                   targetType, offset, contentCount,
                                   greaterThanOrEqual, contextID);
    }
    catch (LDAPException le)
    {
      throw le;
    }
    catch (Exception e)
    {
      Message message =
          INFO_VLVREQ_CONTROL_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, e);
    }
  }
  /**
   * Retrieves a string representation of this VLV request control.
   *
   * @return  A string representation of this VLV request control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
    writer.writeEndSequence();
  }
@@ -550,6 +446,7 @@
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("VLVRequestControl(beforeCount=");
opends/src/server/org/opends/server/controls/VLVResponseControl.java
@@ -28,18 +28,12 @@
import org.opends.messages.Message;
import java.io.IOException;
import java.util.ArrayList;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Enumerated;
import org.opends.server.protocols.asn1.ASN1Integer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.ByteString;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
@@ -75,6 +69,65 @@
public class VLVResponseControl
       extends Control
{
  /**
   * ControlDecoder implentation to decode this control from a ByteString.
   */
  private final static class Decoder
      implements ControlDecoder<VLVResponseControl>
  {
    /**
     * {@inheritDoc}
     */
    public VLVResponseControl decode(boolean isCritical, ByteString value)
        throws DirectoryException
    {
      if (value == null)
      {
        Message message = INFO_VLVRES_CONTROL_NO_VALUE.get();
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
      }
      ASN1Reader reader = ASN1.getReader(value);
      try
      {
        reader.readStartSequence();
        int targetPosition = (int)reader.readInteger();
        int contentCount   = (int)reader.readInteger();
        int vlvResultCode  = (int)reader.readInteger();
        ByteString contextID = null;
        if (reader.hasNextElement())
        {
          contextID = reader.readOctetString();
        }
        return new VLVResponseControl(isCritical, targetPosition,
            contentCount, vlvResultCode, contextID);
      }
      catch (Exception e)
      {
        Message message =
            INFO_VLVRES_CONTROL_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
      }
    }
    /**
     * {@inheritDoc}
     */
    public String getOID()
    {
      return OID_VLV_RESPONSE_CONTROL;
    }
  }
  /**
   * The Control Decoder that can be used to decode this control.
   */
  public static final ControlDecoder<VLVResponseControl> DECODER =
    new Decoder();
  // The context ID for this VLV response control.
  private ByteString contextID;
@@ -100,7 +153,7 @@
  public VLVResponseControl(int targetPosition, int contentCount,
                            int vlvResultCode)
  {
    this(targetPosition, contentCount, vlvResultCode, null);
    this(false, targetPosition, contentCount, vlvResultCode, null);
  }
@@ -108,46 +161,19 @@
  /**
   * Creates a new VLV response control with the provided information.
   *
   * @param  targetPosition  The position of the target entry in the result set.
   * @param  contentCount    The content count estimating the total number of
   *                         entries in the result set.
   * @param  vlvResultCode   The result code for the VLV operation.
   * @param  contextID       The context ID for this VLV response control.
   */
  public VLVResponseControl(int targetPosition, int contentCount,
                            int vlvResultCode, ByteString contextID)
  {
    super(OID_VLV_RESPONSE_CONTROL, false,
          encodeControlValue(targetPosition, contentCount, vlvResultCode,
                             contextID));
    this.targetPosition = targetPosition;
    this.contentCount   = contentCount;
    this.vlvResultCode  = vlvResultCode;
    this.contextID      = contextID;
  }
  /**
   * Creates a new VLV response control with the provided information.
   *
   * @param  oid             The OID for the control.
   * @param  isCritical      Indicates whether the control should be considered
   *                         critical.
   * @param  controlValue    The pre-encoded value for the control.
   * @param  targetPosition  The position of the target entry in the result set.
   * @param  contentCount    The content count estimating the total number of
   *                         entries in the result set.
   * @param  vlvResultCode   The result code for the VLV operation.
   * @param  contextID       The context ID for this VLV response control.
   */
  private VLVResponseControl(String oid, boolean isCritical,
                             ASN1OctetString controlValue, int targetPosition,
  public VLVResponseControl(boolean isCritical, int targetPosition,
                             int contentCount, int vlvResultCode,
                             ByteString contextID)
  {
    super(oid, isCritical, controlValue);
    super(OID_VLV_RESPONSE_CONTROL, isCritical);
    this.targetPosition = targetPosition;
    this.contentCount   = contentCount;
@@ -209,110 +235,27 @@
  /**
   * Encodes the provided information in a manner suitable for use as the value
   * of this control.
   * Writes this control's value to an ASN.1 writer. The value (if any) must be
   * written as an ASN1OctetString.
   *
   * @param  targetPosition  The position of the target entry in the result set.
   * @param  contentCount    The content count estimating the total number of
   *                         entries in the result set.
   * @param  vlvResultCode   The result code for the VLV operation.
   * @param  contextID       The context ID for this VLV response control.
   *
   * @return  The ASN.1 octet string containing the encoded sort order.
   * @param writer The ASN.1 writer to use.
   * @throws IOException If a problem occurs while writing to the stream.
   */
  private static ASN1OctetString encodeControlValue(int targetPosition,
                                      int contentCount, int vlvResultCode,
                                      ByteString contextID)
  {
    ArrayList<ASN1Element> vlvElements = new ArrayList<ASN1Element>(4);
    vlvElements.add(new ASN1Integer(targetPosition));
    vlvElements.add(new ASN1Integer(contentCount));
    vlvElements.add(new ASN1Enumerated(vlvResultCode));
  @Override
  protected void writeValue(ASN1Writer writer) throws IOException {
    writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
    writer.writeStartSequence();
    writer.writeInteger(targetPosition);
    writer.writeInteger(contentCount);
    writer.writeInteger(vlvResultCode);
    if (contextID != null)
    {
      vlvElements.add(contextID.toASN1OctetString());
      writer.writeOctetString(contextID);
    }
    writer.writeEndSequence();
    return new ASN1OctetString(new ASN1Sequence(vlvElements).encode());
  }
  /**
   * Creates a new VLV response control from the contents of the provided
   * control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this VLV response control.  It must not be
   *                  {@code null}.
   *
   * @return  The VLV response control decoded from the provided control.
   *
   * @throws  LDAPException  If this control cannot be decoded as a valid VLV
   *                         response control.
   */
  public static VLVResponseControl decodeControl(Control control)
         throws LDAPException
  {
    ASN1OctetString controlValue = control.getValue();
    if (controlValue == null)
    {
      Message message = INFO_VLVRES_CONTROL_NO_VALUE.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    try
    {
      ASN1Sequence vlvSequence =
           ASN1Sequence.decodeAsSequence(controlValue.value());
      ArrayList<ASN1Element> elements = vlvSequence.elements();
      if ((elements.size() < 3) || (elements.size() > 4))
      {
        Message message =
            INFO_VLVRES_CONTROL_INVALID_ELEMENT_COUNT.get(elements.size());
        throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
      }
      int targetPosition = elements.get(0).decodeAsInteger().intValue();
      int contentCount   = elements.get(1).decodeAsInteger().intValue();
      int vlvResultCode  = elements.get(2).decodeAsEnumerated().intValue();
      ASN1OctetString contextID = null;
      if (elements.size() == 4)
      {
        contextID = elements.get(3).decodeAsOctetString();
      }
      return new VLVResponseControl(control.getOID(), control.isCritical(),
                                    controlValue, targetPosition, contentCount,
                                    vlvResultCode, contextID);
    }
    catch (LDAPException le)
    {
      throw le;
    }
    catch (Exception e)
    {
      Message message =
          INFO_VLVRES_CONTROL_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, e);
    }
  }
  /**
   * Retrieves a string representation of this VLV request control.
   *
   * @return  A string representation of this VLV request control.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
    writer.writeEndSequence();
  }
@@ -323,6 +266,7 @@
   *
   * @param  buffer  The buffer to which the information should be appended.
   */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append("VLVResponseControl(targetPosition=");
opends/src/server/org/opends/server/core/AddOperation.java
@@ -29,13 +29,7 @@
import java.util.List;
import java.util.Map;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.ByteString;
import org.opends.server.types.DN;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.Operation;
import org.opends.server.types.RawAttribute;
import org.opends.server.types.*;
/**
 * This interface defines an operation that may be used to add a new entry to
Diff truncated after the above file
opends/src/server/org/opends/server/core/AddOperationBasis.java opends/src/server/org/opends/server/core/AddOperationWrapper.java opends/src/server/org/opends/server/core/BindOperation.java opends/src/server/org/opends/server/core/BindOperationBasis.java opends/src/server/org/opends/server/core/BindOperationWrapper.java opends/src/server/org/opends/server/core/CompareOperation.java opends/src/server/org/opends/server/core/CompareOperationBasis.java opends/src/server/org/opends/server/core/DefaultCompressedSchema.java opends/src/server/org/opends/server/core/DeleteOperationBasis.java opends/src/server/org/opends/server/core/DirectoryServer.java opends/src/server/org/opends/server/core/ExtendedOperation.java opends/src/server/org/opends/server/core/ExtendedOperationBasis.java opends/src/server/org/opends/server/core/GroupManager.java opends/src/server/org/opends/server/core/ModifyDNOperation.java opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java opends/src/server/org/opends/server/core/ModifyDNOperationWrapper.java opends/src/server/org/opends/server/core/ModifyOperation.java opends/src/server/org/opends/server/core/ModifyOperationBasis.java opends/src/server/org/opends/server/core/ModifyOperationWrapper.java opends/src/server/org/opends/server/core/OperationWrapper.java opends/src/server/org/opends/server/core/PasswordPolicy.java opends/src/server/org/opends/server/core/PasswordPolicyState.java opends/src/server/org/opends/server/core/PluginConfigManager.java opends/src/server/org/opends/server/core/SchemaConfigManager.java opends/src/server/org/opends/server/core/SearchOperation.java opends/src/server/org/opends/server/core/SearchOperationBasis.java opends/src/server/org/opends/server/core/SearchOperationWrapper.java opends/src/server/org/opends/server/core/UnbindOperationBasis.java opends/src/server/org/opends/server/core/networkgroups/NetworkGroup.java opends/src/server/org/opends/server/core/networkgroups/ResourceLimitsPolicyFactory.java opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java opends/src/server/org/opends/server/crypto/CryptoManagerSync.java opends/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperation.java opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java opends/src/server/org/opends/server/extensions/AnonymousSASLMechanismHandler.java opends/src/server/org/opends/server/extensions/AttributeValuePasswordValidator.java opends/src/server/org/opends/server/extensions/Base64PasswordStorageScheme.java opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java opends/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java opends/src/server/org/opends/server/extensions/CancelExtendedOperation.java opends/src/server/org/opends/server/extensions/CharacterSetPasswordValidator.java opends/src/server/org/opends/server/extensions/ClearPasswordStorageScheme.java opends/src/server/org/opends/server/extensions/ConfigFileHandler.java opends/src/server/org/opends/server/extensions/ConnectionSecurityProvider.java opends/src/server/org/opends/server/extensions/CryptPasswordStorageScheme.java opends/src/server/org/opends/server/extensions/DictionaryPasswordValidator.java opends/src/server/org/opends/server/extensions/DynamicGroup.java opends/src/server/org/opends/server/extensions/EntryDNVirtualAttributeProvider.java opends/src/server/org/opends/server/extensions/EntryUUIDVirtualAttributeProvider.java opends/src/server/org/opends/server/extensions/ExactMatchIdentityMapper.java opends/src/server/org/opends/server/extensions/ExternalSASLMechanismHandler.java opends/src/server/org/opends/server/extensions/FileSystemEntryCache.java opends/src/server/org/opends/server/extensions/FingerprintCertificateMapper.java opends/src/server/org/opends/server/extensions/GSSAPISASLMechanismHandler.java opends/src/server/org/opends/server/extensions/GetConnectionIDExtendedOperation.java opends/src/server/org/opends/server/extensions/HasSubordinatesVirtualAttributeProvider.java opends/src/server/org/opends/server/extensions/InternalConnectionSecurityProvider.java (deleted) opends/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java opends/src/server/org/opends/server/extensions/LengthBasedPasswordValidator.java opends/src/server/org/opends/server/extensions/MD5PasswordStorageScheme.java opends/src/server/org/opends/server/extensions/MemberVirtualAttributeProvider.java opends/src/server/org/opends/server/extensions/NullConnectionSecurityProvider.java (deleted) opends/src/server/org/opends/server/extensions/NumSubordinatesVirtualAttributeProvider.java opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java opends/src/server/org/opends/server/extensions/PasswordPolicyStateExtendedOperation.java opends/src/server/org/opends/server/extensions/PlainSASLMechanismHandler.java opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java opends/src/server/org/opends/server/extensions/RandomPasswordGenerator.java opends/src/server/org/opends/server/extensions/RedirectingByteChannel.java opends/src/server/org/opends/server/extensions/RegularExpressionIdentityMapper.java opends/src/server/org/opends/server/extensions/RepeatedCharactersPasswordValidator.java opends/src/server/org/opends/server/extensions/SASLByteChannel.java opends/src/server/org/opends/server/extensions/SASLContext.java opends/src/server/org/opends/server/extensions/SASLSecurityProvider.java (deleted) opends/src/server/org/opends/server/extensions/SHA1PasswordStorageScheme.java opends/src/server/org/opends/server/extensions/SMTPAccountStatusNotificationHandler.java opends/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageScheme.java opends/src/server/org/opends/server/extensions/SaltedSHA1PasswordStorageScheme.java opends/src/server/org/opends/server/extensions/SaltedSHA256PasswordStorageScheme.java opends/src/server/org/opends/server/extensions/SaltedSHA384PasswordStorageScheme.java opends/src/server/org/opends/server/extensions/SaltedSHA512PasswordStorageScheme.java opends/src/server/org/opends/server/extensions/SimilarityBasedPasswordValidator.java opends/src/server/org/opends/server/extensions/StartTLSExtendedOperation.java opends/src/server/org/opends/server/extensions/StaticGroup.java opends/src/server/org/opends/server/extensions/SubjectDNToUserAttributeCertificateMapper.java opends/src/server/org/opends/server/extensions/SubschemaSubentryVirtualAttributeProvider.java opends/src/server/org/opends/server/extensions/TLSByteChannel.java opends/src/server/org/opends/server/extensions/TLSCapableConnection.java opends/src/server/org/opends/server/extensions/TLSConnectionSecurityProvider.java (deleted) opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java opends/src/server/org/opends/server/extensions/UniqueCharactersPasswordValidator.java opends/src/server/org/opends/server/extensions/UserAttributeNotificationMessageTemplateElement.java opends/src/server/org/opends/server/extensions/UserDefinedVirtualAttributeProvider.java opends/src/server/org/opends/server/extensions/VirtualStaticGroup.java opends/src/server/org/opends/server/extensions/WhoAmIExtendedOperation.java opends/src/server/org/opends/server/loggers/TextAccessLogPublisher.java opends/src/server/org/opends/server/loggers/TextAuditLogPublisher.java opends/src/server/org/opends/server/loggers/debug/DebugTracer.java opends/src/server/org/opends/server/loggers/debug/TextDebugLogPublisher.java opends/src/server/org/opends/server/loggers/debug/TraceSettings.java opends/src/server/org/opends/server/monitors/BackendMonitor.java opends/src/server/org/opends/server/monitors/ClientConnectionMonitorProvider.java opends/src/server/org/opends/server/monitors/ConnectionHandlerMonitor.java opends/src/server/org/opends/server/monitors/MemoryUsageMonitorProvider.java opends/src/server/org/opends/server/monitors/StackTraceMonitorProvider.java opends/src/server/org/opends/server/monitors/SystemInfoMonitorProvider.java opends/src/server/org/opends/server/monitors/VersionMonitorProvider.java opends/src/server/org/opends/server/plugins/ChangeNumberControlPlugin.java opends/src/server/org/opends/server/plugins/EntryUUIDPlugin.java opends/src/server/org/opends/server/plugins/LastModPlugin.java opends/src/server/org/opends/server/plugins/PasswordPolicyImportPlugin.java opends/src/server/org/opends/server/plugins/ReferentialIntegrityPlugin.java opends/src/server/org/opends/server/plugins/SevenBitCleanPlugin.java opends/src/server/org/opends/server/plugins/UniqueAttributePlugin.java opends/src/server/org/opends/server/plugins/profiler/ProfileStack.java opends/src/server/org/opends/server/plugins/profiler/ProfileViewer.java opends/src/server/org/opends/server/plugins/profiler/ProfilerThread.java opends/src/server/org/opends/server/protocols/asn1/ASN1.java opends/src/server/org/opends/server/protocols/asn1/ASN1Boolean.java (deleted) opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelReader.java opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelWriter.java opends/src/server/org/opends/server/protocols/asn1/ASN1ByteSequenceReader.java opends/src/server/org/opends/server/protocols/asn1/ASN1Element.java (deleted) opends/src/server/org/opends/server/protocols/asn1/ASN1Enumerated.java (deleted) opends/src/server/org/opends/server/protocols/asn1/ASN1InputStreamReader.java opends/src/server/org/opends/server/protocols/asn1/ASN1Integer.java (deleted) opends/src/server/org/opends/server/protocols/asn1/ASN1Long.java (deleted) opends/src/server/org/opends/server/protocols/asn1/ASN1Null.java (deleted) opends/src/server/org/opends/server/protocols/asn1/ASN1OctetString.java (deleted) opends/src/server/org/opends/server/protocols/asn1/ASN1OutputStreamWriter.java opends/src/server/org/opends/server/protocols/asn1/ASN1Reader.java opends/src/server/org/opends/server/protocols/asn1/ASN1Sequence.java (deleted) opends/src/server/org/opends/server/protocols/asn1/ASN1Set.java (deleted) opends/src/server/org/opends/server/protocols/asn1/ASN1Writer.java opends/src/server/org/opends/server/protocols/asn1/ByteSequenceOutputStream.java opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java opends/src/server/org/opends/server/protocols/internal/InternalLDAPInputStream.java opends/src/server/org/opends/server/protocols/internal/InternalLDAPOutputStream.java opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java opends/src/server/org/opends/server/protocols/jmx/RmiAuthenticator.java opends/src/server/org/opends/server/protocols/ldap/AbandonRequestProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/AddRequestProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/AddResponseProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/BindRequestProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/BindResponseProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/CompareRequestProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/CompareResponseProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/DeleteRequestProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/DeleteResponseProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/ExtendedRequestProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/ExtendedResponseProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/IntermediateResponseProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/LDAPAttribute.java opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java opends/src/server/org/opends/server/protocols/ldap/LDAPControl.java opends/src/server/org/opends/server/protocols/ldap/LDAPFilter.java opends/src/server/org/opends/server/protocols/ldap/LDAPMessage.java opends/src/server/org/opends/server/protocols/ldap/LDAPReader.java opends/src/server/org/opends/server/protocols/ldap/LDAPRequestHandler.java opends/src/server/org/opends/server/protocols/ldap/LDAPStatistics.java opends/src/server/org/opends/server/protocols/ldap/ModifyDNRequestProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/ModifyDNResponseProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/ModifyRequestProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/ModifyResponseProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/ProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/SearchRequestProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/SearchResultDoneProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/SearchResultEntryProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/SearchResultReferenceProtocolOp.java opends/src/server/org/opends/server/protocols/ldap/UnbindRequestProtocolOp.java opends/src/server/org/opends/server/replication/common/ServerState.java opends/src/server/org/opends/server/replication/plugin/HistVal.java opends/src/server/org/opends/server/replication/plugin/Historical.java opends/src/server/org/opends/server/replication/plugin/HistoricalCsnOrderingMatchingRule.java opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java opends/src/server/org/opends/server/replication/plugin/PersistentServerState.java opends/src/server/org/opends/server/replication/plugin/ReplicationRepairRequestControl.java opends/src/server/org/opends/server/replication/protocol/AddMsg.java opends/src/server/org/opends/server/replication/protocol/DeleteMsg.java opends/src/server/org/opends/server/replication/protocol/ModifyCommonMsg.java opends/src/server/org/opends/server/replication/protocol/ModifyDNMsg.java opends/src/server/org/opends/server/replication/protocol/ModifyMsg.java opends/src/server/org/opends/server/replication/protocol/MonitorMsg.java opends/src/server/org/opends/server/replication/server/ReplicationBackend.java opends/src/server/org/opends/server/replication/service/ReplicationDomain.java opends/src/server/org/opends/server/replication/service/ReplicationMonitor.java opends/src/server/org/opends/server/schema/AbsoluteSubtreeSpecificationSyntax.java opends/src/server/org/opends/server/schema/AciSyntax.java opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java opends/src/server/org/opends/server/schema/AuthPasswordEqualityMatchingRule.java opends/src/server/org/opends/server/schema/AuthPasswordExactEqualityMatchingRule.java opends/src/server/org/opends/server/schema/AuthPasswordSyntax.java opends/src/server/org/opends/server/schema/BinarySyntax.java opends/src/server/org/opends/server/schema/BitStringEqualityMatchingRule.java opends/src/server/org/opends/server/schema/BitStringSyntax.java opends/src/server/org/opends/server/schema/BooleanEqualityMatchingRule.java opends/src/server/org/opends/server/schema/BooleanSyntax.java opends/src/server/org/opends/server/schema/CaseExactEqualityMatchingRule.java opends/src/server/org/opends/server/schema/CaseExactIA5EqualityMatchingRule.java opends/src/server/org/opends/server/schema/CaseExactIA5SubstringMatchingRule.java opends/src/server/org/opends/server/schema/CaseExactOrderingMatchingRule.java opends/src/server/org/opends/server/schema/CaseExactSubstringMatchingRule.java opends/src/server/org/opends/server/schema/CaseIgnoreEqualityMatchingRule.java opends/src/server/org/opends/server/schema/CaseIgnoreIA5EqualityMatchingRule.java opends/src/server/org/opends/server/schema/CaseIgnoreIA5SubstringMatchingRule.java opends/src/server/org/opends/server/schema/CaseIgnoreListEqualityMatchingRule.java opends/src/server/org/opends/server/schema/CaseIgnoreListSubstringMatchingRule.java opends/src/server/org/opends/server/schema/CaseIgnoreOrderingMatchingRule.java opends/src/server/org/opends/server/schema/CaseIgnoreSubstringMatchingRule.java opends/src/server/org/opends/server/schema/CertificateListSyntax.java opends/src/server/org/opends/server/schema/CertificatePairSyntax.java opends/src/server/org/opends/server/schema/CertificateSyntax.java opends/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java opends/src/server/org/opends/server/schema/CountryStringSyntax.java opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java opends/src/server/org/opends/server/schema/DITStructureRuleSyntax.java opends/src/server/org/opends/server/schema/DeliveryMethodSyntax.java opends/src/server/org/opends/server/schema/DirectoryStringFirstComponentEqualityMatchingRule.java opends/src/server/org/opends/server/schema/DirectoryStringSyntax.java opends/src/server/org/opends/server/schema/DistinguishedNameEqualityMatchingRule.java opends/src/server/org/opends/server/schema/DistinguishedNameSyntax.java opends/src/server/org/opends/server/schema/DoubleMetaphoneApproximateMatchingRule.java opends/src/server/org/opends/server/schema/EnhancedGuideSyntax.java opends/src/server/org/opends/server/schema/FaxNumberSyntax.java opends/src/server/org/opends/server/schema/FaxSyntax.java opends/src/server/org/opends/server/schema/GeneralizedTimeEqualityMatchingRule.java opends/src/server/org/opends/server/schema/GeneralizedTimeOrderingMatchingRule.java opends/src/server/org/opends/server/schema/GeneralizedTimeSyntax.java opends/src/server/org/opends/server/schema/GuideSyntax.java opends/src/server/org/opends/server/schema/IA5StringSyntax.java opends/src/server/org/opends/server/schema/IntegerEqualityMatchingRule.java opends/src/server/org/opends/server/schema/IntegerFirstComponentEqualityMatchingRule.java opends/src/server/org/opends/server/schema/IntegerOrderingMatchingRule.java opends/src/server/org/opends/server/schema/IntegerSyntax.java opends/src/server/org/opends/server/schema/JPEGSyntax.java opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java opends/src/server/org/opends/server/schema/MatchingRuleSyntax.java opends/src/server/org/opends/server/schema/MatchingRuleUseSyntax.java opends/src/server/org/opends/server/schema/NameAndOptionalUIDSyntax.java opends/src/server/org/opends/server/schema/NameFormSyntax.java opends/src/server/org/opends/server/schema/NumericStringEqualityMatchingRule.java opends/src/server/org/opends/server/schema/NumericStringOrderingMatchingRule.java opends/src/server/org/opends/server/schema/NumericStringSubstringMatchingRule.java opends/src/server/org/opends/server/schema/NumericStringSyntax.java opends/src/server/org/opends/server/schema/OIDSyntax.java opends/src/server/org/opends/server/schema/ObjectClassSyntax.java opends/src/server/org/opends/server/schema/ObjectIdentifierEqualityMatchingRule.java opends/src/server/org/opends/server/schema/ObjectIdentifierFirstComponentEqualityMatchingRule.java opends/src/server/org/opends/server/schema/OctetStringEqualityMatchingRule.java opends/src/server/org/opends/server/schema/OctetStringOrderingMatchingRule.java opends/src/server/org/opends/server/schema/OctetStringSubstringMatchingRule.java opends/src/server/org/opends/server/schema/OctetStringSyntax.java opends/src/server/org/opends/server/schema/OtherMailboxSyntax.java opends/src/server/org/opends/server/schema/PostalAddressSyntax.java opends/src/server/org/opends/server/schema/PresentationAddressEqualityMatchingRule.java opends/src/server/org/opends/server/schema/PresentationAddressSyntax.java opends/src/server/org/opends/server/schema/PrintableStringSyntax.java opends/src/server/org/opends/server/schema/ProtocolInformationEqualityMatchingRule.java opends/src/server/org/opends/server/schema/ProtocolInformationSyntax.java opends/src/server/org/opends/server/schema/RFC3672SubtreeSpecificationSyntax.java opends/src/server/org/opends/server/schema/RelativeSubtreeSpecificationSyntax.java opends/src/server/org/opends/server/schema/SubstringAssertionSyntax.java opends/src/server/org/opends/server/schema/SupportedAlgorithmSyntax.java opends/src/server/org/opends/server/schema/TelephoneNumberEqualityMatchingRule.java opends/src/server/org/opends/server/schema/TelephoneNumberSubstringMatchingRule.java opends/src/server/org/opends/server/schema/TelephoneNumberSyntax.java opends/src/server/org/opends/server/schema/TeletexTerminalIdentifierSyntax.java opends/src/server/org/opends/server/schema/TelexNumberSyntax.java opends/src/server/org/opends/server/schema/UTCTimeSyntax.java opends/src/server/org/opends/server/schema/UUIDEqualityMatchingRule.java opends/src/server/org/opends/server/schema/UUIDOrderingMatchingRule.java opends/src/server/org/opends/server/schema/UUIDSyntax.java opends/src/server/org/opends/server/schema/UniqueMemberEqualityMatchingRule.java opends/src/server/org/opends/server/schema/UserPasswordEqualityMatchingRule.java opends/src/server/org/opends/server/schema/UserPasswordExactEqualityMatchingRule.java opends/src/server/org/opends/server/schema/UserPasswordSyntax.java opends/src/server/org/opends/server/schema/WordEqualityMatchingRule.java opends/src/server/org/opends/server/tasks/AddSchemaFileTask.java opends/src/server/org/opends/server/tasks/BackupTask.java opends/src/server/org/opends/server/tasks/DisconnectClientTask.java opends/src/server/org/opends/server/tasks/ShutdownTask.java opends/src/server/org/opends/server/tasks/TaskUtils.java opends/src/server/org/opends/server/tools/BackUpDB.java opends/src/server/org/opends/server/tools/ConsoleDebugLogPublisher.java opends/src/server/org/opends/server/tools/DBTest.java opends/src/server/org/opends/server/tools/EncodePassword.java opends/src/server/org/opends/server/tools/ExportLDIF.java opends/src/server/org/opends/server/tools/ImportLDIF.java opends/src/server/org/opends/server/tools/LDAPAuthenticationHandler.java opends/src/server/org/opends/server/tools/LDAPCompare.java opends/src/server/org/opends/server/tools/LDAPConnection.java opends/src/server/org/opends/server/tools/LDAPDelete.java opends/src/server/org/opends/server/tools/LDAPModify.java opends/src/server/org/opends/server/tools/LDAPPasswordModify.java opends/src/server/org/opends/server/tools/LDAPReader.java opends/src/server/org/opends/server/tools/LDAPSearch.java opends/src/server/org/opends/server/tools/LDAPToolOptions.java opends/src/server/org/opends/server/tools/LDAPToolUtils.java opends/src/server/org/opends/server/tools/LDAPWriter.java opends/src/server/org/opends/server/tools/LDIFDiff.java opends/src/server/org/opends/server/tools/LDIFModify.java opends/src/server/org/opends/server/tools/ManageAccount.java opends/src/server/org/opends/server/tools/RestoreDB.java opends/src/server/org/opends/server/tools/StopDS.java opends/src/server/org/opends/server/tools/VerboseTracer.java (deleted) opends/src/server/org/opends/server/tools/makeldif/Branch.java opends/src/server/org/opends/server/tools/makeldif/TemplateEntry.java opends/src/server/org/opends/server/tools/tasks/TaskClient.java opends/src/server/org/opends/server/tools/tasks/TaskEntry.java opends/src/server/org/opends/server/types/AbstractOperation.java opends/src/server/org/opends/server/types/AccountStatusNotification.java opends/src/server/org/opends/server/types/AttributeBuilder.java opends/src/server/org/opends/server/types/AttributeType.java opends/src/server/org/opends/server/types/AttributeValue.java opends/src/server/org/opends/server/types/AttributeValues.java opends/src/server/org/opends/server/types/Attributes.java opends/src/server/org/opends/server/types/ByteArray.java (deleted) opends/src/server/org/opends/server/types/ByteSequence.java opends/src/server/org/opends/server/types/ByteSequenceReader.java opends/src/server/org/opends/server/types/ByteString.java opends/src/server/org/opends/server/types/ByteStringBuilder.java opends/src/server/org/opends/server/types/ByteStringFactory.java (deleted) opends/src/server/org/opends/server/types/CommonSchemaElements.java opends/src/server/org/opends/server/types/Control.java opends/src/server/org/opends/server/types/CryptoManager.java opends/src/server/org/opends/server/types/DITContentRule.java opends/src/server/org/opends/server/types/DITStructureRule.java opends/src/server/org/opends/server/types/DN.java opends/src/server/org/opends/server/types/Entry.java opends/src/server/org/opends/server/types/EntryEncodeConfig.java opends/src/server/org/opends/server/types/IntermediateResponse.java opends/src/server/org/opends/server/types/MatchingRuleUse.java opends/src/server/org/opends/server/types/NameForm.java opends/src/server/org/opends/server/types/ObjectClass.java opends/src/server/org/opends/server/types/Operation.java opends/src/server/org/opends/server/types/RDN.java opends/src/server/org/opends/server/types/RawAttribute.java opends/src/server/org/opends/server/types/RawFilter.java opends/src/server/org/opends/server/types/RawModification.java opends/src/server/org/opends/server/types/RecordingInputStream.java opends/src/server/org/opends/server/types/RecordingOutputStream.java opends/src/server/org/opends/server/types/Schema.java opends/src/server/org/opends/server/types/SearchFilter.java opends/src/server/org/opends/server/types/operation/PluginOperation.java opends/src/server/org/opends/server/types/operation/PostOperationBindOperation.java opends/src/server/org/opends/server/types/operation/PostOperationExtendedOperation.java opends/src/server/org/opends/server/types/operation/PostResponseAddOperation.java opends/src/server/org/opends/server/types/operation/PostResponseBindOperation.java opends/src/server/org/opends/server/types/operation/PostResponseCompareOperation.java opends/src/server/org/opends/server/types/operation/PostResponseDeleteOperation.java opends/src/server/org/opends/server/types/operation/PostResponseExtendedOperation.java opends/src/server/org/opends/server/types/operation/PostResponseModifyDNOperation.java opends/src/server/org/opends/server/types/operation/PostResponseModifyOperation.java opends/src/server/org/opends/server/types/operation/PostResponseSearchOperation.java opends/src/server/org/opends/server/types/operation/PreOperationBindOperation.java opends/src/server/org/opends/server/types/operation/PreOperationExtendedOperation.java opends/src/server/org/opends/server/types/operation/PreParseAddOperation.java opends/src/server/org/opends/server/types/operation/PreParseBindOperation.java opends/src/server/org/opends/server/types/operation/PreParseCompareOperation.java opends/src/server/org/opends/server/types/operation/PreParseDeleteOperation.java opends/src/server/org/opends/server/types/operation/PreParseExtendedOperation.java opends/src/server/org/opends/server/types/operation/PreParseModifyDNOperation.java opends/src/server/org/opends/server/types/operation/PreParseModifyOperation.java opends/src/server/org/opends/server/types/operation/SearchEntrySearchOperation.java opends/src/server/org/opends/server/types/operation/SearchReferenceSearchOperation.java opends/src/server/org/opends/server/types/operation/SubordinateModifyDNOperation.java opends/src/server/org/opends/server/util/Base64.java opends/src/server/org/opends/server/util/LDIFReader.java opends/src/server/org/opends/server/util/LDIFWriter.java opends/src/server/org/opends/server/util/ServerConstants.java opends/src/server/org/opends/server/util/SizeLimitInputStream.java opends/src/server/org/opends/server/util/StaticUtils.java opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java opends/tests/staf-tests/functional-tests/testcases/aci/aci_targetattr.xml opends/tests/staf-tests/functional-tests/testcases/aci/aci_targetfilter.xml opends/tests/staf-tests/functional-tests/testcases/aci/multiple_aci_tests.xml opends/tests/staf-tests/functional-tests/testcases/dsml/dsml_test.xml opends/tests/staf-tests/functional-tests/testcases/replication/changelog/changelog.xml opends/tests/unit-tests-testng/src/server/org/opends/quicksetup/TestUtilities.java opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java opends/tests/unit-tests-testng/src/server/org/opends/server/admin/RelativeInheritedDefaultBehaviorProviderTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestCfg.java opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DefaultBehaviorTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/api/PasswordValidatorTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/backends/GenericBackendTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaTestMatchingRule.java opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestJebFormat.java opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestRebuildJob.java opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVLVIndex.java opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java opends/tests/unit-tests-testng/src/server/org/opends/server/controls/MatchedValuesControlTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/controls/PasswordControlTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/controls/PasswordPolicyControlTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/controls/PersistentSearchControlTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ProxiedAuthV1ControlTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ProxiedAuthV2ControlTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ServerSideSortControlTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/controls/VLVControlTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/AbandonOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/BindOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/CompareOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/IdleTimeLimitTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/OperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/PluginConfigManagerTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/RejectUnauthReqTests.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/SearchOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowConfigurationTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockClientConnection.java opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AnonymousSASLMechanismHandlerTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AttributeValuePasswordValidatorTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandlerTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CancelExtendedOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CharacterSetPasswordValidatorTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/DictionaryPasswordValidatorTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandlerTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/EntryDNVirtualAttributeProviderTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/EntryUUIDVirtualAttributeProviderTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ExactMatchIdentityMapperTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ExternalSASLMechanismHandlerTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/HasSubordinatesVirtualAttributeProviderTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/InternalConnectionSecurityProviderTestCase.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/LengthBasedPasswordValidatorTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/NullConnectionSecurityProviderTestCase.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/NumSubordinatesVirtualAttributeProviderTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/PasswordModifyExtendedOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/PasswordStorageSchemeTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/PlainSASLMechanismHandlerTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/RepeatedCharactersPasswordValidatorTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedSHA1PasswordStorageSchemeTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SimilarityBasedPasswordValidatorTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SubschemaSubentryVirtualAttributeProviderTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TestPasswordValidator.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/UniqueCharactersPasswordValidatorTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/UserDefinedVirtualAttributeProviderTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/VirtualStaticGroupTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/WhoAmIExtendedOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/monitors/InternalSearchMonitorTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DelayPreOpPlugin.java opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/DisconnectClientPlugin.java opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/EntryUUIDPluginTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/LDAPADListPluginTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/LastModPluginTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/PasswordPolicyImportPluginTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/ReferentialIntegrityPluginTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/ShortCircuitPlugin.java opends/tests/unit-tests-testng/src/server/org/opends/server/plugins/UniqueAttributePluginTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelReaderTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelWriterTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1ByteSequenceReaderTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1InputStreamReaderTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1OutputStreamWriterTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1ReaderTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1WriterTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/SocketReadThread.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/SocketWriteThread.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1Boolean.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1Element.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1Enumerated.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1Exception.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1Integer.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1Long.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1Null.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1OctetString.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1ReaderAndWriter.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1Sequence.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1Set.java (deleted) opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalLDAPSocketTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalSearchOperationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/jmx/JmxPrivilegeTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/LDAPBinaryOptionTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/LDAPv2TestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/LdapTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestAbandonRequestProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestAddRequestProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestAddResponseProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestBindRequestProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestBindResponseProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestCompareRequestProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestCompareResponseProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestDeleteRequestProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestDeleteResponseProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestLDAPFilter.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyDNRequestProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyDNResponseProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyRequestProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestModifyResponseProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestSearchProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestSearchResultEntryProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestUnbindRequestProtocolOp.java opends/tests/unit-tests-testng/src/server/org/opends/server/replication/GenerationIdTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ProtocolWindowTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ReplicationTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/replication/UpdateOperationTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/AssuredReplicationPluginTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/AttrInfoTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/HistoricalCsnOrderingTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/HistoricalTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/ModifyConflictTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/ValueInfoTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ReplicationServerTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/ApproximatematchingRule.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AttributeSyntaxTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AttributeTypeSyntaxTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AuthPasswordEqualityMatchingRuleTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/BitStringSyntaxTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/CollationMatchingRuleTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/ConfigurableAttributeSyntaxTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/EqualLengthApproximateMatchingRule.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/EqualityMatchingRuleTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/OrderingMatchingRuleTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/SubstringMatchingRuleTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/schema/UserPasswordEqualityMatchingRuleTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/DisconnectClientTaskTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/DummyTask.java opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPAuthenticationHandlerTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/AttributeBuilderTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/ByteSequenceReaderTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/ByteSequenceTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/ByteStringBuilderTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/ByteStringTest.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/PrivilegeTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/SearchFilterTests.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAttributeType.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAttributeValue.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestDN.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestRDN.java opends/tests/unit-tests-testng/src/server/org/opends/server/types/VirtualAttributeTestCase.java opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestLDIFReader.java opends/tests/unit-tests-testng/src/server/org/opends/server/util/TestStaticUtils.java