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

Matthew Swift
23.13.2011 3c776d2736d5406718fe310745796c78c8d28547
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/Argument.java
@@ -28,7 +28,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.forgerock.opendj.util.StaticUtils.toLowerCase;
import java.util.Iterator;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ArgumentParser.java
@@ -28,7 +28,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.forgerock.opendj.util.StaticUtils.EOL;
import static com.forgerock.opendj.util.StaticUtils.getBytes;
import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/AuthRate.java
@@ -29,7 +29,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.sun.opends.sdk.tools.ToolConstants.*;
import static com.sun.opends.sdk.tools.Utils.filterExitCode;
@@ -43,11 +43,11 @@
import java.util.concurrent.atomic.AtomicLong;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.BindResult;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.glassfish.grizzly.TransportFactory;
import org.opends.sdk.*;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.BindResult;
import org.opends.sdk.responses.SearchResultEntry;
import com.forgerock.opendj.util.RecursiveFutureResult;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java
@@ -29,9 +29,9 @@
import org.opends.sdk.*;
import org.opends.sdk.requests.BindRequest;
import org.opends.sdk.responses.BindResult;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.BindRequest;
import org.forgerock.opendj.ldap.responses.BindResult;
import com.forgerock.opendj.util.AsynchronousConnectionDecorator;
import com.forgerock.opendj.util.FutureResultTransformer;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/BooleanArgument.java
@@ -28,7 +28,7 @@
import static org.opends.sdk.CoreMessages.ERR_BOOLEANARG_NO_VALUE_ALLOWED;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_BOOLEANARG_NO_VALUE_ALLOWED;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/CLIException.java
@@ -31,7 +31,7 @@
import org.forgerock.i18n.LocalizableException;
import org.forgerock.i18n.LocalizableMessage;
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ConnectionFactoryProvider.java
@@ -29,7 +29,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.sun.opends.sdk.tools.ToolConstants.*;
import java.io.File;
@@ -49,8 +49,8 @@
import javax.net.ssl.X509TrustManager;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.*;
import org.opends.sdk.requests.*;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.*;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ConsoleApplication.java
@@ -28,9 +28,9 @@
import static org.opends.sdk.CoreMessages.INFO_ERROR_EMPTY_RESPONSE;
import static org.opends.sdk.CoreMessages.INFO_MENU_PROMPT_RETURN_TO_CONTINUE;
import static org.opends.sdk.CoreMessages.INFO_PROMPT_SINGLE_DEFAULT;
import static org.forgerock.opendj.ldap.CoreMessages.INFO_ERROR_EMPTY_RESPONSE;
import static org.forgerock.opendj.ldap.CoreMessages.INFO_MENU_PROMPT_RETURN_TO_CONTINUE;
import static org.forgerock.opendj.ldap.CoreMessages.INFO_PROMPT_SINGLE_DEFAULT;
import static com.sun.opends.sdk.tools.Utils.MAX_LINE_WIDTH;
import static com.sun.opends.sdk.tools.Utils.wrapText;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/FileBasedArgument.java
@@ -28,7 +28,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage;
import java.io.BufferedReader;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/IntegerArgument.java
@@ -28,10 +28,10 @@
import static org.opends.sdk.CoreMessages.ERR_ARG_CANNOT_DECODE_AS_INT;
import static org.opends.sdk.CoreMessages.ERR_INTARG_LOWER_BOUND_ABOVE_UPPER_BOUND;
import static org.opends.sdk.CoreMessages.ERR_INTARG_VALUE_ABOVE_UPPER_BOUND;
import static org.opends.sdk.CoreMessages.ERR_INTARG_VALUE_BELOW_LOWER_BOUND;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ARG_CANNOT_DECODE_AS_INT;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_INTARG_LOWER_BOUND_ABOVE_UPPER_BOUND;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_INTARG_VALUE_ABOVE_UPPER_BOUND;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_INTARG_VALUE_BELOW_LOWER_BOUND;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPCompare.java
@@ -29,7 +29,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.sun.opends.sdk.tools.ToolConstants.*;
import static com.sun.opends.sdk.tools.Utils.filterExitCode;
@@ -38,14 +38,14 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.opends.sdk.*;
import org.opends.sdk.controls.AssertionRequestControl;
import org.opends.sdk.controls.Control;
import org.opends.sdk.controls.ProxiedAuthV2RequestControl;
import org.opends.sdk.requests.CompareRequest;
import org.opends.sdk.requests.Requests;
import org.opends.sdk.responses.Responses;
import org.opends.sdk.responses.Result;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.controls.AssertionRequestControl;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.ProxiedAuthV2RequestControl;
import org.forgerock.opendj.ldap.requests.CompareRequest;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import com.forgerock.opendj.util.Base64;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPModify.java
@@ -29,7 +29,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.sun.opends.sdk.tools.ToolConstants.*;
import static com.sun.opends.sdk.tools.Utils.filterExitCode;
@@ -44,15 +44,15 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.opends.sdk.*;
import org.opends.sdk.controls.*;
import org.opends.sdk.ldif.*;
import org.opends.sdk.requests.AddRequest;
import org.opends.sdk.requests.DeleteRequest;
import org.opends.sdk.requests.ModifyDNRequest;
import org.opends.sdk.requests.ModifyRequest;
import org.opends.sdk.responses.Responses;
import org.opends.sdk.responses.Result;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.controls.*;
import org.forgerock.opendj.ldap.requests.AddRequest;
import org.forgerock.opendj.ldap.requests.DeleteRequest;
import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
import org.forgerock.opendj.ldap.requests.ModifyRequest;
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldif.*;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPPasswordModify.java
@@ -29,7 +29,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.sun.opends.sdk.tools.ToolConstants.*;
import static com.sun.opends.sdk.tools.Utils.filterExitCode;
@@ -37,12 +37,12 @@
import java.io.OutputStream;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.*;
import org.opends.sdk.controls.Control;
import org.opends.sdk.requests.PasswordModifyExtendedRequest;
import org.opends.sdk.requests.Requests;
import org.opends.sdk.responses.PasswordModifyExtendedResult;
import org.opends.sdk.responses.Responses;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.requests.PasswordModifyExtendedRequest;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.responses.PasswordModifyExtendedResult;
import org.forgerock.opendj.ldap.responses.Responses;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPSearch.java
@@ -29,7 +29,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.sun.opends.sdk.tools.ToolConstants.*;
import static com.sun.opends.sdk.tools.Utils.filterExitCode;
@@ -38,16 +38,16 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.opends.sdk.*;
import org.opends.sdk.controls.*;
import org.opends.sdk.ldif.EntryWriter;
import org.opends.sdk.ldif.LDIFEntryWriter;
import org.opends.sdk.requests.Requests;
import org.opends.sdk.requests.SearchRequest;
import org.opends.sdk.responses.Responses;
import org.opends.sdk.responses.Result;
import org.opends.sdk.responses.SearchResultEntry;
import org.opends.sdk.responses.SearchResultReference;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.controls.*;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.ldap.responses.SearchResultReference;
import org.forgerock.opendj.ldif.EntryWriter;
import org.forgerock.opendj.ldif.LDIFEntryWriter;
import com.forgerock.opendj.ldap.controls.AccountUsabilityResponseControl;
import com.forgerock.opendj.util.StaticUtils;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ModRate.java
@@ -29,7 +29,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.sun.opends.sdk.tools.ToolConstants.*;
import static com.sun.opends.sdk.tools.Utils.filterExitCode;
@@ -37,11 +37,11 @@
import java.io.OutputStream;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.ModifyRequest;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.responses.Result;
import org.glassfish.grizzly.TransportFactory;
import org.opends.sdk.*;
import org.opends.sdk.requests.ModifyRequest;
import org.opends.sdk.requests.Requests;
import org.opends.sdk.responses.Result;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/MultiChoiceArgument.java
@@ -28,7 +28,7 @@
import static org.opends.sdk.CoreMessages.ERR_MCARG_VALUE_NOT_ALLOWED;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_MCARG_VALUE_NOT_ALLOWED;
import java.util.Collection;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/PerfToolTCPNIOTransportFactory.java
@@ -109,34 +109,34 @@
    selectors = Math.max(2, cpus / 8);
    final String threadsStr = System
        .getProperty("org.opends.sdk.ldap.transport.threads");
        .getProperty("org.forgerock.opendj.ldap.ldap.transport.threads");
    if (threadsStr != null)
    {
      threads = Integer.parseInt(threadsStr);
    }
    final String selectorsStr = System
        .getProperty("org.opends.sdk.ldap.transport.selectors");
        .getProperty("org.forgerock.opendj.ldap.ldap.transport.selectors");
    if (selectorsStr != null)
    {
      selectors = Integer.parseInt(selectorsStr);
    }
    final String lingerStr = System
        .getProperty("org.opends.sdk.ldap.transport.linger");
        .getProperty("org.forgerock.opendj.ldap.ldap.transport.linger");
    if (lingerStr != null)
    {
      linger = Integer.parseInt(lingerStr);
    }
    final String tcpNoDelayStr = System
        .getProperty("org.opends.sdk.ldap.transport.tcpNoDelay");
        .getProperty("org.forgerock.opendj.ldap.ldap.transport.tcpNoDelay");
    if (tcpNoDelayStr != null)
    {
      tcpNoDelay = Integer.parseInt(tcpNoDelayStr) != 0;
    }
    final String reuseAddressStr = System
        .getProperty("org.opends.sdk.ldap.transport.reuseAddress");
        .getProperty("org.forgerock.opendj.ldap.ldap.transport.reuseAddress");
    if (reuseAddressStr != null)
    {
      reuseAddress = Integer.parseInt(reuseAddressStr) != 0;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/PerformanceRunner.java
@@ -39,10 +39,10 @@
import java.util.concurrent.atomic.AtomicReference;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.*;
import org.opends.sdk.responses.BindResult;
import org.opends.sdk.responses.ExtendedResult;
import org.opends.sdk.responses.Result;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.responses.BindResult;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.Result;
import com.forgerock.opendj.util.StaticUtils;
import com.sun.opends.sdk.tools.AuthenticatedConnectionFactory.AuthenticatedAsynchronousConnection;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/PromptingTrustManager.java
@@ -29,7 +29,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import java.io.File;
import java.io.FileInputStream;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/SearchRate.java
@@ -29,7 +29,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.sun.opends.sdk.tools.ToolConstants.*;
import static com.sun.opends.sdk.tools.Utils.filterExitCode;
@@ -41,13 +41,13 @@
import java.util.concurrent.atomic.AtomicInteger;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.ldap.responses.SearchResultReference;
import org.glassfish.grizzly.TransportFactory;
import org.opends.sdk.*;
import org.opends.sdk.requests.Requests;
import org.opends.sdk.requests.SearchRequest;
import org.opends.sdk.responses.Result;
import org.opends.sdk.responses.SearchResultEntry;
import org.opends.sdk.responses.SearchResultReference;
opendj-sdk/opendj3/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/Utils.java
@@ -28,7 +28,7 @@
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import static com.forgerock.opendj.util.StaticUtils.EOL;
import java.io.File;
@@ -37,9 +37,9 @@
import java.util.StringTokenizer;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.*;
import org.opends.sdk.controls.*;
import org.opends.sdk.responses.BindResult;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.controls.*;
import org.forgerock.opendj.ldap.responses.BindResult;
import com.forgerock.opendj.ldap.controls.AccountUsabilityRequestControl;
import com.forgerock.opendj.util.StaticUtils;
@@ -122,7 +122,7 @@
   *          The argument string containing the encoded control information.
   * @return The control decoded from the provided string, or <CODE>null</CODE>
   *         if an error occurs while parsing the argument value.
   * @throws org.opends.sdk.DecodeException
   * @throws org.forgerock.opendj.ldap.DecodeException
   *           If an error occurs.
   */
  static GenericControl getControl(final String argString)
opendj-sdk/opendj3/opendj-sdk/pom.xml
@@ -73,7 +73,7 @@
            </goals>
            <configuration>
              <messageFiles>
                <messageFile>org/opends/sdk/core.properties</messageFile>
                <messageFile>org/forgerock/opendj/ldap/core.properties</messageFile>
              </messageFiles>
            </configuration>
          </execution>
@@ -85,7 +85,7 @@
        <extensions>true</extensions>
        <configuration>
          <instructions>
            <Export-Package>org.opends.sdk.*</Export-Package>
            <Export-Package>org.forgerock.opendj.ldap.*</Export-Package>
          </instructions>
        </configuration>
      </plugin>
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/ASN1BufferReader.java
@@ -30,21 +30,21 @@
import static com.forgerock.opendj.ldap.LDAPConstants.*;
import static org.opends.sdk.CoreMessages.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import java.io.IOException;
import java.util.logging.Level;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.asn1.ASN1Reader;
import org.forgerock.opendj.asn1.AbstractASN1Reader;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.DecodeException;
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.memory.BuffersBuffer;
import org.glassfish.grizzly.memory.CompositeBuffer;
import org.glassfish.grizzly.memory.MemoryManager;
import org.opends.sdk.ByteString;
import org.opends.sdk.ByteStringBuilder;
import org.opends.sdk.DecodeException;
import org.opends.sdk.asn1.ASN1Reader;
import org.opends.sdk.asn1.AbstractASN1Reader;
import com.forgerock.opendj.util.StaticUtils;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/ASN1BufferWriter.java
@@ -28,23 +28,23 @@
import static org.opends.sdk.CoreMessages.ERR_ASN1_SEQUENCE_WRITE_NOT_STARTED;
import static org.opends.sdk.asn1.ASN1Constants.BOOLEAN_VALUE_FALSE;
import static org.opends.sdk.asn1.ASN1Constants.BOOLEAN_VALUE_TRUE;
import static org.forgerock.opendj.asn1.ASN1Constants.BOOLEAN_VALUE_FALSE;
import static org.forgerock.opendj.asn1.ASN1Constants.BOOLEAN_VALUE_TRUE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ASN1_SEQUENCE_WRITE_NOT_STARTED;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.asn1.ASN1Writer;
import org.forgerock.opendj.asn1.AbstractASN1Writer;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.Cacheable;
import org.glassfish.grizzly.ThreadCache;
import org.glassfish.grizzly.memory.ByteBufferWrapper;
import org.opends.sdk.ByteSequence;
import org.opends.sdk.ByteStringBuilder;
import org.opends.sdk.asn1.ASN1Writer;
import org.opends.sdk.asn1.AbstractASN1Writer;
import com.forgerock.opendj.util.StaticUtils;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPFutureResultImpl.java
@@ -29,10 +29,10 @@
import org.opends.sdk.*;
import org.opends.sdk.requests.Requests;
import org.opends.sdk.responses.IntermediateResponse;
import org.opends.sdk.responses.Result;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.responses.IntermediateResponse;
import org.forgerock.opendj.ldap.responses.Result;
import com.forgerock.opendj.util.AsynchronousFutureResult;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPMessageHandler.java
@@ -31,9 +31,9 @@
import java.io.IOException;
import org.opends.sdk.ByteString;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/InternalConnection.java
@@ -33,9 +33,9 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import org.opends.sdk.*;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import com.forgerock.opendj.util.CompletedFutureResult;
import com.forgerock.opendj.util.Validator;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPBindFutureResultImpl.java
@@ -29,13 +29,13 @@
import org.opends.sdk.AsynchronousConnection;
import org.opends.sdk.IntermediateResponseHandler;
import org.opends.sdk.ResultCode;
import org.opends.sdk.ResultHandler;
import org.opends.sdk.requests.BindClient;
import org.opends.sdk.responses.BindResult;
import org.opends.sdk.responses.Responses;
import org.forgerock.opendj.ldap.AsynchronousConnection;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.ResultHandler;
import org.forgerock.opendj.ldap.requests.BindClient;
import org.forgerock.opendj.ldap.responses.BindResult;
import org.forgerock.opendj.ldap.responses.Responses;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPClientFilter.java
@@ -36,6 +36,12 @@
import javax.net.ssl.SSLEngine;
import org.forgerock.opendj.ldap.ConnectionSecurityLayer;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.EmptyCompletionHandler;
@@ -44,12 +50,6 @@
import org.glassfish.grizzly.filterchain.BaseFilter;
import org.glassfish.grizzly.filterchain.FilterChainContext;
import org.glassfish.grizzly.filterchain.NextAction;
import org.opends.sdk.ConnectionSecurityLayer;
import org.opends.sdk.DecodeException;
import org.opends.sdk.ErrorResultException;
import org.opends.sdk.ResultCode;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPCompareFutureResultImpl.java
@@ -29,13 +29,13 @@
import org.opends.sdk.AsynchronousConnection;
import org.opends.sdk.IntermediateResponseHandler;
import org.opends.sdk.ResultCode;
import org.opends.sdk.ResultHandler;
import org.opends.sdk.requests.CompareRequest;
import org.opends.sdk.responses.CompareResult;
import org.opends.sdk.responses.Responses;
import org.forgerock.opendj.ldap.AsynchronousConnection;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.ResultHandler;
import org.forgerock.opendj.ldap.requests.CompareRequest;
import org.forgerock.opendj.ldap.responses.CompareResult;
import org.forgerock.opendj.ldap.responses.Responses;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java
@@ -41,15 +41,15 @@
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import org.glassfish.grizzly.CompletionHandler;
import org.glassfish.grizzly.filterchain.DefaultFilterChain;
import org.glassfish.grizzly.filterchain.Filter;
import org.glassfish.grizzly.filterchain.FilterChain;
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
import org.glassfish.grizzly.ssl.SSLFilter;
import org.opends.sdk.*;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
import com.forgerock.opendj.util.CompletedFutureResult;
import com.forgerock.opendj.util.StaticUtils;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
@@ -35,6 +35,12 @@
import javax.net.ssl.SSLEngine;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.StartTLSExtendedRequest;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.glassfish.grizzly.CompletionHandler;
import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.EmptyCompletionHandler;
@@ -42,12 +48,6 @@
import org.glassfish.grizzly.filterchain.FilterChain;
import org.glassfish.grizzly.filterchain.TransportFilter;
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
import org.opends.sdk.*;
import org.opends.sdk.requests.Requests;
import org.opends.sdk.requests.StartTLSExtendedRequest;
import org.opends.sdk.responses.ExtendedResult;
import org.opends.sdk.responses.Responses;
import org.opends.sdk.responses.Result;
import com.forgerock.opendj.util.CompletedFutureResult;
import com.forgerock.opendj.util.FutureResultTransformer;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPExtendedFutureResultImpl.java
@@ -29,10 +29,10 @@
import org.opends.sdk.*;
import org.opends.sdk.requests.ExtendedRequest;
import org.opends.sdk.requests.StartTLSExtendedRequest;
import org.opends.sdk.responses.ExtendedResult;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
import org.forgerock.opendj.ldap.requests.StartTLSExtendedRequest;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPFutureResultImpl.java
@@ -29,13 +29,13 @@
import org.opends.sdk.AsynchronousConnection;
import org.opends.sdk.IntermediateResponseHandler;
import org.opends.sdk.ResultCode;
import org.opends.sdk.ResultHandler;
import org.opends.sdk.requests.Request;
import org.opends.sdk.responses.Responses;
import org.opends.sdk.responses.Result;
import org.forgerock.opendj.ldap.AsynchronousConnection;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.ResultHandler;
import org.forgerock.opendj.ldap.requests.Request;
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPListenerImpl.java
@@ -36,6 +36,10 @@
import javax.net.ssl.SSLContext;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.LDAPClientContext;
import org.forgerock.opendj.ldap.LDAPListenerOptions;
import org.forgerock.opendj.ldap.ServerConnectionFactory;
import org.glassfish.grizzly.filterchain.DefaultFilterChain;
import org.glassfish.grizzly.filterchain.FilterChain;
import org.glassfish.grizzly.filterchain.TransportFilter;
@@ -43,10 +47,6 @@
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
import org.glassfish.grizzly.ssl.SSLFilter;
import org.opends.sdk.DecodeOptions;
import org.opends.sdk.LDAPClientContext;
import org.opends.sdk.LDAPListenerOptions;
import org.opends.sdk.ServerConnectionFactory;
import com.forgerock.opendj.util.StaticUtils;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPMessageHandler.java
@@ -31,9 +31,9 @@
import java.io.IOException;
import org.opends.sdk.ByteString;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPReader.java
@@ -30,23 +30,23 @@
import static com.forgerock.opendj.ldap.LDAPConstants.*;
import static org.opends.sdk.CoreMessages.ERR_LDAP_MODIFICATION_DECODE_INVALID_MOD_TYPE;
import static org.opends.sdk.CoreMessages.ERR_LDAP_SEARCH_REQUEST_DECODE_INVALID_DEREF;
import static org.opends.sdk.CoreMessages.ERR_LDAP_SEARCH_REQUEST_DECODE_INVALID_SCOPE;
import static org.opends.sdk.asn1.ASN1Constants.UNIVERSAL_BOOLEAN_TYPE;
import static org.opends.sdk.asn1.ASN1Constants.UNIVERSAL_OCTET_STRING_TYPE;
import static org.forgerock.opendj.asn1.ASN1Constants.UNIVERSAL_BOOLEAN_TYPE;
import static org.forgerock.opendj.asn1.ASN1Constants.UNIVERSAL_OCTET_STRING_TYPE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_LDAP_MODIFICATION_DECODE_INVALID_MOD_TYPE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_LDAP_SEARCH_REQUEST_DECODE_INVALID_DEREF;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_LDAP_SEARCH_REQUEST_DECODE_INVALID_SCOPE;
import java.io.IOException;
import java.util.logging.Level;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.opends.sdk.*;
import org.opends.sdk.asn1.ASN1Reader;
import org.opends.sdk.controls.Control;
import org.opends.sdk.controls.GenericControl;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
import org.opends.sdk.schema.Schema;
import org.forgerock.opendj.asn1.ASN1Reader;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.GenericControl;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import org.forgerock.opendj.ldap.schema.Schema;
import com.forgerock.opendj.util.StaticUtils;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPSearchFutureResultImpl.java
@@ -29,15 +29,15 @@
import org.opends.sdk.AsynchronousConnection;
import org.opends.sdk.IntermediateResponseHandler;
import org.opends.sdk.ResultCode;
import org.opends.sdk.SearchResultHandler;
import org.opends.sdk.requests.SearchRequest;
import org.opends.sdk.responses.Responses;
import org.opends.sdk.responses.Result;
import org.opends.sdk.responses.SearchResultEntry;
import org.opends.sdk.responses.SearchResultReference;
import org.forgerock.opendj.ldap.AsynchronousConnection;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchResultHandler;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.ldap.responses.SearchResultReference;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPServerFilter.java
@@ -39,6 +39,10 @@
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.Grizzly;
@@ -47,10 +51,6 @@
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
import org.glassfish.grizzly.ssl.SSLFilter;
import org.glassfish.grizzly.ssl.SSLUtils;
import org.opends.sdk.*;
import org.opends.sdk.controls.Control;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
import com.forgerock.opendj.util.StaticUtils;
import com.forgerock.opendj.util.Validator;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPUtils.java
@@ -36,10 +36,10 @@
import java.util.LinkedList;
import java.util.List;
import org.opends.sdk.*;
import org.opends.sdk.asn1.ASN1Reader;
import org.opends.sdk.asn1.ASN1Writer;
import org.opends.sdk.responses.SearchResultEntry;
import org.forgerock.opendj.asn1.ASN1Reader;
import org.forgerock.opendj.asn1.ASN1Writer;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPWriter.java
@@ -35,14 +35,14 @@
import java.util.List;
import java.util.logging.Level;
import org.opends.sdk.Attribute;
import org.opends.sdk.ByteString;
import org.opends.sdk.DN;
import org.opends.sdk.Modification;
import org.opends.sdk.asn1.ASN1Writer;
import org.opends.sdk.controls.Control;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
import org.forgerock.opendj.asn1.ASN1Writer;
import org.forgerock.opendj.ldap.Attribute;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.Modification;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import com.forgerock.opendj.util.StaticUtils;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/SASLDecoderTransformer.java
@@ -29,6 +29,8 @@
import org.forgerock.opendj.ldap.ConnectionSecurityLayer;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.glassfish.grizzly.AbstractTransformer;
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.TransformationException;
@@ -36,8 +38,6 @@
import org.glassfish.grizzly.attributes.AttributeStorage;
import org.glassfish.grizzly.memory.Buffers;
import org.glassfish.grizzly.memory.MemoryManager;
import org.opends.sdk.ConnectionSecurityLayer;
import org.opends.sdk.ErrorResultException;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/SASLEncoderTransformer.java
@@ -29,6 +29,8 @@
import org.forgerock.opendj.ldap.ConnectionSecurityLayer;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.glassfish.grizzly.AbstractTransformer;
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.TransformationException;
@@ -36,8 +38,6 @@
import org.glassfish.grizzly.attributes.AttributeStorage;
import org.glassfish.grizzly.memory.Buffers;
import org.glassfish.grizzly.memory.MemoryManager;
import org.opends.sdk.ConnectionSecurityLayer;
import org.opends.sdk.ErrorResultException;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/SASLFilter.java
@@ -29,10 +29,10 @@
import org.forgerock.opendj.ldap.ConnectionSecurityLayer;
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.filterchain.AbstractCodecFilter;
import org.glassfish.grizzly.memory.MemoryManager;
import org.opends.sdk.ConnectionSecurityLayer;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/UnexpectedRequestException.java
@@ -32,7 +32,7 @@
import java.io.IOException;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.requests.Request;
import org.forgerock.opendj.ldap.requests.Request;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/UnexpectedResponseException.java
@@ -32,7 +32,7 @@
import java.io.IOException;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.responses.Response;
import org.forgerock.opendj.ldap.responses.Response;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/UnsupportedMessageException.java
@@ -32,7 +32,7 @@
import java.io.IOException;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.ByteString;
import org.forgerock.opendj.ldap.ByteString;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/controls/AccountUsabilityRequestControl.java
@@ -28,15 +28,15 @@
import static org.opends.sdk.CoreMessages.ERR_ACCTUSABLEREQ_CONTROL_BAD_OID;
import static org.opends.sdk.CoreMessages.ERR_ACCTUSABLEREQ_CONTROL_HAS_VALUE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ACCTUSABLEREQ_CONTROL_BAD_OID;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ACCTUSABLEREQ_CONTROL_HAS_VALUE;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.ByteString;
import org.opends.sdk.DecodeException;
import org.opends.sdk.DecodeOptions;
import org.opends.sdk.controls.Control;
import org.opends.sdk.controls.ControlDecoder;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.ControlDecoder;
import com.forgerock.opendj.util.Validator;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/controls/AccountUsabilityResponseControl.java
@@ -30,23 +30,23 @@
import static com.forgerock.opendj.util.StaticUtils.byteToHex;
import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage;
import static org.opends.sdk.CoreMessages.ERR_ACCTUSABLERES_CONTROL_BAD_OID;
import static org.opends.sdk.CoreMessages.ERR_ACCTUSABLERES_DECODE_ERROR;
import static org.opends.sdk.CoreMessages.ERR_ACCTUSABLERES_NO_CONTROL_VALUE;
import static org.opends.sdk.CoreMessages.ERR_ACCTUSABLERES_UNKNOWN_VALUE_ELEMENT_TYPE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ACCTUSABLERES_CONTROL_BAD_OID;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ACCTUSABLERES_DECODE_ERROR;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ACCTUSABLERES_NO_CONTROL_VALUE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ACCTUSABLERES_UNKNOWN_VALUE_ELEMENT_TYPE;
import java.io.IOException;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.ByteString;
import org.opends.sdk.ByteStringBuilder;
import org.opends.sdk.DecodeException;
import org.opends.sdk.DecodeOptions;
import org.opends.sdk.asn1.ASN1;
import org.opends.sdk.asn1.ASN1Reader;
import org.opends.sdk.asn1.ASN1Writer;
import org.opends.sdk.controls.Control;
import org.opends.sdk.controls.ControlDecoder;
import org.forgerock.opendj.asn1.ASN1;
import org.forgerock.opendj.asn1.ASN1Reader;
import org.forgerock.opendj.asn1.ASN1Writer;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.ControlDecoder;
import com.forgerock.opendj.util.StaticUtils;
import com.forgerock.opendj.util.Validator;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/controls/RealAttributesOnlyRequestControl.java
@@ -28,15 +28,15 @@
import static org.opends.sdk.CoreMessages.ERR_REAL_ATTRS_ONLY_CONTROL_BAD_OID;
import static org.opends.sdk.CoreMessages.ERR_REAL_ATTRS_ONLY_INVALID_CONTROL_VALUE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_REAL_ATTRS_ONLY_CONTROL_BAD_OID;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_REAL_ATTRS_ONLY_INVALID_CONTROL_VALUE;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.ByteString;
import org.opends.sdk.DecodeException;
import org.opends.sdk.DecodeOptions;
import org.opends.sdk.controls.Control;
import org.opends.sdk.controls.ControlDecoder;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.ControlDecoder;
import com.forgerock.opendj.util.Validator;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/controls/VirtualAttributesOnlyRequestControl.java
@@ -28,15 +28,15 @@
import static org.opends.sdk.CoreMessages.ERR_VIRTUAL_ATTRS_ONLY_CONTROL_BAD_OID;
import static org.opends.sdk.CoreMessages.ERR_VIRTUAL_ATTRS_ONLY_INVALID_CONTROL_VALUE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_VIRTUAL_ATTRS_ONLY_CONTROL_BAD_OID;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_VIRTUAL_ATTRS_ONLY_INVALID_CONTROL_VALUE;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.ByteString;
import org.opends.sdk.DecodeException;
import org.opends.sdk.DecodeOptions;
import org.opends.sdk.controls.Control;
import org.opends.sdk.controls.ControlDecoder;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.ControlDecoder;
import com.forgerock.opendj.util.Validator;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/extensions/GetConnectionIDExtendedRequest.java
@@ -32,19 +32,19 @@
import java.io.IOException;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.ByteString;
import org.opends.sdk.DecodeException;
import org.opends.sdk.DecodeOptions;
import org.opends.sdk.ResultCode;
import org.opends.sdk.asn1.ASN1;
import org.opends.sdk.asn1.ASN1Reader;
import org.opends.sdk.controls.Control;
import org.opends.sdk.requests.AbstractExtendedRequest;
import org.opends.sdk.requests.ExtendedRequest;
import org.opends.sdk.requests.ExtendedRequestDecoder;
import org.opends.sdk.responses.AbstractExtendedResultDecoder;
import org.opends.sdk.responses.ExtendedResult;
import org.opends.sdk.responses.ExtendedResultDecoder;
import org.forgerock.opendj.asn1.ASN1;
import org.forgerock.opendj.asn1.ASN1Reader;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.requests.AbstractExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequestDecoder;
import org.forgerock.opendj.ldap.responses.AbstractExtendedResultDecoder;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.ExtendedResultDecoder;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/extensions/GetConnectionIDExtendedResult.java
@@ -31,12 +31,12 @@
import java.io.IOException;
import org.opends.sdk.ByteString;
import org.opends.sdk.ByteStringBuilder;
import org.opends.sdk.ResultCode;
import org.opends.sdk.asn1.ASN1;
import org.opends.sdk.asn1.ASN1Writer;
import org.opends.sdk.responses.AbstractExtendedResult;
import org.forgerock.opendj.asn1.ASN1;
import org.forgerock.opendj.asn1.ASN1Writer;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.responses.AbstractExtendedResult;
import com.forgerock.opendj.util.Validator;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/extensions/GetSymmetricKeyExtendedRequest.java
@@ -29,24 +29,24 @@
import static org.opends.sdk.CoreMessages.ERR_GET_SYMMETRIC_KEY_ASN1_DECODE_EXCEPTION;
import static org.opends.sdk.CoreMessages.ERR_GET_SYMMETRIC_KEY_NO_VALUE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_GET_SYMMETRIC_KEY_ASN1_DECODE_EXCEPTION;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_GET_SYMMETRIC_KEY_NO_VALUE;
import java.io.IOException;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.*;
import org.opends.sdk.asn1.ASN1;
import org.opends.sdk.asn1.ASN1Reader;
import org.opends.sdk.asn1.ASN1Writer;
import org.opends.sdk.controls.Control;
import org.opends.sdk.requests.AbstractExtendedRequest;
import org.opends.sdk.requests.ExtendedRequest;
import org.opends.sdk.requests.ExtendedRequestDecoder;
import org.opends.sdk.responses.AbstractExtendedResultDecoder;
import org.opends.sdk.responses.ExtendedResult;
import org.opends.sdk.responses.ExtendedResultDecoder;
import org.opends.sdk.responses.Responses;
import org.forgerock.opendj.asn1.ASN1;
import org.forgerock.opendj.asn1.ASN1Reader;
import org.forgerock.opendj.asn1.ASN1Writer;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.requests.AbstractExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequestDecoder;
import org.forgerock.opendj.ldap.responses.AbstractExtendedResultDecoder;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.ExtendedResultDecoder;
import org.forgerock.opendj.ldap.responses.Responses;
import com.forgerock.opendj.util.StaticUtils;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateExtendedRequest.java
@@ -31,9 +31,9 @@
import static com.forgerock.opendj.util.StaticUtils.formatAsGeneralizedTime;
import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage;
import static org.opends.sdk.CoreMessages.ERR_PWPSTATE_EXTOP_DECODE_FAILURE;
import static org.opends.sdk.CoreMessages.ERR_PWPSTATE_EXTOP_NO_REQUEST_VALUE;
import static org.opends.sdk.CoreMessages.ERR_PWPSTATE_EXTOP_UNKNOWN_OP_TYPE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_PWPSTATE_EXTOP_DECODE_FAILURE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_PWPSTATE_EXTOP_NO_REQUEST_VALUE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_PWPSTATE_EXTOP_UNKNOWN_OP_TYPE;
import java.io.IOException;
import java.util.ArrayList;
@@ -42,17 +42,17 @@
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.sdk.*;
import org.opends.sdk.asn1.ASN1;
import org.opends.sdk.asn1.ASN1Reader;
import org.opends.sdk.asn1.ASN1Writer;
import org.opends.sdk.controls.Control;
import org.opends.sdk.requests.AbstractExtendedRequest;
import org.opends.sdk.requests.ExtendedRequest;
import org.opends.sdk.requests.ExtendedRequestDecoder;
import org.opends.sdk.responses.AbstractExtendedResultDecoder;
import org.opends.sdk.responses.ExtendedResult;
import org.opends.sdk.responses.ExtendedResultDecoder;
import org.forgerock.opendj.asn1.ASN1;
import org.forgerock.opendj.asn1.ASN1Reader;
import org.forgerock.opendj.asn1.ASN1Writer;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.requests.AbstractExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequestDecoder;
import org.forgerock.opendj.ldap.responses.AbstractExtendedResultDecoder;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.ExtendedResultDecoder;
import com.forgerock.opendj.util.Validator;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateExtendedResult.java
@@ -32,10 +32,10 @@
import java.util.ArrayList;
import java.util.List;
import org.opends.sdk.ByteString;
import org.opends.sdk.DN;
import org.opends.sdk.ResultCode;
import org.opends.sdk.responses.AbstractExtendedResult;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.responses.AbstractExtendedResult;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateOperation.java
@@ -29,7 +29,7 @@
import org.opends.sdk.ByteString;
import org.forgerock.opendj.ldap.ByteString;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateOperationType.java
@@ -29,7 +29,7 @@
import org.opends.sdk.ByteString;
import org.forgerock.opendj.ldap.ByteString;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/util/AsynchronousConnectionDecorator.java
@@ -31,10 +31,10 @@
import java.util.Collection;
import org.opends.sdk.*;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
import org.opends.sdk.schema.Schema;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import org.forgerock.opendj.ldap.schema.Schema;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/util/AsynchronousFutureResult.java
@@ -33,9 +33,9 @@
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import org.opends.sdk.*;
import org.opends.sdk.responses.Responses;
import org.opends.sdk.responses.Result;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/util/Base64.java
@@ -29,14 +29,14 @@
import static com.forgerock.opendj.util.Validator.ensureNotNull;
import static org.opends.sdk.CoreMessages.ERR_BASE64_DECODE_INVALID_CHARACTER;
import static org.opends.sdk.CoreMessages.ERR_BASE64_DECODE_INVALID_LENGTH;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_BASE64_DECODE_INVALID_CHARACTER;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_BASE64_DECODE_INVALID_LENGTH;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.opends.sdk.ByteSequence;
import org.opends.sdk.ByteString;
import org.opends.sdk.ByteStringBuilder;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/util/ByteSequenceOutputStream.java
@@ -31,7 +31,7 @@
import java.io.IOException;
import java.io.OutputStream;
import org.opends.sdk.ByteStringBuilder;
import org.forgerock.opendj.ldap.ByteStringBuilder;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/util/CompletedFutureResult.java
@@ -32,8 +32,8 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.opends.sdk.ErrorResultException;
import org.opends.sdk.FutureResult;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.FutureResult;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/util/Functions.java
@@ -29,10 +29,10 @@
import org.opends.sdk.AttributeDescription;
import org.opends.sdk.ByteString;
import org.opends.sdk.DN;
import org.opends.sdk.schema.Schema;
import org.forgerock.opendj.ldap.AttributeDescription;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.schema.Schema;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/util/FutureResultTransformer.java
@@ -32,9 +32,9 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.opends.sdk.ErrorResultException;
import org.opends.sdk.FutureResult;
import org.opends.sdk.ResultHandler;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.FutureResult;
import org.forgerock.opendj.ldap.ResultHandler;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/util/RecursiveFutureResult.java
@@ -33,9 +33,9 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.opends.sdk.ErrorResultException;
import org.opends.sdk.FutureResult;
import org.opends.sdk.ResultHandler;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.FutureResult;
import org.forgerock.opendj.ldap.ResultHandler;
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java
@@ -29,8 +29,8 @@
import static org.opends.sdk.CoreMessages.ERR_HEX_DECODE_INVALID_CHARACTER;
import static org.opends.sdk.CoreMessages.ERR_HEX_DECODE_INVALID_LENGTH;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_HEX_DECODE_INVALID_CHARACTER;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_HEX_DECODE_INVALID_LENGTH;
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
@@ -48,8 +48,8 @@
import org.forgerock.i18n.LocalizableException;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
import org.opends.sdk.ByteSequence;
import org.opends.sdk.ByteStringBuilder;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteStringBuilder;
@@ -61,7 +61,7 @@
  /**
   * The debug logger which should be used by the SDK.
   */
  public static final Logger DEBUG_LOG = Logger.getLogger("org.opends.sdk");
  public static final Logger DEBUG_LOG = Logger.getLogger("org.forgerock.opendj.ldap");
  /**
   * The end-of-line character for this platform.
opendj-sdk/opendj3/opendj-sdk/src/main/java/com/forgerock/opendj/util/StringPrepProfile.java
@@ -35,7 +35,7 @@
import java.util.HashMap;
import java.util.HashSet;
import org.opends.sdk.ByteSequence;
import org.forgerock.opendj.ldap.ByteSequence;
@@ -470,7 +470,7 @@
   *          The buffer to which the prepared form of the string should be
   *          appended.
   * @param sequence
   *          The {@link org.opends.sdk.ByteSequence} that needs preparation.
   *          The {@link org.forgerock.opendj.ldap.ByteSequence} that needs preparation.
   * @param trim
   *          Indicates whether leading and trailing spaces should be omitted
   *          from the string representation.
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1.java
New file
@@ -0,0 +1,226 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.asn1;
import java.io.InputStream;
import java.io.OutputStream;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteSequenceReader;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import com.forgerock.opendj.util.ByteSequenceOutputStream;
/**
 * This class contains various static factory methods for creating ASN.1 readers
 * and writers.
 *
 * @see ASN1Reader
 * @see ASN1Writer
 */
public final class ASN1
{
  /**
   * Returns an ASN.1 reader whose source is the provided byte array and having
   * an unlimited maximum BER element size.
   *
   * @param array
   *          The byte array to use.
   * @return The new ASN.1 reader.
   */
  public static ASN1Reader getReader(final byte[] array)
  {
    return getReader(array, 0);
  }
  /**
   * Returns an ASN.1 reader whose source is the provided byte array and having
   * a user defined maximum BER element size.
   *
   * @param array
   *          The byte array to use.
   * @param maxElementSize
   *          The maximum BER element size, or {@code 0} to indicate that there
   *          is no limit.
   * @return The new ASN.1 reader.
   */
  public static ASN1Reader getReader(final byte[] array,
      final int maxElementSize)
  {
    return getReader(ByteString.wrap(array), maxElementSize);
  }
  /**
   * Returns an ASN.1 reader whose source is the provided byte sequence and
   * having an unlimited maximum BER element size.
   *
   * @param sequence
   *          The byte sequence to use.
   * @return The new ASN.1 reader.
   */
  public static ASN1Reader getReader(final ByteSequence sequence)
  {
    return getReader(sequence, 0);
  }
  /**
   * Returns an ASN.1 reader whose source is the provided byte sequence and
   * having a user defined maximum BER element size.
   *
   * @param sequence
   *          The byte sequence to use.
   * @param maxElementSize
   *          The maximum BER element size, or {@code 0} to indicate that there
   *          is no limit.
   * @return The new ASN.1 reader.
   */
  public static ASN1Reader getReader(final ByteSequence sequence,
      final int maxElementSize)
  {
    return new ASN1ByteSequenceReader(sequence.asReader(), maxElementSize);
  }
  /**
   * Returns an ASN.1 reader whose source is the provided byte sequence reader
   * and having an unlimited maximum BER element size.
   *
   * @param reader
   *          The byte sequence reader to use.
   * @return The new ASN.1 reader.
   */
  public static ASN1Reader getReader(final ByteSequenceReader reader)
  {
    return getReader(reader, 0);
  }
  /**
   * Returns an ASN.1 reader whose source is the provided byte sequence reader
   * and having a user defined maximum BER element size.
   *
   * @param reader
   *          The byte sequence reader to use.
   * @param maxElementSize
   *          The maximum BER element size, or {@code 0} to indicate that there
   *          is no limit.
   * @return The new ASN.1 reader.
   */
  public static ASN1Reader getReader(final ByteSequenceReader reader,
      final int maxElementSize)
  {
    return new ASN1ByteSequenceReader(reader, maxElementSize);
  }
  /**
   * Returns an ASN.1 reader whose source is the provided input stream and
   * having an unlimited maximum BER element size.
   *
   * @param stream
   *          The input stream to use.
   * @return The new ASN.1 reader.
   */
  public static ASN1Reader getReader(final InputStream stream)
  {
    return getReader(stream, 0);
  }
  /**
   * Returns an ASN.1 reader whose source is the provided input stream and
   * having a user defined maximum BER element size.
   *
   * @param stream
   *          The input stream to use.
   * @param maxElementSize
   *          The maximum BER element size, or {@code 0} to indicate that there
   *          is no limit.
   * @return The new ASN.1 reader.
   */
  public static ASN1Reader getReader(final InputStream stream,
      final int maxElementSize)
  {
    return new ASN1InputStreamReader(stream, maxElementSize);
  }
  /**
   * Returns an ASN.1 writer whose destination is the provided byte string
   * builder.
   *
   * @param builder
   *          The byte string builder to use.
   * @return The new ASN.1 writer.
   */
  public static ASN1Writer getWriter(final ByteStringBuilder builder)
  {
    final ByteSequenceOutputStream outputStream = new ByteSequenceOutputStream(
        builder);
    return getWriter(outputStream);
  }
  /**
   * Returns an ASN.1 writer whose destination is the provided output stream.
   *
   * @param stream
   *          The output stream to use.
   * @return The new ASN.1 writer.
   */
  public static ASN1Writer getWriter(final OutputStream stream)
  {
    return new ASN1OutputStreamWriter(stream);
  }
  // Prevent instantiation.
  private ASN1()
  {
    // Nothing to do.
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1ByteSequenceReader.java
New file
@@ -0,0 +1,566 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.asn1;
import static org.forgerock.opendj.asn1.ASN1Constants.ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE;
import static org.forgerock.opendj.asn1.ASN1Constants.ELEMENT_READ_STATE_NEED_TYPE;
import static org.forgerock.opendj.asn1.ASN1Constants.ELEMENT_READ_STATE_NEED_VALUE_BYTES;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import java.io.IOException;
import java.util.LinkedList;
import java.util.logging.Level;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteSequenceReader;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.DecodeException;
import com.forgerock.opendj.util.StaticUtils;
/**
 * An ASN.1 reader that reads from a {@link ByteSequenceReader}.
 */
final class ASN1ByteSequenceReader extends AbstractASN1Reader implements
    ASN1Reader
{
  private int state = ELEMENT_READ_STATE_NEED_TYPE;
  private byte peekType = 0;
  private int peekLength = -1;
  private final int maxElementSize;
  private ByteSequenceReader reader;
  private final LinkedList<ByteSequenceReader> readerStack;
  /**
   * Creates a new ASN1 reader whose source is the provided byte sequence reader
   * and having a user defined maximum BER element size.
   *
   * @param reader
   *          The byte sequence reader to be read.
   * @param maxElementSize
   *          The maximum BER element size, or <code>0</code> to indicate that
   *          there is no limit.
   */
  ASN1ByteSequenceReader(final ByteSequenceReader reader,
      final int maxElementSize)
  {
    this.reader = reader;
    this.readerStack = new LinkedList<ByteSequenceReader>();
    this.maxElementSize = maxElementSize;
  }
  /**
   * {@inheritDoc}
   */
  public void close() throws IOException
  {
    readerStack.clear();
  }
  /**
   * {@inheritDoc}
   */
  public boolean elementAvailable() throws IOException
  {
    if ((state == ELEMENT_READ_STATE_NEED_TYPE) && !needTypeState(false))
    {
      return false;
    }
    if ((state == ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE)
        && !needFirstLengthByteState(false))
    {
      return false;
    }
    return peekLength <= reader.remaining();
  }
  /**
   * {@inheritDoc}
   */
  public boolean hasNextElement() throws IOException
  {
    return (state != ELEMENT_READ_STATE_NEED_TYPE) || needTypeState(false);
  }
  /**
   * {@inheritDoc}
   */
  public int peekLength() throws IOException
  {
    peekType();
    if (state == ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE)
    {
      needFirstLengthByteState(true);
    }
    return peekLength;
  }
  /**
   * {@inheritDoc}
   */
  public byte peekType() throws IOException
  {
    if (state == ELEMENT_READ_STATE_NEED_TYPE)
    {
      // Read just the type.
      if (reader.remaining() <= 0)
      {
        final LocalizableMessage message = ERR_ASN1_TRUCATED_TYPE_BYTE.get();
        throw DecodeException.fatalError(message);
      }
      final int type = reader.get();
      peekType = (byte) type;
      state = ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE;
    }
    return peekType;
  }
  /**
   * {@inheritDoc}
   */
  public boolean readBoolean() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if (peekLength != 1)
    {
      final LocalizableMessage message = ERR_ASN1_BOOLEAN_INVALID_LENGTH
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    if (reader.remaining() < peekLength)
    {
      final LocalizableMessage message = ERR_ASN1_BOOLEAN_TRUNCATED_VALUE
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    final int readByte = reader.get();
    state = ELEMENT_READ_STATE_NEED_TYPE;
    return readByte != 0x00;
  }
  /**
   * {@inheritDoc}
   */
  public void readEndSequence() throws IOException, IllegalStateException
  {
    if (readerStack.isEmpty())
    {
      final LocalizableMessage message = ERR_ASN1_SEQUENCE_READ_NOT_STARTED
          .get();
      throw new IllegalStateException(message.toString());
    }
    if ((reader.remaining() > 0)
        && StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
    {
      StaticUtils.DEBUG_LOG.fine("Ignoring " + reader.remaining()
          + " unused trailing bytes in " + "ASN.1 SEQUENCE");
    }
    reader = readerStack.removeFirst();
    // Reset the state
    state = ELEMENT_READ_STATE_NEED_TYPE;
  }
  /**
   * {@inheritDoc}
   */
  public void readEndSet() throws IOException
  {
    // From an implementation point of view, a set is equivalent to a
    // sequence.
    readEndSequence();
  }
  /**
   * {@inheritDoc}
   */
  public int readEnumerated() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if ((peekLength < 1) || (peekLength > 4))
    {
      final LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    // From an implementation point of view, an enumerated value is
    // equivalent to an integer.
    return (int) readInteger();
  }
  /**
   * {@inheritDoc}
   */
  public long readInteger() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if ((peekLength < 1) || (peekLength > 8))
    {
      final LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    if (reader.remaining() < peekLength)
    {
      final LocalizableMessage message = ERR_ASN1_INTEGER_TRUNCATED_VALUE
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    if (peekLength > 4)
    {
      long longValue = 0;
      for (int i = 0; i < peekLength; i++)
      {
        final int readByte = reader.get();
        if ((i == 0) && (readByte < 0))
        {
          longValue = 0xFFFFFFFFFFFFFFFFL;
        }
        longValue = (longValue << 8) | (readByte & 0xFF);
      }
      state = ELEMENT_READ_STATE_NEED_TYPE;
      return longValue;
    }
    else
    {
      int intValue = 0;
      for (int i = 0; i < peekLength; i++)
      {
        final int readByte = reader.get();
        if ((i == 0) && (readByte < 0))
        {
          intValue = 0xFFFFFFFF;
        }
        intValue = (intValue << 8) | (readByte & 0xFF);
      }
      state = ELEMENT_READ_STATE_NEED_TYPE;
      return intValue;
    }
  }
  /**
   * {@inheritDoc}
   */
  public void readNull() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    // Make sure that the decoded length is exactly zero byte.
    if (peekLength != 0)
    {
      final LocalizableMessage message = ERR_ASN1_NULL_INVALID_LENGTH
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    state = ELEMENT_READ_STATE_NEED_TYPE;
  }
  /**
   * {@inheritDoc}
   */
  public ByteString readOctetString() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if (reader.remaining() < peekLength)
    {
      final LocalizableMessage message = ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    state = ELEMENT_READ_STATE_NEED_TYPE;
    return reader.getByteString(peekLength);
  }
  /**
   * {@inheritDoc}
   */
  public ByteStringBuilder readOctetString(final ByteStringBuilder builder)
      throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    // Copy the value.
    if (reader.remaining() < peekLength)
    {
      final LocalizableMessage message = ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    builder.append(reader, peekLength);
    state = ELEMENT_READ_STATE_NEED_TYPE;
    return builder;
  }
  /**
   * {@inheritDoc}
   */
  public String readOctetStringAsString() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if (reader.remaining() < peekLength)
    {
      final LocalizableMessage message = ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    state = ELEMENT_READ_STATE_NEED_TYPE;
    return reader.getString(peekLength);
  }
  /**
   * {@inheritDoc}
   */
  public void readStartSequence() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if (reader.remaining() < peekLength)
    {
      final LocalizableMessage message = ERR_ASN1_SEQUENCE_SET_TRUNCATED_VALUE
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    final ByteSequenceReader subByteString = reader.getByteSequence(peekLength)
        .asReader();
    readerStack.addFirst(reader);
    reader = subByteString;
    // Reset the state
    state = ELEMENT_READ_STATE_NEED_TYPE;
  }
  /**
   * {@inheritDoc}
   */
  public void readStartSet() throws IOException
  {
    // From an implementation point of view, a set is equivalent to a
    // sequence.
    readStartSequence();
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Reader skipElement() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if (reader.remaining() < peekLength)
    {
      final LocalizableMessage message = ERR_ASN1_SKIP_TRUNCATED_VALUE
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    state = ELEMENT_READ_STATE_NEED_TYPE;
    reader.skip(peekLength);
    return this;
  }
  /**
   * Internal helper method reading the first length bytes and transition to the
   * next state if successful.
   *
   * @param throwEofException
   *          <code>true</code> to throw an exception when the end of the
   *          sequence is encountered.
   * @return <code>true</code> if the length bytes was successfully read
   * @throws IOException
   *           If an error occurs while trying to decode an ASN1 element.
   */
  private boolean needFirstLengthByteState(final boolean throwEofException)
      throws IOException
  {
    if (reader.remaining() <= 0)
    {
      if (throwEofException)
      {
        final LocalizableMessage message = ERR_ASN1_TRUNCATED_LENGTH_BYTE.get();
        throw DecodeException.fatalError(message);
      }
      return false;
    }
    int readByte = reader.get();
    peekLength = (readByte & 0x7F);
    if (peekLength != readByte)
    {
      int lengthBytesNeeded = peekLength;
      if (lengthBytesNeeded > 4)
      {
        final LocalizableMessage message = ERR_ASN1_INVALID_NUM_LENGTH_BYTES
            .get(lengthBytesNeeded);
        throw DecodeException.fatalError(message);
      }
      peekLength = 0x00;
      if (reader.remaining() < lengthBytesNeeded)
      {
        if (throwEofException)
        {
          final LocalizableMessage message = ERR_ASN1_TRUNCATED_LENGTH_BYTES
              .get(lengthBytesNeeded);
          throw DecodeException.fatalError(message);
        }
        return false;
      }
      while (lengthBytesNeeded > 0)
      {
        readByte = reader.get();
        peekLength = (peekLength << 8) | (readByte & 0xFF);
        lengthBytesNeeded--;
      }
    }
    // Make sure that the element is not larger than the maximum allowed
    // message size.
    if ((maxElementSize > 0) && (peekLength > maxElementSize))
    {
      final LocalizableMessage message = ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED
          .get(peekLength, maxElementSize);
      throw DecodeException.fatalError(message);
    }
    state = ELEMENT_READ_STATE_NEED_VALUE_BYTES;
    return true;
  }
  /**
   * Internal helper method reading the ASN.1 type byte and transition to the
   * next state if successful.
   *
   * @param throwEofException
   *          <code>true</code> to throw an exception when the end of the
   *          sequence is encountered.
   * @return <code>true</code> if the type byte was successfully read
   * @throws IOException
   *           If an error occurs while trying to decode an ASN1 element.
   */
  private boolean needTypeState(final boolean throwEofException)
      throws IOException
  {
    // Read just the type.
    if (reader.remaining() <= 0)
    {
      if (throwEofException)
      {
        final LocalizableMessage message = ERR_ASN1_TRUCATED_TYPE_BYTE.get();
        throw DecodeException.fatalError(message);
      }
      return false;
    }
    final int type = reader.get();
    peekType = (byte) type;
    state = ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE;
    return true;
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1Constants.java
New file
@@ -0,0 +1,169 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.asn1;
/**
 * This class defines a number of constants that may be used when interacting
 * with ASN.1 elements.
 */
public final class ASN1Constants
{
  /**
   * The ASN.1 element decoding state that indicates that the next byte read
   * should be the BER type for a new element.
   */
  static final int ELEMENT_READ_STATE_NEED_TYPE = 0;
  /**
   * The ASN.1 element decoding state that indicates that the next byte read
   * should be the first byte for the element length.
   */
  static final int ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE = 1;
  /**
   * The ASN.1 element decoding state that indicates that the next byte read
   * should be additional bytes of a multi-byte length.
   */
  static final int ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES = 2;
  /**
   * The ASN.1 element decoding state that indicates that the next byte read
   * should be applied to the value of the element.
   */
  static final int ELEMENT_READ_STATE_NEED_VALUE_BYTES = 3;
  /**
   * The BER type that is assigned to the universal Boolean element.
   */
  public static final byte UNIVERSAL_BOOLEAN_TYPE = 0x01;
  /**
   * The BER type that is assigned to the universal integer type.
   */
  public static final byte UNIVERSAL_INTEGER_TYPE = 0x02;
  /**
   * The BER type that is assigned to the universal octet string type.
   */
  public static final byte UNIVERSAL_OCTET_STRING_TYPE = 0x04;
  /**
   * The BER type that is assigned to the universal null type.
   */
  public static final byte UNIVERSAL_NULL_TYPE = 0x05;
  /**
   * The BER type that is assigned to the universal enumerated type.
   */
  public static final byte UNIVERSAL_ENUMERATED_TYPE = 0x0A;
  /**
   * The BER type that is assigned to the universal sequence type.
   */
  public static final byte UNIVERSAL_SEQUENCE_TYPE = 0x30;
  /**
   * The BER type that is assigned to the universal set type.
   */
  public static final byte UNIVERSAL_SET_TYPE = 0x31;
  /**
   * The byte array that will be used for ASN.1 elements with no value.
   */
  static final byte[] NO_VALUE = new byte[0];
  /**
   * The bitmask that can be ANDed with the BER type to zero out all bits except
   * those used in the class.
   */
  static final byte TYPE_MASK_ALL_BUT_CLASS = (byte) 0xC0;
  /**
   * The bitmask that can be ANDed with the BER type to determine if the element
   * is in the universal class.
   */
  static final byte TYPE_MASK_UNIVERSAL = 0x00;
  /**
   * The bitmask that can be ANDed with the BER type to determine if the element
   * is in the application-specific class.
   */
  static final byte TYPE_MASK_APPLICATION = 0x40;
  /**
   * The bitmask that can be ANDed with the BER type to determine if the element
   * is in the context-specific class.
   */
  static final byte TYPE_MASK_CONTEXT = (byte) 0x80;
  /**
   * The bitmask that can be ANDed with the BER type to determine if the element
   * is in the private class.
   */
  static final byte TYPE_MASK_PRIVATE = (byte) 0xC0;
  /**
   * The bitmask that can be ANDed with the BER type to zero out all bits except
   * the primitive/constructed bit.
   */
  static final byte TYPE_MASK_ALL_BUT_PC = (byte) 0x20;
  /**
   * The bitmask that can be ANDed with the BER type to determine if the element
   * is a primitive.
   */
  static final byte TYPE_MASK_PRIMITIVE = 0x00;
  /**
   * The bitmask that can be ANDed with the BER type to determine if the element
   * is constructed.
   */
  static final byte TYPE_MASK_CONSTRUCTED = 0x20;
  /**
   * The byte array containing the pre-encoded ASN.1 encoding for a boolean
   * value of "false".
   */
  public static final byte BOOLEAN_VALUE_FALSE = 0x00;
  /**
   * The byte array containing the pre-encoded ASN.1 encoding for a boolean
   * value of "false".
   */
  public static final byte BOOLEAN_VALUE_TRUE = (byte) 0xFF;
  // Prevent instantiation.
  private ASN1Constants()
  {
    // Nothing to do.
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1InputStreamReader.java
New file
@@ -0,0 +1,783 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.asn1;
import static org.forgerock.opendj.asn1.ASN1Constants.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.logging.Level;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.DecodeException;
import com.forgerock.opendj.util.SizeLimitInputStream;
import com.forgerock.opendj.util.StaticUtils;
/**
 * An ASN1Reader that reads from an input stream.
 */
final class ASN1InputStreamReader extends AbstractASN1Reader implements
    ASN1Reader
{
  private int state = ELEMENT_READ_STATE_NEED_TYPE;
  private byte peekType = 0;
  private int peekLength = -1;
  private int lengthBytesNeeded = 0;
  private final int maxElementSize;
  private InputStream in;
  private final LinkedList<InputStream> streamStack;
  private byte[] buffer;
  /**
   * Creates a new ASN1 reader whose source is the provided input stream and
   * having a user defined maximum BER element size.
   *
   * @param stream
   *          The input stream to be read.
   * @param maxElementSize
   *          The maximum BER element size, or <code>0</code> to indicate that
   *          there is no limit.
   */
  ASN1InputStreamReader(final InputStream stream, final int maxElementSize)
  {
    this.in = stream;
    this.streamStack = new LinkedList<InputStream>();
    this.buffer = new byte[512];
    this.maxElementSize = maxElementSize;
  }
  /**
   * {@inheritDoc}
   */
  public void close() throws IOException
  {
    // Calling close of SizeLimitInputStream should close the parent
    // stream.
    in.close();
    streamStack.clear();
  }
  /**
   * {@inheritDoc}
   */
  public boolean elementAvailable() throws IOException
  {
    if ((state == ELEMENT_READ_STATE_NEED_TYPE) && !needTypeState(false, false))
    {
      return false;
    }
    if ((state == ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE)
        && !needFirstLengthByteState(false, false))
    {
      return false;
    }
    if ((state == ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES)
        && !needAdditionalLengthBytesState(false, false))
    {
      return false;
    }
    return peekLength <= in.available();
  }
  /**
   * {@inheritDoc}
   */
  public boolean hasNextElement() throws IOException
  {
    if (!streamStack.isEmpty())
    {
      // We are reading a sub sequence. Return true as long as we
      // haven't exhausted the size limit for the sub sequence sub input
      // stream.
      final SizeLimitInputStream subSq = (SizeLimitInputStream) in;
      return (subSq.getSizeLimit() - subSq.getBytesRead() > 0);
    }
    return (state != ELEMENT_READ_STATE_NEED_TYPE)
        || needTypeState(true, false);
  }
  /**
   * {@inheritDoc}
   */
  public int peekLength() throws IOException
  {
    peekType();
    switch (state)
    {
    case ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE:
      needFirstLengthByteState(true, true);
      break;
    case ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES:
      needAdditionalLengthBytesState(true, true);
    }
    return peekLength;
  }
  /**
   * {@inheritDoc}
   */
  public byte peekType() throws IOException
  {
    if (state == ELEMENT_READ_STATE_NEED_TYPE)
    {
      needTypeState(true, true);
    }
    return peekType;
  }
  /**
   * {@inheritDoc}
   */
  public boolean readBoolean() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if (peekLength != 1)
    {
      final LocalizableMessage message = ERR_ASN1_BOOLEAN_INVALID_LENGTH
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    final int readByte = in.read();
    if (readByte == -1)
    {
      final LocalizableMessage message = ERR_ASN1_BOOLEAN_TRUNCATED_VALUE
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String.format(
          "READ ASN.1 BOOLEAN(type=0x%x, length=%d, value=%s)", peekType,
          peekLength, String.valueOf(readByte != 0x00)));
    }
    state = ELEMENT_READ_STATE_NEED_TYPE;
    return readByte != 0x00;
  }
  /**
   * {@inheritDoc}
   */
  public void readEndSequence() throws IOException, IllegalStateException
  {
    if (streamStack.isEmpty())
    {
      final LocalizableMessage message = ERR_ASN1_SEQUENCE_READ_NOT_STARTED
          .get();
      throw new IllegalStateException(message.toString());
    }
    // Ignore all unused trailing components.
    final SizeLimitInputStream subSq = (SizeLimitInputStream) in;
    if (subSq.getSizeLimit() - subSq.getBytesRead() > 0)
    {
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
      {
        StaticUtils.DEBUG_LOG.fine(String.format(
            "Ignoring %d unused trailing bytes in ASN.1 SEQUENCE", subSq
                .getSizeLimit()
                - subSq.getBytesRead()));
      }
      subSq.skip(subSq.getSizeLimit() - subSq.getBytesRead());
    }
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String.format("READ ASN.1 END SEQUENCE"));
    }
    in = streamStack.removeFirst();
    // Reset the state
    state = ELEMENT_READ_STATE_NEED_TYPE;
  }
  /**
   * {@inheritDoc}
   */
  public void readEndSet() throws IOException
  {
    // From an implementation point of view, a set is equivalent to a
    // sequence.
    readEndSequence();
  }
  /**
   * {@inheritDoc}
   */
  public int readEnumerated() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if ((peekLength < 1) || (peekLength > 4))
    {
      final LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    // From an implementation point of view, an enumerated value is
    // equivalent to an integer.
    return (int) readInteger();
  }
  /**
   * {@inheritDoc}
   */
  public long readInteger() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if ((peekLength < 1) || (peekLength > 8))
    {
      final LocalizableMessage message = ERR_ASN1_INTEGER_INVALID_LENGTH
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    if (peekLength > 4)
    {
      long longValue = 0;
      for (int i = 0; i < peekLength; i++)
      {
        final int readByte = in.read();
        if (readByte == -1)
        {
          final LocalizableMessage message = ERR_ASN1_INTEGER_TRUNCATED_VALUE
              .get(peekLength);
          throw DecodeException.fatalError(message);
        }
        if ((i == 0) && (((byte) readByte) < 0))
        {
          longValue = 0xFFFFFFFFFFFFFFFFL;
        }
        longValue = (longValue << 8) | (readByte & 0xFF);
      }
      state = ELEMENT_READ_STATE_NEED_TYPE;
      return longValue;
    }
    else
    {
      int intValue = 0;
      for (int i = 0; i < peekLength; i++)
      {
        final int readByte = in.read();
        if (readByte == -1)
        {
          final LocalizableMessage message = ERR_ASN1_INTEGER_TRUNCATED_VALUE
              .get(peekLength);
          throw DecodeException.fatalError(message);
        }
        if ((i == 0) && (((byte) readByte) < 0))
        {
          intValue = 0xFFFFFFFF;
        }
        intValue = (intValue << 8) | (readByte & 0xFF);
      }
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "READ ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", peekType,
            peekLength, intValue));
      }
      state = ELEMENT_READ_STATE_NEED_TYPE;
      return intValue;
    }
  }
  /**
   * {@inheritDoc}
   */
  public void readNull() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    // Make sure that the decoded length is exactly zero byte.
    if (peekLength != 0)
    {
      final LocalizableMessage message = ERR_ASN1_NULL_INVALID_LENGTH
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String.format(
          "READ ASN.1 NULL(type=0x%x, length=%d)", peekType, peekLength));
    }
    state = ELEMENT_READ_STATE_NEED_TYPE;
  }
  /**
   * {@inheritDoc}
   */
  public ByteString readOctetString() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if (peekLength == 0)
    {
      state = ELEMENT_READ_STATE_NEED_TYPE;
      return ByteString.empty();
    }
    // Copy the value and construct the element to return.
    final byte[] value = new byte[peekLength];
    int bytesNeeded = peekLength;
    int bytesRead;
    while (bytesNeeded > 0)
    {
      bytesRead = in.read(value, peekLength - bytesNeeded, bytesNeeded);
      if (bytesRead < 0)
      {
        final LocalizableMessage message = ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE
            .get(peekLength);
        throw DecodeException.fatalError(message);
      }
      bytesNeeded -= bytesRead;
    }
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG
          .finest(String.format("READ ASN.1 OCTETSTRING(type=0x%x, length=%d)",
              peekType, peekLength));
    }
    state = ELEMENT_READ_STATE_NEED_TYPE;
    return ByteString.wrap(value);
  }
  /**
   * {@inheritDoc}
   */
  public ByteStringBuilder readOctetString(final ByteStringBuilder builder)
      throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if (peekLength == 0)
    {
      state = ELEMENT_READ_STATE_NEED_TYPE;
      return builder;
    }
    // Copy the value and construct the element to return.
    int bytesNeeded = peekLength;
    int bytesRead;
    while (bytesNeeded > 0)
    {
      bytesRead = builder.append(in, bytesNeeded);
      if (bytesRead < 0)
      {
        final LocalizableMessage message = ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE
            .get(peekLength);
        throw DecodeException.fatalError(message);
      }
      bytesNeeded -= bytesRead;
    }
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG
          .finest(String.format("READ ASN.1 OCTETSTRING(type=0x%x, length=%d)",
              peekType, peekLength));
    }
    state = ELEMENT_READ_STATE_NEED_TYPE;
    return builder;
  }
  /**
   * {@inheritDoc}
   */
  public String readOctetStringAsString() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    if (peekLength == 0)
    {
      state = ELEMENT_READ_STATE_NEED_TYPE;
      return "";
    }
    // Resize the temp buffer if needed
    if (peekLength > buffer.length)
    {
      buffer = new byte[peekLength];
    }
    int bytesNeeded = peekLength;
    int bytesRead;
    while (bytesNeeded > 0)
    {
      bytesRead = in.read(buffer, peekLength - bytesNeeded, bytesNeeded);
      if (bytesRead < 0)
      {
        final LocalizableMessage message = ERR_ASN1_OCTET_STRING_TRUNCATED_VALUE
            .get(peekLength);
        throw DecodeException.fatalError(message);
      }
      bytesNeeded -= bytesRead;
    }
    state = ELEMENT_READ_STATE_NEED_TYPE;
    String str;
    try
    {
      str = new String(buffer, 0, peekLength, "UTF-8");
    }
    catch (final Exception e)
    {
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
      {
        StaticUtils.DEBUG_LOG.warning("Unable to decode ASN.1 OCTETSTRING "
            + "bytes as UTF-8 string: " + e.toString());
      }
      str = new String(buffer, 0, peekLength);
    }
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String.format(
          "READ ASN.1 OCTETSTRING(type=0x%x, length=%d, value=%s)", peekType,
          peekLength, str));
    }
    return str;
  }
  /**
   * {@inheritDoc}
   */
  public void readStartSequence() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    final SizeLimitInputStream subStream = new SizeLimitInputStream(in,
        peekLength);
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String.format(
          "READ ASN.1 START SEQUENCE(type=0x%x, length=%d)", peekType,
          peekLength));
    }
    streamStack.addFirst(in);
    in = subStream;
    // Reset the state
    state = ELEMENT_READ_STATE_NEED_TYPE;
  }
  /**
   * {@inheritDoc}
   */
  public void readStartSet() throws IOException
  {
    // From an implementation point of view, a set is equivalent to a
    // sequence.
    readStartSequence();
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Reader skipElement() throws IOException
  {
    // Read the header if haven't done so already
    peekLength();
    final long bytesSkipped = in.skip(peekLength);
    if (bytesSkipped != peekLength)
    {
      final LocalizableMessage message = ERR_ASN1_SKIP_TRUNCATED_VALUE
          .get(peekLength);
      throw DecodeException.fatalError(message);
    }
    state = ELEMENT_READ_STATE_NEED_TYPE;
    return this;
  }
  /**
   * Internal helper method reading the additional ASN.1 length bytes and
   * transition to the next state if successful.
   *
   * @param isBlocking
   *          <code>true</code> to block if the type byte is not available or
   *          <code>false</code> to check for availability first.
   * @param throwEofException
   *          <code>true</code> to throw an exception when an EOF is encountered
   *          or <code>false</code> to return false.
   * @return <code>true</code> if the length bytes was successfully read.
   * @throws IOException
   *           If an error occurs while reading from the stream.
   */
  private boolean needAdditionalLengthBytesState(final boolean isBlocking,
      final boolean throwEofException) throws IOException
  {
    if (!isBlocking && (in.available() < lengthBytesNeeded))
    {
      return false;
    }
    int readByte;
    while (lengthBytesNeeded > 0)
    {
      readByte = in.read();
      if (readByte == -1)
      {
        state = ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES;
        if (throwEofException)
        {
          final LocalizableMessage message = ERR_ASN1_TRUNCATED_LENGTH_BYTES
              .get(lengthBytesNeeded);
          throw DecodeException.fatalError(message);
        }
        return false;
      }
      peekLength = (peekLength << 8) | (readByte & 0xFF);
      lengthBytesNeeded--;
    }
    // Make sure that the element is not larger than the maximum allowed
    // message size.
    if ((maxElementSize > 0) && (peekLength > maxElementSize))
    {
      final LocalizableMessage message = ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED
          .get(peekLength, maxElementSize);
      throw DecodeException.fatalError(message);
    }
    state = ELEMENT_READ_STATE_NEED_VALUE_BYTES;
    return true;
  }
  /**
   * Internal helper method reading the first length bytes and transition to the
   * next state if successful.
   *
   * @param isBlocking
   *          <code>true</code> to block if the type byte is not available or
   *          <code>false</code> to check for availability first.
   * @param throwEofException
   *          <code>true</code> to throw an exception when an EOF is encountered
   *          or <code>false</code> to return false.
   * @return <code>true</code> if the length bytes was successfully read
   * @throws IOException
   *           If an error occurs while reading from the stream.
   */
  private boolean needFirstLengthByteState(final boolean isBlocking,
      final boolean throwEofException) throws IOException
  {
    if (!isBlocking && (in.available() <= 0))
    {
      return false;
    }
    int readByte = in.read();
    if (readByte == -1)
    {
      if (throwEofException)
      {
        final LocalizableMessage message = ERR_ASN1_TRUNCATED_LENGTH_BYTE.get();
        throw DecodeException.fatalError(message);
      }
      return false;
    }
    peekLength = (readByte & 0x7F);
    if (peekLength != readByte)
    {
      lengthBytesNeeded = peekLength;
      if (lengthBytesNeeded > 4)
      {
        final LocalizableMessage message = ERR_ASN1_INVALID_NUM_LENGTH_BYTES
            .get(lengthBytesNeeded);
        throw DecodeException.fatalError(message);
      }
      peekLength = 0x00;
      if (!isBlocking && (in.available() < lengthBytesNeeded))
      {
        state = ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES;
        return false;
      }
      while (lengthBytesNeeded > 0)
      {
        readByte = in.read();
        if (readByte == -1)
        {
          state = ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES;
          if (throwEofException)
          {
            final LocalizableMessage message = ERR_ASN1_TRUNCATED_LENGTH_BYTES
                .get(lengthBytesNeeded);
            throw DecodeException.fatalError(message);
          }
          return false;
        }
        peekLength = (peekLength << 8) | (readByte & 0xFF);
        lengthBytesNeeded--;
      }
    }
    // Make sure that the element is not larger than the maximum allowed
    // message size.
    if ((maxElementSize > 0) && (peekLength > maxElementSize))
    {
      final LocalizableMessage message = ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED
          .get(peekLength, maxElementSize);
      throw DecodeException.fatalError(message);
    }
    state = ELEMENT_READ_STATE_NEED_VALUE_BYTES;
    return true;
  }
  /**
   * Internal helper method reading the ASN.1 type byte and transition to the
   * next state if successful.
   *
   * @param isBlocking
   *          <code>true</code> to block if the type byte is not available or
   *          <code>false</code> to check for availability first.
   * @param throwEofException
   *          <code>true</code> to throw an exception when an EOF is encountered
   *          or <code>false</code> to return false.
   * @return <code>true</code> if the type byte was successfully read
   * @throws IOException
   *           If an error occurs while reading from the stream.
   */
  private boolean needTypeState(final boolean isBlocking,
      final boolean throwEofException) throws IOException
  {
    // Read just the type.
    if (!isBlocking && (in.available() <= 0))
    {
      return false;
    }
    final int type = in.read();
    if (type == -1)
    {
      if (throwEofException)
      {
        final LocalizableMessage message = ERR_ASN1_TRUCATED_TYPE_BYTE.get();
        throw DecodeException.fatalError(message);
      }
      return false;
    }
    peekType = (byte) type;
    state = ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE;
    return true;
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1OutputStreamWriter.java
New file
@@ -0,0 +1,562 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.asn1;
import static org.forgerock.opendj.asn1.ASN1Constants.BOOLEAN_VALUE_FALSE;
import static org.forgerock.opendj.asn1.ASN1Constants.BOOLEAN_VALUE_TRUE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ASN1_SEQUENCE_WRITE_NOT_STARTED;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.logging.Level;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import com.forgerock.opendj.util.ByteSequenceOutputStream;
import com.forgerock.opendj.util.StaticUtils;
/**
 * An ASN1Writer implementation that outputs to an outputstream.
 */
final class ASN1OutputStreamWriter extends AbstractASN1Writer implements
    ASN1Writer
{
  private final OutputStream rootStream;
  private OutputStream out;
  private final ArrayList<ByteSequenceOutputStream> streamStack;
  private int stackDepth;
  /**
   * Creates a new ASN.1 output stream reader.
   *
   * @param stream
   *          The underlying output stream.
   */
  ASN1OutputStreamWriter(final OutputStream stream)
  {
    this.out = stream;
    this.rootStream = stream;
    this.streamStack = new ArrayList<ByteSequenceOutputStream>();
    this.stackDepth = -1;
  }
  /**
   * {@inheritDoc}
   */
  public void close() throws IOException
  {
    while (stackDepth >= 0)
    {
      writeEndSequence();
    }
    rootStream.flush();
    streamStack.clear();
    rootStream.close();
  }
  /**
   * {@inheritDoc}
   */
  public void flush() throws IOException
  {
    rootStream.flush();
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeBoolean(final byte type, final boolean booleanValue)
      throws IOException
  {
    out.write(type);
    writeLength(1);
    out.write(booleanValue ? BOOLEAN_VALUE_TRUE : BOOLEAN_VALUE_FALSE);
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String.format(
          "WRITE ASN.1 BOOLEAN(type=0x%x, length=%d, value=%s)", type, 1,
          String.valueOf(booleanValue)));
    }
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeEndSequence() throws IOException,
      IllegalStateException
  {
    if (stackDepth < 0)
    {
      final LocalizableMessage message = ERR_ASN1_SEQUENCE_WRITE_NOT_STARTED
          .get();
      throw new IllegalStateException(message.toString());
    }
    final ByteSequenceOutputStream childStream = streamStack.get(stackDepth);
    // Decrement the stack depth and get the parent stream
    --stackDepth;
    final OutputStream parentStream = stackDepth < 0 ? rootStream : streamStack
        .get(stackDepth);
    // Switch to parent stream and reset the sub-stream
    out = parentStream;
    // Write the length and contents of the sub-stream
    writeLength(childStream.length());
    childStream.writeTo(parentStream);
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String.format(
          "WRITE ASN.1 END SEQUENCE(length=%d)", childStream.length()));
    }
    childStream.reset();
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeEndSet() throws IOException
  {
    return writeEndSequence();
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeEnumerated(final byte type, final int intValue)
      throws IOException
  {
    return writeInteger(type, intValue);
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeInteger(final byte type, final int intValue)
      throws IOException
  {
    out.write(type);
    if (((intValue < 0) && ((intValue & 0xFFFFFF80) == 0xFFFFFF80))
        || ((intValue & 0x0000007F) == intValue))
    {
      writeLength(1);
      out.write((byte) (intValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 1,
            intValue));
      }
    }
    else if (((intValue < 0) && ((intValue & 0xFFFF8000) == 0xFFFF8000))
        || ((intValue & 0x00007FFF) == intValue))
    {
      writeLength(2);
      out.write((byte) ((intValue >> 8) & 0xFF));
      out.write((byte) (intValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 2,
            intValue));
      }
    }
    else if (((intValue < 0) && ((intValue & 0xFF800000) == 0xFF800000))
        || ((intValue & 0x007FFFFF) == intValue))
    {
      writeLength(3);
      out.write((byte) ((intValue >> 16) & 0xFF));
      out.write((byte) ((intValue >> 8) & 0xFF));
      out.write((byte) (intValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 3,
            intValue));
      }
    }
    else
    {
      writeLength(4);
      out.write((byte) ((intValue >> 24) & 0xFF));
      out.write((byte) ((intValue >> 16) & 0xFF));
      out.write((byte) ((intValue >> 8) & 0xFF));
      out.write((byte) (intValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 4,
            intValue));
      }
    }
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeInteger(final byte type, final long longValue)
      throws IOException
  {
    out.write(type);
    if (((longValue < 0) && ((longValue & 0xFFFFFFFFFFFFFF80L) == 0xFFFFFFFFFFFFFF80L))
        || ((longValue & 0x000000000000007FL) == longValue))
    {
      writeLength(1);
      out.write((byte) (longValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 1,
            longValue));
      }
    }
    else if (((longValue < 0) && ((longValue & 0xFFFFFFFFFFFF8000L) == 0xFFFFFFFFFFFF8000L))
        || ((longValue & 0x0000000000007FFFL) == longValue))
    {
      writeLength(2);
      out.write((byte) ((longValue >> 8) & 0xFF));
      out.write((byte) (longValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 2,
            longValue));
      }
    }
    else if (((longValue < 0) && ((longValue & 0xFFFFFFFFFF800000L) == 0xFFFFFFFFFF800000L))
        || ((longValue & 0x00000000007FFFFFL) == longValue))
    {
      writeLength(3);
      out.write((byte) ((longValue >> 16) & 0xFF));
      out.write((byte) ((longValue >> 8) & 0xFF));
      out.write((byte) (longValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 3,
            longValue));
      }
    }
    else if (((longValue < 0) && ((longValue & 0xFFFFFFFF80000000L) == 0xFFFFFFFF80000000L))
        || ((longValue & 0x000000007FFFFFFFL) == longValue))
    {
      writeLength(4);
      out.write((byte) ((longValue >> 24) & 0xFF));
      out.write((byte) ((longValue >> 16) & 0xFF));
      out.write((byte) ((longValue >> 8) & 0xFF));
      out.write((byte) (longValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 4,
            longValue));
      }
    }
    else if (((longValue < 0) && ((longValue & 0xFFFFFF8000000000L) == 0xFFFFFF8000000000L))
        || ((longValue & 0x0000007FFFFFFFFFL) == longValue))
    {
      writeLength(5);
      out.write((byte) ((longValue >> 32) & 0xFF));
      out.write((byte) ((longValue >> 24) & 0xFF));
      out.write((byte) ((longValue >> 16) & 0xFF));
      out.write((byte) ((longValue >> 8) & 0xFF));
      out.write((byte) (longValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 5,
            longValue));
      }
    }
    else if (((longValue < 0) && ((longValue & 0xFFFF800000000000L) == 0xFFFF800000000000L))
        || ((longValue & 0x00007FFFFFFFFFFFL) == longValue))
    {
      writeLength(6);
      out.write((byte) ((longValue >> 40) & 0xFF));
      out.write((byte) ((longValue >> 32) & 0xFF));
      out.write((byte) ((longValue >> 24) & 0xFF));
      out.write((byte) ((longValue >> 16) & 0xFF));
      out.write((byte) ((longValue >> 8) & 0xFF));
      out.write((byte) (longValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 6,
            longValue));
      }
    }
    else if (((longValue < 0) && ((longValue & 0xFF80000000000000L) == 0xFF80000000000000L))
        || ((longValue & 0x007FFFFFFFFFFFFFL) == longValue))
    {
      writeLength(7);
      out.write((byte) ((longValue >> 48) & 0xFF));
      out.write((byte) ((longValue >> 40) & 0xFF));
      out.write((byte) ((longValue >> 32) & 0xFF));
      out.write((byte) ((longValue >> 24) & 0xFF));
      out.write((byte) ((longValue >> 16) & 0xFF));
      out.write((byte) ((longValue >> 8) & 0xFF));
      out.write((byte) (longValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 7,
            longValue));
      }
    }
    else
    {
      writeLength(8);
      out.write((byte) ((longValue >> 56) & 0xFF));
      out.write((byte) ((longValue >> 48) & 0xFF));
      out.write((byte) ((longValue >> 40) & 0xFF));
      out.write((byte) ((longValue >> 32) & 0xFF));
      out.write((byte) ((longValue >> 24) & 0xFF));
      out.write((byte) ((longValue >> 16) & 0xFF));
      out.write((byte) ((longValue >> 8) & 0xFF));
      out.write((byte) (longValue & 0xFF));
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
      {
        StaticUtils.DEBUG_LOG.finest(String.format(
            "WRITE ASN.1 INTEGER(type=0x%x, length=%d, value=%d)", type, 8,
            longValue));
      }
    }
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeNull(final byte type) throws IOException
  {
    out.write(type);
    writeLength(0);
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String.format(
          "WRITE ASN.1 NULL(type=0x%x, length=%d)", type, 0));
    }
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeOctetString(final byte type, final byte[] value,
      final int offset, final int length) throws IOException
  {
    out.write(type);
    writeLength(length);
    out.write(value, offset, length);
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String.format(
          "WRITE ASN.1 OCTETSTRING(type=0x%x, length=%d)", type, length));
    }
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeOctetString(final byte type, final ByteSequence value)
      throws IOException
  {
    out.write(type);
    writeLength(value.length());
    value.copyTo(out);
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String
          .format("WRITE ASN.1 OCTETSTRING(type=0x%x, length=%d)", type, value
              .length()));
    }
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeOctetString(final byte type, final String value)
      throws IOException
  {
    out.write(type);
    if (value == null)
    {
      writeLength(0);
      return this;
    }
    final byte[] bytes = StaticUtils.getBytes(value);
    writeLength(bytes.length);
    out.write(bytes);
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String.format(
          "WRITE ASN.1 OCTETSTRING(type=0x%x, length=%d, " + "value=%s)", type,
          bytes.length, value));
    }
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeStartSequence(final byte type) throws IOException
  {
    // Write the type in current stream switch to next sub-stream
    out.write(type);
    // Increment the stack depth and get the sub-stream from the stack
    ++stackDepth;
    // Make sure we have a cached sub-stream at this depth
    if (stackDepth >= streamStack.size())
    {
      final ByteSequenceOutputStream subStream = new ByteSequenceOutputStream(
          new ByteStringBuilder());
      streamStack.add(subStream);
      out = subStream;
    }
    else
    {
      out = streamStack.get(stackDepth);
    }
    if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
    {
      StaticUtils.DEBUG_LOG.finest(String.format(
          "WRITE ASN.1 START SEQUENCE(type=0x%x)", type));
    }
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeStartSet(final byte type) throws IOException
  {
    // From an implementation point of view, a set is equivalent to a
    // sequence.
    return writeStartSequence(type);
  }
  /**
   * Writes the provided value for use as the length of an ASN.1 element.
   *
   * @param length
   *          The length to encode for use in an ASN.1 element.
   * @throws IOException
   *           if an error occurs while writing.
   */
  private void writeLength(final int length) throws IOException
  {
    if (length < 128)
    {
      out.write((byte) length);
    }
    else if ((length & 0x000000FF) == length)
    {
      out.write((byte) 0x81);
      out.write((byte) (length & 0xFF));
    }
    else if ((length & 0x0000FFFF) == length)
    {
      out.write((byte) 0x82);
      out.write((byte) ((length >> 8) & 0xFF));
      out.write((byte) (length & 0xFF));
    }
    else if ((length & 0x00FFFFFF) == length)
    {
      out.write((byte) 0x83);
      out.write((byte) ((length >> 16) & 0xFF));
      out.write((byte) ((length >> 8) & 0xFF));
      out.write((byte) (length & 0xFF));
    }
    else
    {
      out.write((byte) 0x84);
      out.write((byte) ((length >> 24) & 0xFF));
      out.write((byte) ((length >> 16) & 0xFF));
      out.write((byte) ((length >> 8) & 0xFF));
      out.write((byte) (length & 0xFF));
    }
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1Reader.java
New file
@@ -0,0 +1,431 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.asn1;
import java.io.Closeable;
import java.io.IOException;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.DecodeException;
/**
 * An interface for decoding ASN.1 elements from a data source.
 * <p>
 * Methods for creating {@link ASN1Reader}s are provided in the {@link ASN1}
 * class.
 */
public interface ASN1Reader extends Closeable
{
  /**
   * Closes this ASN.1 reader.
   *
   * @throws IOException
   *           If an error occurs while closing.
   */
  void close() throws IOException;
  /**
   * Indicates whether or not the next element can be read without blocking.
   *
   * @return {@code true} if a complete element is available or {@code false}
   *         otherwise.
   * @throws DecodeException
   *           If the available data was not valid ASN.1.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  boolean elementAvailable() throws DecodeException, IOException;
  /**
   * Indicates whether or not the current stream, sequence, or set contains
   * another element. Note that this method may return {@code true} even if a
   * previous call to {@link #elementAvailable} returned {@code false},
   * indicating that the current set or sequence contains another element but an
   * attempt to read that element may block. This method will block if there is
   * not enough data available to make the determination (typically only the
   * next element's type is required).
   *
   * @return {@code true} if the current stream, sequence, or set contains
   *         another element, or {@code false} if the end of the stream,
   *         sequence, or set has been reached.
   * @throws DecodeException
   *           If the available data was not valid ASN.1.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  boolean hasNextElement() throws DecodeException, IOException;
  /**
   * Returns the data length of the next element without actually reading it.
   *
   * @return The data length of the next element, or {@code -1} if the end of
   *         the stream, sequence, or set has been reached.
   * @throws DecodeException
   *           If the available data was not valid ASN.1.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  int peekLength() throws DecodeException, IOException;
  /**
   * Returns the type of the next element without actually reading it.
   *
   * @return The type of the next element, or {@code -1} if the end of the
   *         stream, sequence, or set has been reached.
   * @throws DecodeException
   *           If the available data was not valid ASN.1.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  byte peekType() throws DecodeException, IOException;
  /**
   * Reads the next element as a boolean having the Universal Boolean ASN.1 type
   * tag.
   *
   * @return The decoded boolean value.
   * @throws DecodeException
   *           If the element cannot be decoded as a boolean.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  boolean readBoolean() throws DecodeException, IOException;
  /**
   * Reads the next element as a boolean having the provided type tag.
   *
   * @param type
   *          The expected type tag of the element.
   * @return The decoded boolean value.
   * @throws DecodeException
   *           If the element cannot be decoded as a boolean.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  boolean readBoolean(byte type) throws DecodeException, IOException;
  /**
   * Finishes reading a sequence and discards any unread elements.
   *
   * @throws DecodeException
   *           If an error occurs while advancing to the end of the sequence.
   * @throws IOException
   *           If an unexpected IO error occurred.
   * @throws IllegalStateException
   *           If there is no sequence being read.
   */
  void readEndSequence() throws DecodeException, IOException,
      IllegalStateException;
  /**
   * Finishes reading a set and discards any unread elements.
   *
   * @throws DecodeException
   *           If an error occurs while advancing to the end of the set.
   * @throws IOException
   *           If an unexpected IO error occurred.
   * @throws IllegalStateException
   *           If there is no set being read.
   */
  void readEndSet() throws DecodeException, IOException, IllegalStateException;
  /**
   * Reads the next element as an enumerated having the Universal Enumerated
   * ASN.1 type tag.
   *
   * @return The decoded enumerated value.
   * @throws DecodeException
   *           If the element cannot be decoded as an enumerated value.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  int readEnumerated() throws DecodeException, IOException;
  /**
   * Reads the next element as an enumerated having the provided type tag.
   *
   * @param type
   *          The expected type tag of the element.
   * @return The decoded enumerated value.
   * @throws DecodeException
   *           If the element cannot be decoded as an enumerated value.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  int readEnumerated(byte type) throws DecodeException, IOException;
  /**
   * Reads the next element as an integer having the Universal Integer ASN.1
   * type tag.
   *
   * @return The decoded integer value.
   * @throws DecodeException
   *           If the element cannot be decoded as an integer.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  long readInteger() throws DecodeException, IOException;
  /**
   * Reads the next element as an integer having the provided type tag.
   *
   * @param type
   *          The expected type tag of the element.
   * @return The decoded integer value.
   * @throws DecodeException
   *           If the element cannot be decoded as an integer.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  long readInteger(byte type) throws DecodeException, IOException;
  /**
   * Reads the next element as a null element having the Universal Null ASN.1
   * type tag.
   *
   * @throws DecodeException
   *           If the element cannot be decoded as a null element.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  void readNull() throws DecodeException, IOException;
  /**
   * Reads the next element as a null element having the provided type tag.
   *
   * @param type
   *          The expected type tag of the element.
   * @throws DecodeException
   *           If the element cannot be decoded as a null element.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  void readNull(byte type) throws DecodeException, IOException;
  /**
   * Reads the next element as an octet string having the Universal Octet String
   * ASN.1 type tag.
   *
   * @return The decoded octet string represented using a {@link ByteString}.
   * @throws DecodeException
   *           If the element cannot be decoded as an octet string.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  ByteString readOctetString() throws DecodeException, IOException;
  /**
   * Reads the next element as an octet string having the provided type tag.
   *
   * @param type
   *          The expected type tag of the element.
   * @return The decoded octet string represented using a {@link ByteString}.
   * @throws DecodeException
   *           If the element cannot be decoded as an octet string.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  ByteString readOctetString(byte type) throws DecodeException, IOException;
  /**
   * Reads the next element as an octet string having the provided type tag and
   * appends it to the provided {@link ByteStringBuilder}.
   *
   * @param type
   *          The expected type tag of the element.
   * @param builder
   *          The {@link ByteStringBuilder} to append the octet string to.
   * @return A reference to {@code builder}.
   * @throws DecodeException
   *           If the element cannot be decoded as an octet string.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  ByteStringBuilder readOctetString(byte type, ByteStringBuilder builder)
      throws DecodeException, IOException;
  /**
   * Reads the next element as an octet string having the Universal Octet String
   * ASN.1 type tag and appends it to the provided {@link ByteStringBuilder}.
   *
   * @param builder
   *          The {@link ByteStringBuilder} to append the octet string to.
   * @return A reference to {@code builder}.
   * @throws DecodeException
   *           If the element cannot be decoded as an octet string.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  ByteStringBuilder readOctetString(ByteStringBuilder builder)
      throws DecodeException, IOException;
  /**
   * Reads the next element as an octet string having the Universal Octet String
   * ASN.1 type tag and decodes the value as a UTF-8 encoded string.
   *
   * @return The decoded octet string as a UTF-8 encoded string.
   * @throws DecodeException
   *           If the element cannot be decoded as an octet string.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  String readOctetStringAsString() throws DecodeException, IOException;
  /**
   * Reads the next element as an octet string having the provided type tag and
   * decodes the value as a UTF-8 encoded string.
   *
   * @param type
   *          The expected type tag of the element.
   * @return The decoded octet string as a UTF-8 encoded string.
   * @throws DecodeException
   *           If the element cannot be decoded as an octet string.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  String readOctetStringAsString(byte type) throws DecodeException, IOException;
  /**
   * Reads the next element as a sequence having the Universal Sequence ASN.1
   * type tag. All further reads will read the elements in the sequence until
   * {@link #readEndSequence()} is called.
   *
   * @throws DecodeException
   *           If the element cannot be decoded as a sequence.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  void readStartSequence() throws DecodeException, IOException;
  /**
   * Reads the next element as a sequence having the provided type tag. All
   * further reads will read the elements in the sequence until
   * {@link #readEndSequence()} is called.
   *
   * @param type
   *          The expected type tag of the element.
   * @throws DecodeException
   *           If the element cannot be decoded as a sequence.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  void readStartSequence(byte type) throws DecodeException, IOException;
  /**
   * Reads the next element as a set having the Universal Set ASN.1 type tag.
   * All further reads will read the elements in the set until
   * {@link #readEndSet()} is called.
   *
   * @throws DecodeException
   *           If the element cannot be decoded as a set.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  void readStartSet() throws DecodeException, IOException;
  /**
   * Reads the next element as a set having the provided type tag. All further
   * reads will read the elements in the set until {@link #readEndSet()} is
   * called.
   *
   * @param type
   *          The expected type tag of the element.
   * @throws DecodeException
   *           If the element cannot be decoded as a set.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  void readStartSet(byte type) throws DecodeException, IOException;
  /**
   * Skips the next element without decoding it.
   *
   * @return A reference to this ASN.1 reader.
   * @throws DecodeException
   *           If the next element could not be skipped.
   * @throws IOException
   *           If an unexpected IO error occurred.
   */
  ASN1Reader skipElement() throws DecodeException, IOException;
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/asn1/ASN1Writer.java
New file
@@ -0,0 +1,391 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.asn1;
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import org.forgerock.opendj.ldap.ByteSequence;
/**
 * An interface for encoding ASN.1 elements to a data source.
 * <p>
 * Methods for creating {@link ASN1Writer}s are provided in the {@link ASN1}
 * class.
 */
public interface ASN1Writer extends Closeable, Flushable
{
  /**
   * Closes this ASN.1 writer, flushing it first. Closing a previously closed
   * ASN.1 writer has no effect. Any unfinished sequences and/or sets will be
   * ended.
   *
   * @throws IOException
   *           If an error occurs while closing.
   */
  void close() throws IOException;
  /**
   * Flushes this ASN.1 writer so that any buffered elements are written
   * immediately to their intended destination. Then, if that destination is
   * another byte stream, flush it. Thus one {@code flush()} invocation will
   * flush all the buffers in a chain of streams.
   * <p>
   * If the intended destination of this stream is an abstraction provided by
   * the underlying operating system, for example a file, then flushing the
   * stream guarantees only that bytes previously written to the stream are
   * passed to the operating system for writing; it does not guarantee that they
   * are actually written to a physical device such as a disk drive.
   *
   * @throws IOException
   *           If an error occurs while flushing.
   */
  void flush() throws IOException;
  /**
   * Writes a boolean element using the Universal Boolean ASN.1 type tag.
   *
   * @param value
   *          The boolean value.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeBoolean(boolean value) throws IOException;
  /**
   * Writes a boolean element using the provided type tag.
   *
   * @param type
   *          The type tag of the element.
   * @param value
   *          The boolean value.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeBoolean(byte type, boolean value) throws IOException;
  /**
   * Finishes writing a sequence element.
   *
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   * @throws IllegalStateException
   *           If there is no sequence being written.
   */
  ASN1Writer writeEndSequence() throws IOException, IllegalStateException;
  /**
   * Finishes writing a set element.
   *
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   * @throws IllegalStateException
   *           If there is no set being written, IllegalStateException.
   */
  ASN1Writer writeEndSet() throws IOException, IllegalStateException;
  /**
   * Writes an enumerated element using the provided type tag.
   *
   * @param type
   *          The type tag of the element.
   * @param value
   *          The enumerated value.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeEnumerated(byte type, int value) throws IOException;
  /**
   * Writes an enumerated element using the Universal Enumerated ASN.1 type tag.
   *
   * @param value
   *          The enumerated value.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeEnumerated(int value) throws IOException;
  /**
   * Writes an integer element using the provided type tag.
   *
   * @param type
   *          The type tag of the element.
   * @param value
   *          The integer value.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeInteger(byte type, int value) throws IOException;
  /**
   * Writes an integer element using the provided type tag.
   *
   * @param type
   *          The type tag of the element.
   * @param value
   *          The integer value.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeInteger(byte type, long value) throws IOException;
  /**
   * Writes an integer element using the Universal Integer ASN.1 type tag.
   *
   * @param value
   *          The integer value.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeInteger(int value) throws IOException;
  /**
   * Writes an integer element using the Universal Integer ASN.1 type tag.
   *
   * @param value
   *          The integer value.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeInteger(long value) throws IOException;
  /**
   * Writes a null element using the Universal Null ASN.1 type tag.
   *
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeNull() throws IOException;
  /**
   * Writes a null element using the provided type tag.
   *
   * @param type
   *          The type tag of the element.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeNull(byte type) throws IOException;
  /**
   * Writes an octet string element using the provided type tag.
   *
   * @param type
   *          The type tag of the element.
   * @param value
   *          The byte array containing the octet string data.
   * @param offset
   *          The offset in the byte array.
   * @param length
   *          The number of bytes to write.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeOctetString(byte type, byte[] value, int offset, int length)
      throws IOException;
  /**
   * Writes an octet string element using the provided type tag.
   *
   * @param type
   *          The type tag of the element.
   * @param value
   *          The octet string value.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeOctetString(byte type, ByteSequence value) throws IOException;
  /**
   * Writes a string as a UTF-8 encoded octet string element using the provided
   * type tag.
   *
   * @param type
   *          The type tag of the element.
   * @param value
   *          The string to be written as a UTF-8 encoded octet string.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeOctetString(byte type, String value) throws IOException;
  /**
   * Writes an octet string element using the Universal Octet String ASN.1 type
   * tag.
   *
   * @param value
   *          The byte array containing the octet string data.
   * @param offset
   *          The offset in the byte array.
   * @param length
   *          The number of bytes to write.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeOctetString(byte[] value, int offset, int length)
      throws IOException;
  /**
   * Writes an octet string element using the Universal Octet String ASN.1 type
   * tag.
   *
   * @param value
   *          The octet string value.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeOctetString(ByteSequence value) throws IOException;
  /**
   * Writes a string as a UTF-8 encoded octet string element using the Universal
   * Octet String ASN.1 type tag.
   *
   * @param value
   *          The string to be written as a UTF-8 encoded octet string.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeOctetString(String value) throws IOException;
  /**
   * Writes a sequence element using the Universal Sequence ASN.1 type tag. All
   * further writes will append elements to the sequence until
   * {@link #writeEndSequence} is called.
   *
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeStartSequence() throws IOException;
  /**
   * Writes a sequence element using the provided type tag. All further writes
   * will append elements to the sequence until {@link #writeEndSequence} is
   * called.
   *
   * @param type
   *          The type tag of the element.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeStartSequence(byte type) throws IOException;
  /**
   * Writes a set element using the Universal Set ASN.1 type tag. All further
   * writes will append elements to the set until {@link #writeEndSet} is
   * called.
   *
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeStartSet() throws IOException;
  /**
   * Writes a set element using the provided type tag. All further writes will
   * append elements to the set until {@link #writeEndSet} is called.
   *
   * @param type
   *          The type tag of the element.
   * @return A reference to this ASN.1 writer.
   * @throws IOException
   *           If an error occurs while writing the element.
   */
  ASN1Writer writeStartSet(byte type) throws IOException;
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/asn1/AbstractASN1Reader.java
New file
@@ -0,0 +1,210 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.asn1;
import static org.forgerock.opendj.asn1.ASN1Constants.*;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ASN1_UNEXPECTED_TAG;
import java.io.IOException;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.DecodeException;
/**
 * An abstract {@code ASN1Reader} which can be used as the basis for
 * implementing new ASN1 reader implementations.
 */
public abstract class AbstractASN1Reader implements ASN1Reader
{
  /**
   * Creates a new abstract ASN.1 reader.
   */
  protected AbstractASN1Reader()
  {
    // No implementation required.
  }
  /**
   * {@inheritDoc}
   */
  public boolean readBoolean(byte type) throws IOException
  {
    if (type == 0x00)
    {
      type = UNIVERSAL_BOOLEAN_TYPE;
    }
    checkType(type);
    return readBoolean();
  }
  /**
   * {@inheritDoc}
   */
  public int readEnumerated(byte type) throws IOException
  {
    if (type == 0x00)
    {
      type = UNIVERSAL_ENUMERATED_TYPE;
    }
    checkType(type);
    return readEnumerated();
  }
  /**
   * {@inheritDoc}
   */
  public long readInteger(byte type) throws IOException
  {
    if (type == 0x00)
    {
      type = UNIVERSAL_INTEGER_TYPE;
    }
    checkType(type);
    return readInteger();
  }
  /**
   * {@inheritDoc}
   */
  public void readNull(byte type) throws IOException
  {
    if (type == 0x00)
    {
      type = UNIVERSAL_NULL_TYPE;
    }
    checkType(type);
    readNull();
  }
  /**
   * {@inheritDoc}
   */
  public ByteString readOctetString(byte type) throws IOException
  {
    if (type == 0x00)
    {
      type = UNIVERSAL_OCTET_STRING_TYPE;
    }
    checkType(type);
    return readOctetString();
  }
  /**
   * {@inheritDoc}
   */
  public ByteStringBuilder readOctetString(byte type,
      final ByteStringBuilder builder) throws IOException
  {
    if (type == 0x00)
    {
      type = UNIVERSAL_OCTET_STRING_TYPE;
    }
    checkType(type);
    readOctetString(builder);
    return builder;
  }
  /**
   * {@inheritDoc}
   */
  public String readOctetStringAsString(byte type) throws IOException
  {
    // We could cache the UTF-8 CharSet if performance proves to be an
    // issue.
    if (type == 0x00)
    {
      type = UNIVERSAL_OCTET_STRING_TYPE;
    }
    checkType(type);
    return readOctetStringAsString();
  }
  /**
   * {@inheritDoc}
   */
  public void readStartSequence(byte type) throws IOException
  {
    if (type == 0x00)
    {
      type = UNIVERSAL_SEQUENCE_TYPE;
    }
    checkType(type);
    readStartSequence();
  }
  /**
   * {@inheritDoc}
   */
  public void readStartSet(byte type) throws IOException
  {
    // From an implementation point of view, a set is equivalent to a
    // sequence.
    if (type == 0x00)
    {
      type = UNIVERSAL_SET_TYPE;
    }
    checkType(type);
    readStartSet();
  }
  private void checkType(final byte expectedType) throws IOException
  {
    if (peekType() != expectedType)
    {
      final LocalizableMessage message = ERR_ASN1_UNEXPECTED_TAG.get(
          expectedType, peekType());
      throw DecodeException.fatalError(message);
    }
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/asn1/AbstractASN1Writer.java
New file
@@ -0,0 +1,156 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.asn1;
import static org.forgerock.opendj.asn1.ASN1Constants.*;
import java.io.IOException;
import org.forgerock.opendj.ldap.ByteSequence;
/**
 * An abstract {@code ASN1Writer} which can be used as the basis for
 * implementing new ASN1 writer implementations.
 */
public abstract class AbstractASN1Writer implements ASN1Writer
{
  /**
   * Creates a new abstract ASN.1 writer.
   */
  protected AbstractASN1Writer()
  {
    // No implementation required.
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeBoolean(final boolean value) throws IOException
  {
    return writeBoolean(UNIVERSAL_BOOLEAN_TYPE, value);
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeEnumerated(final int value) throws IOException
  {
    return writeEnumerated(UNIVERSAL_ENUMERATED_TYPE, value);
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeInteger(final int value) throws IOException
  {
    return writeInteger(UNIVERSAL_INTEGER_TYPE, value);
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeInteger(final long value) throws IOException
  {
    return writeInteger(UNIVERSAL_INTEGER_TYPE, value);
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeNull() throws IOException
  {
    return writeNull(UNIVERSAL_NULL_TYPE);
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeOctetString(final byte[] value, final int offset,
      final int length) throws IOException
  {
    return writeOctetString(UNIVERSAL_OCTET_STRING_TYPE, value, offset, length);
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeOctetString(final ByteSequence value)
      throws IOException
  {
    return writeOctetString(UNIVERSAL_OCTET_STRING_TYPE, value);
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeOctetString(final String value) throws IOException
  {
    return writeOctetString(UNIVERSAL_OCTET_STRING_TYPE, value);
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeStartSequence() throws IOException
  {
    return writeStartSequence(UNIVERSAL_SEQUENCE_TYPE);
  }
  /**
   * {@inheritDoc}
   */
  public ASN1Writer writeStartSet() throws IOException
  {
    return writeStartSet(UNIVERSAL_SET_TYPE);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/asn1/package-info.java
New file
@@ -0,0 +1,39 @@
/*
 * 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.
 */
/**
 * Classes and interfaces for encoding and decoding ASN.1 data streams.
 * <p>
 * Note that this particular implementation is limited to the subset of elements
 * that are typically used by LDAP clients. As such, it does not include all
 * ASN.1 element types, particularly elements like OIDs, bit strings, and
 * timestamp values.
 */
package org.forgerock.opendj.asn1;
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AVA.java
New file
@@ -0,0 +1,969 @@
/*
 * 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 2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 */
package org.forgerock.opendj.ldap;
import static com.forgerock.opendj.util.StaticUtils.*;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import java.util.Comparator;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.forgerock.opendj.ldap.schema.*;
import com.forgerock.opendj.util.StaticUtils;
import com.forgerock.opendj.util.SubstringReader;
import com.forgerock.opendj.util.Validator;
/**
 * An attribute value assertion (AVA) as defined in RFC 4512 section 2.3
 * consists of an attribute description with zero options and an attribute
 * value.
 * <p>
 * The following are examples of string representations of AVAs:
 *
 * <pre>
 * uid=12345
 * ou=Engineering
 * cn=Kurt Zeilenga
 * </pre>
 *
 * @see <a href="http://tools.ietf.org/html/rfc4512#section-2.3">RFC 4512 -
 *      Lightweight Directory Access Protocol (LDAP): Directory Information
 *      Models </a>
 */
public final class AVA implements Comparable<AVA>
{
  /**
   * Parses the provided LDAP string representation of an AVA using the default
   * schema.
   *
   * @param ava
   *          The LDAP string representation of an AVA.
   * @return The parsed RDN.
   * @throws LocalizedIllegalArgumentException
   *           If {@code ava} is not a valid LDAP string representation of a
   *           AVA.
   * @throws NullPointerException
   *           If {@code ava} was {@code null}.
   */
  public static AVA valueOf(final String ava)
      throws LocalizedIllegalArgumentException, NullPointerException
  {
    return valueOf(ava, Schema.getDefaultSchema());
  }
  /**
   * Parses the provided LDAP string representation of an AVA using the provided
   * schema.
   *
   * @param ava
   *          The LDAP string representation of a AVA.
   * @param schema
   *          The schema to use when parsing the AVA.
   * @return The parsed AVA.
   * @throws LocalizedIllegalArgumentException
   *           If {@code ava} is not a valid LDAP string representation of a
   *           AVA.
   * @throws NullPointerException
   *           If {@code ava} or {@code schema} was {@code null}.
   */
  public static AVA valueOf(final String ava, final Schema schema)
      throws LocalizedIllegalArgumentException, NullPointerException
  {
    final SubstringReader reader = new SubstringReader(ava);
    try
    {
      return decode(reader, schema);
    }
    catch (final UnknownSchemaElementException e)
    {
      final LocalizableMessage message = ERR_RDN_TYPE_NOT_FOUND.get(ava,
          e.getMessageObject());
      throw new LocalizedIllegalArgumentException(message);
    }
  }
  static AVA decode(final SubstringReader reader, final Schema schema)
      throws LocalizedIllegalArgumentException, UnknownSchemaElementException
  {
    // Skip over any spaces at the beginning.
    reader.skipWhitespaces();
    if (reader.remaining() == 0)
    {
      final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ATTR_NO_NAME
          .get(reader.getString());
      throw new LocalizedIllegalArgumentException(message);
    }
    final AttributeType attribute = readAttributeName(reader, schema);
    // Skip over any spaces if we have.
    reader.skipWhitespaces();
    // Make sure that we're not at the end of the DN string because
    // that would be invalid.
    if (reader.remaining() == 0)
    {
      final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME
          .get(reader.getString(), attribute.getNameOrOID());
      throw new LocalizedIllegalArgumentException(message);
    }
    // The next character must be an equal sign. If it is not, then
    // that's an error.
    char c;
    if ((c = reader.read()) != '=')
    {
      final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_NO_EQUAL.get(
          reader.getString(), attribute.getNameOrOID(), c);
      throw new LocalizedIllegalArgumentException(message);
    }
    // Skip over any spaces after the equal sign.
    reader.skipWhitespaces();
    // Parse the value for this RDN component.
    final ByteString value = readAttributeValue(reader);
    return new AVA(attribute, value);
  }
  private static void appendHexChars(final SubstringReader reader,
      final StringBuilder valueBuffer, final StringBuilder hexBuffer)
      throws DecodeException
  {
    final int length = hexBuffer.length();
    if (length == 0)
    {
      return;
    }
    if ((length % 2) != 0)
    {
      final LocalizableMessage message = ERR_HEX_DECODE_INVALID_LENGTH
          .get(hexBuffer);
      throw DecodeException.error(message);
    }
    int pos = 0;
    final int arrayLength = (length / 2);
    final byte[] hexArray = new byte[arrayLength];
    for (int i = 0; i < arrayLength; i++)
    {
      switch (hexBuffer.charAt(pos++))
      {
      case '0':
        hexArray[i] = 0x00;
        break;
      case '1':
        hexArray[i] = 0x10;
        break;
      case '2':
        hexArray[i] = 0x20;
        break;
      case '3':
        hexArray[i] = 0x30;
        break;
      case '4':
        hexArray[i] = 0x40;
        break;
      case '5':
        hexArray[i] = 0x50;
        break;
      case '6':
        hexArray[i] = 0x60;
        break;
      case '7':
        hexArray[i] = 0x70;
        break;
      case '8':
        hexArray[i] = (byte) 0x80;
        break;
      case '9':
        hexArray[i] = (byte) 0x90;
        break;
      case 'A':
      case 'a':
        hexArray[i] = (byte) 0xA0;
        break;
      case 'B':
      case 'b':
        hexArray[i] = (byte) 0xB0;
        break;
      case 'C':
      case 'c':
        hexArray[i] = (byte) 0xC0;
        break;
      case 'D':
      case 'd':
        hexArray[i] = (byte) 0xD0;
        break;
      case 'E':
      case 'e':
        hexArray[i] = (byte) 0xE0;
        break;
      case 'F':
      case 'f':
        hexArray[i] = (byte) 0xF0;
        break;
      default:
        final LocalizableMessage message = ERR_HEX_DECODE_INVALID_CHARACTER
            .get(hexBuffer, hexBuffer.charAt(pos - 1));
        throw DecodeException.error(message);
      }
      switch (hexBuffer.charAt(pos++))
      {
      case '0':
        // No action required.
        break;
      case '1':
        hexArray[i] |= 0x01;
        break;
      case '2':
        hexArray[i] |= 0x02;
        break;
      case '3':
        hexArray[i] |= 0x03;
        break;
      case '4':
        hexArray[i] |= 0x04;
        break;
      case '5':
        hexArray[i] |= 0x05;
        break;
      case '6':
        hexArray[i] |= 0x06;
        break;
      case '7':
        hexArray[i] |= 0x07;
        break;
      case '8':
        hexArray[i] |= 0x08;
        break;
      case '9':
        hexArray[i] |= 0x09;
        break;
      case 'A':
      case 'a':
        hexArray[i] |= 0x0A;
        break;
      case 'B':
      case 'b':
        hexArray[i] |= 0x0B;
        break;
      case 'C':
      case 'c':
        hexArray[i] |= 0x0C;
        break;
      case 'D':
      case 'd':
        hexArray[i] |= 0x0D;
        break;
      case 'E':
      case 'e':
        hexArray[i] |= 0x0E;
        break;
      case 'F':
      case 'f':
        hexArray[i] |= 0x0F;
        break;
      default:
        final LocalizableMessage message = ERR_HEX_DECODE_INVALID_CHARACTER
            .get(hexBuffer, hexBuffer.charAt(pos - 1));
        throw DecodeException.error(message);
      }
    }
    try
    {
      valueBuffer.append(new String(hexArray, "UTF-8"));
    }
    catch (final Exception e)
    {
      final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ATTR_VALUE_DECODE_FAILURE
          .get(reader.getString(), String.valueOf(e));
      throw DecodeException.error(message);
    }
    // Clean up the hex buffer.
    hexBuffer.setLength(0);
  }
  private static ByteString delimitAndEvaluateEscape(
      final SubstringReader reader) throws DecodeException
  {
    char c = '\u0000';
    final StringBuilder valueBuffer = new StringBuilder();
    final StringBuilder hexBuffer = new StringBuilder();
    reader.skipWhitespaces();
    boolean escaped = false;
    while (reader.remaining() > 0)
    {
      c = reader.read();
      if (escaped)
      {
        // This character is escaped.
        if (isHexDigit(c))
        {
          // Unicode characters.
          if (!(reader.remaining() > 0))
          {
            final LocalizableMessage msg = ERR_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID
                .get(reader.getString());
            throw DecodeException.error(msg);
          }
          // Check the next byte for hex.
          final char c2 = reader.read();
          if (isHexDigit(c2))
          {
            hexBuffer.append(c);
            hexBuffer.append(c2);
            // We may be at the end.
            if (reader.remaining() == 0)
            {
              appendHexChars(reader, valueBuffer, hexBuffer);
            }
          }
          else
          {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID
                .get(reader.getString());
            throw DecodeException.error(message);
          }
        }
        else
        {
          appendHexChars(reader, valueBuffer, hexBuffer);
          valueBuffer.append(c);
        }
        escaped = false;
      }
      else if (c == 0x5C) // The backslash character
      {
        // We found an escape.
        escaped = true;
      }
      else
      {
        // Check for delimited chars.
        if (c == '+' || c == ',' || c == ';')
        {
          reader.reset();
          // Return what we have got here so far.
          appendHexChars(reader, valueBuffer, hexBuffer);
          return ByteString.valueOf(valueBuffer.toString());
        }
        // It is definitely not a delimiter at this point.
        appendHexChars(reader, valueBuffer, hexBuffer);
        valueBuffer.append(c);
        // reader.mark();
      }
      reader.mark();
    }
    reader.reset();
    return ByteString.valueOf(valueBuffer.toString());
  }
  private static AttributeType readAttributeName(final SubstringReader reader,
      final Schema schema) throws LocalizedIllegalArgumentException,
      UnknownSchemaElementException
  {
    int length = 1;
    reader.mark();
    // The next character must be either numeric (for an OID) or
    // alphabetic (for an attribute description).
    char c = reader.read();
    if (isDigit(c))
    {
      boolean lastWasPeriod = false;
      while (reader.remaining() > 0)
      {
        c = reader.read();
        if (c == '=' || c == ' ')
        {
          // This signals the end of the OID.
          break;
        }
        else if (c == '.')
        {
          if (lastWasPeriod)
          {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_OID_CONSECUTIVE_PERIODS
                .get(reader.getString(), reader.pos() - 1);
            throw new LocalizedIllegalArgumentException(message);
          }
          else
          {
            lastWasPeriod = true;
          }
        }
        else if (!isDigit(c))
        {
          // This must have been an illegal character.
          final LocalizableMessage message = ERR_ATTR_SYNTAX_OID_ILLEGAL_CHARACTER
              .get(reader.getString(), reader.pos() - 1);
          throw new LocalizedIllegalArgumentException(message);
        }
        else
        {
          lastWasPeriod = false;
        }
        length++;
      }
    }
    else if (isAlpha(c))
    {
      // This must be an attribute description. In this case, we will
      // only accept alphabetic characters, numeric digits, and the hyphen.
      while (reader.remaining() > 0)
      {
        c = reader.read();
        if (c == '=' || c == ' ')
        {
          // This signals the end of the OID.
          break;
        }
        else if (!isAlpha(c) && !isDigit(c) && c != '-')
        {
          // This is an illegal character.
          final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR
              .get(reader.getString(), c, reader.pos() - 1);
          throw new LocalizedIllegalArgumentException(message);
        }
        length++;
      }
    }
    else
    {
      final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR
          .get(reader.getString(), c, reader.pos() - 1);
      throw new LocalizedIllegalArgumentException(message);
    }
    reader.reset();
    // Return the position of the first non-space character after the
    // token.
    return schema.getAttributeType(reader.read(length));
  }
  private static ByteString readAttributeValue(final SubstringReader reader)
      throws LocalizedIllegalArgumentException
  {
    // All leading spaces have already been stripped so we can start
    // reading the value. However, it may be empty so check for that.
    if (reader.remaining() == 0)
    {
      return ByteString.empty();
    }
    reader.mark();
    // Look at the first character. If it is an octothorpe (#), then
    // that means that the value should be a hex string.
    char c = reader.read();
    int length = 0;
    if (c == '#')
    {
      // The first two characters must be hex characters.
      reader.mark();
      if (reader.remaining() < 2)
      {
        final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT
            .get(reader.getString());
        throw new LocalizedIllegalArgumentException(message);
      }
      for (int i = 0; i < 2; i++)
      {
        c = reader.read();
        if (isHexDigit(c))
        {
          length++;
        }
        else
        {
          final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT
              .get(reader.getString(), c);
          throw new LocalizedIllegalArgumentException(message);
        }
      }
      // The rest of the value must be a multiple of two hex
      // characters. The end of the value may be designated by the
      // end of the DN, a comma or semicolon, or a space.
      while (reader.remaining() > 0)
      {
        c = reader.read();
        if (isHexDigit(c))
        {
          length++;
          if (reader.remaining() > 0)
          {
            c = reader.read();
            if (isHexDigit(c))
            {
              length++;
            }
            else
            {
              final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT
                  .get(reader.getString(), c);
              throw new LocalizedIllegalArgumentException(message);
            }
          }
          else
          {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT
                .get(reader.getString());
            throw new LocalizedIllegalArgumentException(message);
          }
        }
        else if ((c == ' ') || (c == ',') || (c == ';'))
        {
          // This denotes the end of the value.
          break;
        }
        else
        {
          final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT
              .get(reader.getString(), c);
          throw new LocalizedIllegalArgumentException(message);
        }
      }
      // At this point, we should have a valid hex string. Convert it
      // to a byte array and set that as the value of the provided
      // octet string.
      try
      {
        reader.reset();
        return ByteString.wrap(hexStringToByteArray(reader.read(length)));
      }
      catch (final Exception e)
      {
        final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ATTR_VALUE_DECODE_FAILURE
            .get(reader.getString(), String.valueOf(e));
        throw new LocalizedIllegalArgumentException(message);
      }
    }
    // If the first character is a quotation mark, then the value
    // should continue until the corresponding closing quotation mark.
    else if (c == '"')
    {
      reader.mark();
      while (true)
      {
        if (reader.remaining() <= 0)
        {
          // We hit the end of the AVA before the closing quote.
          // That's an error.
          final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_UNMATCHED_QUOTE
              .get(reader.getString());
          throw new LocalizedIllegalArgumentException(message);
        }
        if (reader.read() == '"')
        {
          // This is the end of the value.
          break;
        }
        length++;
      }
      reader.reset();
      final ByteString retString = ByteString.valueOf(reader.read(length));
      reader.read();
      return retString;
    }
    // Otherwise, use general parsing to find the end of the value.
    else
    {
      reader.reset();
      ByteString bytes;
      try
      {
        bytes = delimitAndEvaluateEscape(reader);
      }
      catch (final DecodeException e)
      {
        throw new LocalizedIllegalArgumentException(e.getMessageObject());
      }
      if (bytes.length() == 0)
      {
        // We don't allow an empty attribute value.
        final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_INVALID_REQUIRES_ESCAPE_CHAR
            .get(reader.getString(), reader.pos());
        throw new LocalizedIllegalArgumentException(message);
      }
      return bytes;
    }
  }
  private final AttributeType attributeType;
  private final ByteString attributeValue;
  // Cached normalized value using equality matching rule.
  private ByteString equalityNormalizedAttributeValue = null;
  // Cached normalized value using ordering matching rule.
  private ByteString orderingNormalizedAttributeValue = null;
  /**
   * Creates a new attribute value assertion (AVA) using the provided attribute
   * type and value.
   *
   * @param attributeType
   *          The attribute type.
   * @param attributeValue
   *          The attribute value.
   * @throws NullPointerException
   *           If {@code attributeType} or {@code attributeValue} was
   *           {@code null}.
   */
  public AVA(final AttributeType attributeType, final ByteString attributeValue)
      throws NullPointerException
  {
    Validator.ensureNotNull(attributeType, attributeValue);
    this.attributeType = attributeType;
    this.attributeValue = attributeValue;
  }
  /**
   * Creates a new attribute value assertion (AVA) using the provided attribute
   * type and value decoded using the default schema.
   * <p>
   * If {@code attributeValue} is not an instance of {@code ByteString} then it
   * will be converted using the {@link ByteString#valueOf(Object)} method.
   *
   * @param attributeType
   *          The attribute type.
   * @param attributeValue
   *          The attribute value.
   * @throws UnknownSchemaElementException
   *           If {@code attributeType} was not found in the default schema.
   * @throws NullPointerException
   *           If {@code attributeType} or {@code attributeValue} was
   *           {@code null}.
   */
  public AVA(final String attributeType, final Object attributeValue)
      throws UnknownSchemaElementException, NullPointerException
  {
    Validator.ensureNotNull(attributeType, attributeValue);
    this.attributeType = Schema.getDefaultSchema().getAttributeType(
        attributeType);
    this.attributeValue = ByteString.valueOf(attributeValue);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int compareTo(final AVA ava)
  {
    final int result = attributeType.compareTo(ava.attributeType);
    if (result != 0)
    {
      return result > 0 ? 1 : -1;
    }
    final ByteString normalizedValue = getOrderingNormalizedValue();
    final ByteString otherNormalizedValue = ava.getOrderingNormalizedValue();
    final MatchingRule rule = attributeType.getOrderingMatchingRule();
    if (rule != null)
    {
      final Comparator<ByteSequence> comparator = rule.comparator();
      return comparator.compare(normalizedValue, otherNormalizedValue);
    }
    else
    {
      return normalizedValue.compareTo(otherNormalizedValue);
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean equals(final Object obj)
  {
    if (this == obj)
    {
      return true;
    }
    else if (obj instanceof AVA)
    {
      final AVA ava = (AVA) obj;
      if (!attributeType.equals(ava.attributeType))
      {
        return false;
      }
      final ByteString normalizedValue = getEqualityNormalizedValue();
      final ByteString otherNormalizedValue = ava.getEqualityNormalizedValue();
      final MatchingRule rule = attributeType.getEqualityMatchingRule();
      if (rule != null)
      {
        final Comparator<ByteSequence> comparator = rule.comparator();
        return comparator.compare(normalizedValue, otherNormalizedValue) != 0 ? false
            : true;
      }
      else
      {
        return normalizedValue.equals(otherNormalizedValue);
      }
    }
    else
    {
      return false;
    }
  }
  /**
   * Returns the attribute type associated with this AVA.
   *
   * @return The attribute type associated with this AVA.
   */
  public AttributeType getAttributeType()
  {
    return attributeType;
  }
  /**
   * Returns the attribute value associated with this AVA.
   *
   * @return The attribute value associated with this AVA.
   */
  public ByteString getAttributeValue()
  {
    return attributeValue;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int hashCode()
  {
    return attributeType.hashCode() * 31
        + getEqualityNormalizedValue().hashCode();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    final StringBuilder builder = new StringBuilder();
    return toString(builder).toString();
  }
  StringBuilder toString(final StringBuilder builder)
  {
    if (!attributeType.getNames().iterator().hasNext())
    {
      builder.append(attributeType.getOID());
      builder.append("=#");
      StaticUtils.toHex(attributeValue, builder);
    }
    else
    {
      final String name = attributeType.getNameOrOID();
      builder.append(name);
      builder.append("=");
      final Syntax syntax = attributeType.getSyntax();
      if (!syntax.isHumanReadable())
      {
        builder.append("#");
        StaticUtils.toHex(attributeValue, builder);
      }
      else
      {
        final String str = attributeValue.toString();
        if (str.length() == 0)
        {
          return builder;
        }
        char c = str.charAt(0);
        int startPos = 0;
        if ((c == ' ') || (c == '#'))
        {
          builder.append('\\');
          builder.append(c);
          startPos = 1;
        }
        final int length = str.length();
        for (int si = startPos; si < length; si++)
        {
          c = str.charAt(si);
          if (c < ' ')
          {
            for (final byte b : getBytes(String.valueOf(c)))
            {
              builder.append('\\');
              builder.append(StaticUtils.byteToLowerHex(b));
            }
          }
          else
          {
            if ((c == ' ' && si == length - 1)
                || (c == '"' || c == '+' || c == ',' || c == ';' || c == '<'
                    || c == '=' || c == '>' || c == '\\' || c == '\u0000'))
            {
              builder.append('\\');
            }
            builder.append(c);
          }
        }
      }
    }
    return builder;
  }
  private ByteString getEqualityNormalizedValue()
  {
    final ByteString normalizedValue = equalityNormalizedAttributeValue;
    if (normalizedValue != null)
    {
      return normalizedValue;
    }
    final MatchingRule matchingRule = attributeType.getEqualityMatchingRule();
    if (matchingRule != null)
    {
      try
      {
        equalityNormalizedAttributeValue = matchingRule
            .normalizeAttributeValue(attributeValue);
      }
      catch (final DecodeException de)
      {
        // Unable to normalize, so default to byte-wise comparison.
        equalityNormalizedAttributeValue = attributeValue;
      }
    }
    else
    {
      // No matching rule, so default to byte-wise comparison.
      equalityNormalizedAttributeValue = attributeValue;
    }
    return equalityNormalizedAttributeValue;
  }
  private ByteString getOrderingNormalizedValue()
  {
    final ByteString normalizedValue = orderingNormalizedAttributeValue;
    if (normalizedValue != null)
    {
      return normalizedValue;
    }
    final MatchingRule matchingRule = attributeType.getEqualityMatchingRule();
    if (matchingRule != null)
    {
      try
      {
        orderingNormalizedAttributeValue = matchingRule
            .normalizeAttributeValue(attributeValue);
      }
      catch (final DecodeException de)
      {
        // Unable to normalize, so default to equality matching.
        orderingNormalizedAttributeValue = getEqualityNormalizedValue();
      }
    }
    else
    {
      // No matching rule, so default to equality matching.
      orderingNormalizedAttributeValue = getEqualityNormalizedValue();
    }
    return orderingNormalizedAttributeValue;
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java
New file
@@ -0,0 +1,430 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_NO_SEARCH_RESULT_ENTRIES;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import org.forgerock.opendj.ldap.schema.Schema;
/**
 * This class provides a skeletal implementation of the
 * {@code AsynchronousConnection} interface, to minimize the effort required to
 * implement this interface.
 */
public abstract class AbstractAsynchronousConnection implements
    AsynchronousConnection
{
  private static final class SingleEntryFuture implements
      FutureResult<SearchResultEntry>, SearchResultHandler
  {
    private final ResultHandler<? super SearchResultEntry> handler;
    private volatile SearchResultEntry firstEntry = null;
    private volatile SearchResultReference firstReference = null;
    private volatile int entryCount = 0;
    private volatile FutureResult<Result> future = null;
    private SingleEntryFuture(
        final ResultHandler<? super SearchResultEntry> handler)
    {
      this.handler = handler;
    }
    public boolean cancel(final boolean mayInterruptIfRunning)
    {
      return future.cancel(mayInterruptIfRunning);
    }
    public SearchResultEntry get() throws ErrorResultException,
        InterruptedException
    {
      future.get();
      return get0();
    }
    public SearchResultEntry get(final long timeout, final TimeUnit unit)
        throws ErrorResultException, TimeoutException, InterruptedException
    {
      future.get(timeout, unit);
      return get0();
    }
    public int getRequestID()
    {
      return future.getRequestID();
    }
    public boolean handleEntry(final SearchResultEntry entry)
    {
      if (firstEntry == null)
      {
        firstEntry = entry;
      }
      entryCount++;
      return true;
    }
    public void handleErrorResult(final ErrorResultException error)
    {
      if (handler != null)
      {
        handler.handleErrorResult(error);
      }
    }
    public boolean handleReference(final SearchResultReference reference)
    {
      if (firstReference == null)
      {
        firstReference = reference;
      }
      return true;
    }
    public void handleResult(final Result result)
    {
      if (handler != null)
      {
        try
        {
          handler.handleResult(get0());
        }
        catch (final ErrorResultException e)
        {
          handler.handleErrorResult(e);
        }
      }
    }
    public boolean isCancelled()
    {
      return future.isCancelled();
    }
    public boolean isDone()
    {
      return future.isDone();
    }
    private SearchResultEntry get0() throws ErrorResultException
    {
      if (entryCount == 0)
      {
        // Did not find any entries.
        final Result result = Responses.newResult(
            ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED).setDiagnosticMessage(
            ERR_NO_SEARCH_RESULT_ENTRIES.get().toString());
        throw ErrorResultException.wrap(result);
      }
      else if (entryCount > 1)
      {
        // Got more entries than expected.
        final Result result = Responses
            .newResult(ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED)
            .setDiagnosticMessage(
                ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES.get(entryCount).toString());
        throw ErrorResultException.wrap(result);
      }
      else if (firstReference != null)
      {
        // Got an unexpected search result reference.
        final Result result = Responses.newResult(
            ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED)
            .setDiagnosticMessage(
                ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES.get(
                    firstReference.getURIs().iterator().next()).toString());
        throw ErrorResultException.wrap(result);
      }
      else
      {
        return firstEntry;
      }
    }
    private void setResultFuture(final FutureResult<Result> future)
    {
      this.future = future;
    }
  }
  /**
   * Creates a new abstract connection.
   */
  protected AbstractAsynchronousConnection()
  {
    // No implementation required.
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<Result> add(final AddRequest request,
      final ResultHandler<? super Result> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    return add(request, handler, null);
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<BindResult> bind(final BindRequest request,
      final ResultHandler<? super BindResult> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    return bind(request, handler, null);
  }
  /**
   * {@inheritDoc}
   */
  public void close()
  {
    close(Requests.newUnbindRequest(), null);
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<CompareResult> compare(final CompareRequest request,
      final ResultHandler<? super CompareResult> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    return compare(request, handler, null);
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<Result> delete(final DeleteRequest request,
      final ResultHandler<? super Result> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    return delete(request, handler, null);
  }
  /**
   * {@inheritDoc}
   */
  public <R extends ExtendedResult> FutureResult<R> extendedRequest(
      final ExtendedRequest<R> request, final ResultHandler<? super R> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    return extendedRequest(request, handler, null);
  }
  /**
   * {@inheritDoc}
   */
  public Connection getSynchronousConnection()
  {
    return new SynchronousConnection(this);
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<Result> modify(final ModifyRequest request,
      final ResultHandler<? super Result> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    return modify(request, handler, null);
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<Result> modifyDN(final ModifyDNRequest request,
      final ResultHandler<? super Result> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    return modifyDN(request, handler, null);
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<SearchResultEntry> readEntry(final DN name,
      final Collection<String> attributeDescriptions,
      final ResultHandler<? super SearchResultEntry> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    final SearchRequest request = Requests.newSearchRequest(name,
        SearchScope.BASE_OBJECT, Filter.getObjectClassPresentFilter());
    request.getAttributes().addAll(attributeDescriptions);
    return searchSingleEntry(request, handler);
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<RootDSE> readRootDSE(
      final ResultHandler<? super RootDSE> handler)
      throws UnsupportedOperationException, IllegalStateException
  {
    return RootDSE.readRootDSE(this, handler);
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<Schema> readSchema(final DN name,
      final ResultHandler<? super Schema> handler)
      throws UnsupportedOperationException, IllegalStateException
  {
    return Schema.readSchema(this, name, handler);
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<Schema> readSchemaForEntry(final DN name,
      final ResultHandler<? super Schema> handler)
      throws UnsupportedOperationException, IllegalStateException
  {
    return Schema.readSchema(this, name, handler);
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<Result> search(final SearchRequest request,
      final SearchResultHandler handler) throws UnsupportedOperationException,
      IllegalStateException, NullPointerException
  {
    return search(request, handler, null);
  }
  /**
   * {@inheritDoc}
   */
  public FutureResult<SearchResultEntry> searchSingleEntry(
      final SearchRequest request,
      final ResultHandler<? super SearchResultEntry> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    final SingleEntryFuture innerFuture = new SingleEntryFuture(handler);
    final FutureResult<Result> future = search(request, innerFuture);
    innerFuture.setResultFuture(future);
    return innerFuture;
  }
  /**
   * {@inheritDoc}
   * <p>
   * Sub-classes should provide an implementation which returns an appropriate
   * description of the connection which may be used for debugging purposes.
   */
  public abstract String toString();
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAttribute.java
New file
@@ -0,0 +1,497 @@
/*
 * 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.forgerock.opendj.ldap;
import java.util.*;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.MatchingRule;
import com.forgerock.opendj.util.Validator;
/**
 * This class provides a skeletal implementation of the {@code Attribute}
 * interface, to minimize the effort required to implement this interface.
 */
public abstract class AbstractAttribute extends AbstractSet<ByteString>
    implements Attribute
{
  /**
   * Returns {@code true} if {@code object} is an attribute which is equal to
   * {@code attribute}. Two attributes are considered equal if their attribute
   * descriptions are equal, they both have the same number of attribute values,
   * and every attribute value contained in the first attribute is also
   * contained in the second attribute.
   *
   * @param attribute
   *          The attribute to be tested for equality.
   * @param object
   *          The object to be tested for equality with the attribute.
   * @return {@code true} if {@code object} is an attribute which is equal to
   *         {@code attribute}, or {@code false} if not.
   */
  static boolean equals(final Attribute attribute, final Object object)
  {
    if (attribute == object)
    {
      return true;
    }
    if (!(object instanceof Attribute))
    {
      return false;
    }
    final Attribute other = (Attribute) object;
    if (!attribute.getAttributeDescription().equals(
        other.getAttributeDescription()))
    {
      return false;
    }
    // Attribute description is the same, compare values.
    if (attribute.size() != other.size())
    {
      return false;
    }
    return attribute.containsAll(other);
  }
  /**
   * Returns the hash code for {@code attribute}. It will be calculated as the
   * sum of the hash codes of the attribute description and all of the attribute
   * values.
   *
   * @param attribute
   *          The attribute whose hash code should be calculated.
   * @return The hash code for {@code attribute}.
   */
  static int hashCode(final Attribute attribute)
  {
    int hashCode = attribute.getAttributeDescription().hashCode();
    for (final ByteString value : attribute)
    {
      hashCode += normalizeValue(attribute, value).hashCode();
    }
    return hashCode;
  }
  /**
   * Returns the normalized form of {@code value} normalized using {@code
   * attribute}'s equality matching rule.
   *
   * @param attribute
   *          The attribute whose equality matching rule should be used for
   *          normalization.
   * @param value
   *          The attribute value to be normalized.
   * @return The normalized form of {@code value} normalized using {@code
   *         attribute}'s equality matching rule.
   */
  static ByteString normalizeValue(final Attribute attribute,
      final ByteString value)
  {
    final AttributeDescription attributeDescription = attribute
        .getAttributeDescription();
    final AttributeType attributeType = attributeDescription.getAttributeType();
    final MatchingRule matchingRule = attributeType.getEqualityMatchingRule();
    try
    {
      return matchingRule.normalizeAttributeValue(value);
    }
    catch (final Exception e)
    {
      // Fall back to provided value.
      return value;
    }
  }
  /**
   * Returns a string representation of {@code attribute}.
   *
   * @param attribute
   *          The attribute whose string representation should be returned.
   * @return The string representation of {@code attribute}.
   */
  static String toString(final Attribute attribute)
  {
    final StringBuilder builder = new StringBuilder();
    builder.append("Attribute(");
    builder.append(attribute.getAttributeDescriptionAsString());
    builder.append(", {");
    boolean firstValue = true;
    for (final ByteString value : attribute)
    {
      if (!firstValue)
      {
        builder.append(", ");
      }
      builder.append(value);
      firstValue = false;
    }
    builder.append("})");
    return builder.toString();
  }
  /**
   * Sole constructor.
   */
  protected AbstractAttribute()
  {
    // No implementation required.
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public abstract boolean add(ByteString value)
      throws UnsupportedOperationException, NullPointerException;
  /**
   * {@inheritDoc}
   */
  public boolean add(final Object firstValue, final Object... remainingValues)
      throws UnsupportedOperationException, NullPointerException
  {
    Validator.ensureNotNull(firstValue);
    boolean modified = add(ByteString.valueOf(firstValue));
    if (remainingValues != null)
    {
      for (final Object value : remainingValues)
      {
        modified |= add(ByteString.valueOf(value));
      }
    }
    return modified;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean addAll(final Collection<? extends ByteString> values)
      throws UnsupportedOperationException, NullPointerException
  {
    return addAll(values, null);
  }
  /**
   * {@inheritDoc}
   */
  public boolean addAll(final Collection<? extends ByteString> values,
      final Collection<? super ByteString> duplicateValues)
      throws UnsupportedOperationException, NullPointerException
  {
    boolean modified = false;
    for (final ByteString value : values)
    {
      if (add(value))
      {
        modified = true;
      }
      else if (duplicateValues != null)
      {
        duplicateValues.add(value);
      }
    }
    return modified;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public abstract boolean contains(Object value) throws NullPointerException;
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean containsAll(final Collection<?> values)
      throws NullPointerException
  {
    for (final Object value : values)
    {
      if (!contains(value))
      {
        return false;
      }
    }
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean equals(final Object object)
  {
    return equals(this, object);
  }
  /**
   * {@inheritDoc}
   */
  public ByteString firstValue() throws NoSuchElementException
  {
    return iterator().next();
  }
  /**
   * {@inheritDoc}
   */
  public String firstValueAsString() throws NoSuchElementException
  {
    return firstValue().toString();
  }
  /**
   * {@inheritDoc}
   */
  public abstract AttributeDescription getAttributeDescription();
  /**
   * {@inheritDoc}
   */
  public String getAttributeDescriptionAsString()
  {
    return getAttributeDescription().toString();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int hashCode()
  {
    return hashCode(this);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public abstract Iterator<ByteString> iterator();
  /**
   * {@inheritDoc}
   */
  @Override
  public abstract boolean remove(Object value)
      throws UnsupportedOperationException, NullPointerException;
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean removeAll(final Collection<?> values)
      throws UnsupportedOperationException, NullPointerException
  {
    return removeAll(values, null);
  }
  /**
   * {@inheritDoc}
   */
  public <T> boolean removeAll(final Collection<T> values,
      final Collection<? super T> missingValues)
      throws UnsupportedOperationException, NullPointerException
  {
    boolean modified = false;
    for (final T value : values)
    {
      if (remove(value))
      {
        modified = true;
      }
      else if (missingValues != null)
      {
        missingValues.add(value);
      }
    }
    return modified;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean retainAll(final Collection<?> values)
      throws UnsupportedOperationException, NullPointerException
  {
    return retainAll(values, null);
  }
  /**
   * {@inheritDoc}
   */
  public <T> boolean retainAll(final Collection<T> values,
      final Collection<? super T> missingValues)
      throws UnsupportedOperationException, NullPointerException
  {
    if (values.isEmpty())
    {
      if (isEmpty())
      {
        return false;
      }
      else
      {
        clear();
        return true;
      }
    }
    if (isEmpty())
    {
      if (missingValues != null)
      {
        for (final T value : values)
        {
          missingValues.add(value);
        }
      }
      return false;
    }
    final Map<ByteString, T> valuesToRetain = new HashMap<ByteString, T>(values
        .size());
    for (final T value : values)
    {
      valuesToRetain
          .put(normalizeValue(this, ByteString.valueOf(value)), value);
    }
    boolean modified = false;
    final Iterator<ByteString> iterator = iterator();
    while (iterator.hasNext())
    {
      final ByteString value = iterator.next();
      final ByteString normalizedValue = normalizeValue(this, value);
      if (valuesToRetain.remove(normalizedValue) == null)
      {
        modified = true;
        iterator.remove();
      }
    }
    if (missingValues != null)
    {
      missingValues.addAll(valuesToRetain.values());
    }
    return modified;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public abstract int size();
  /**
   * {@inheritDoc}
   */
  @Override
  public ByteString[] toArray()
  {
    return toArray(new ByteString[size()]);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    return toString(this);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java
New file
@@ -0,0 +1,495 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_NO_SEARCH_RESULT_ENTRIES;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES;
import java.util.Collection;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.responses.*;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldif.ConnectionEntryReader;
import com.forgerock.opendj.util.Validator;
/**
 * This class provides a skeletal implementation of the {@code Connection}
 * interface, to minimize the effort required to implement this interface.
 */
public abstract class AbstractConnection implements Connection
{
  private static final class SingleEntryHandler implements SearchResultHandler
  {
    private volatile SearchResultEntry firstEntry = null;
    private volatile SearchResultReference firstReference = null;
    private volatile int entryCount = 0;
    public boolean handleEntry(final SearchResultEntry entry)
    {
      if (firstEntry == null)
      {
        firstEntry = entry;
      }
      entryCount++;
      return true;
    }
    public boolean handleReference(final SearchResultReference reference)
    {
      if (firstReference == null)
      {
        firstReference = reference;
      }
      return true;
    }
    /**
     * {@inheritDoc}
     */
    public void handleErrorResult(ErrorResultException error)
    {
      // Ignore.
    }
    /**
     * {@inheritDoc}
     */
    public void handleResult(Result result)
    {
      // Ignore.
    }
  }
  /**
   * Creates a new abstract connection.
   */
  protected AbstractConnection()
  {
    // No implementation required.
  }
  /**
   * {@inheritDoc}
   */
  public Result add(final Entry entry) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException, NullPointerException
  {
    return add(Requests.newAddRequest(entry));
  }
  /**
   * {@inheritDoc}
   */
  public Result add(final String... ldifLines) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      LocalizedIllegalArgumentException, IllegalStateException,
      NullPointerException
  {
    return add(Requests.newAddRequest(ldifLines));
  }
  /**
   * {@inheritDoc}
   */
  public BindResult bind(final String name, final char[] password)
      throws ErrorResultException, InterruptedException,
      LocalizedIllegalArgumentException, UnsupportedOperationException,
      IllegalStateException, NullPointerException
  {
    return bind(Requests.newSimpleBindRequest(name, password));
  }
  /**
   * {@inheritDoc}
   */
  public CompareResult compare(final String name,
      final String attributeDescription, final String assertionValue)
      throws ErrorResultException, InterruptedException,
      LocalizedIllegalArgumentException, UnsupportedOperationException,
      IllegalStateException, NullPointerException
  {
    return compare(Requests.newCompareRequest(name, attributeDescription,
        assertionValue));
  }
  /**
   * {@inheritDoc}
   */
  public Result delete(final String name) throws ErrorResultException,
      InterruptedException, LocalizedIllegalArgumentException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    return delete(Requests.newDeleteRequest(name));
  }
  /**
   * {@inheritDoc}
   */
  public GenericExtendedResult extendedRequest(final String requestName,
      final ByteString requestValue) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException, NullPointerException
  {
    return extendedRequest(Requests.newGenericExtendedRequest(requestName,
        requestValue));
  }
  /**
   * {@inheritDoc}
   */
  public Result modify(final String... ldifLines) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      LocalizedIllegalArgumentException, IllegalStateException,
      NullPointerException
  {
    return modify(Requests.newModifyRequest(ldifLines));
  }
  /**
   * {@inheritDoc}
   */
  public Result modifyDN(final String name, final String newRDN)
      throws ErrorResultException, InterruptedException,
      LocalizedIllegalArgumentException, UnsupportedOperationException,
      IllegalStateException, NullPointerException
  {
    return modifyDN(Requests.newModifyDNRequest(name, newRDN));
  }
  /**
   * {@inheritDoc}
   */
  public SearchResultEntry readEntry(final DN baseObject,
      final String... attributeDescriptions) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException, NullPointerException
  {
    final SearchRequest request = Requests.newSearchRequest(baseObject,
        SearchScope.BASE_OBJECT, Filter.getObjectClassPresentFilter(),
        attributeDescriptions);
    return searchSingleEntry(request);
  }
  /**
   * {@inheritDoc}
   */
  public SearchResultEntry readEntry(final String baseObject,
      final String... attributeDescriptions) throws ErrorResultException,
      InterruptedException, LocalizedIllegalArgumentException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    return readEntry(DN.valueOf(baseObject));
  }
  /**
   * {@inheritDoc}
   */
  public RootDSE readRootDSE() throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException
  {
    return RootDSE.readRootDSE(this);
  }
  /**
   * {@inheritDoc}
   */
  public Schema readSchema(final DN name) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException
  {
    return Schema.readSchema(this, name);
  }
  /**
   * {@inheritDoc}
   */
  public Schema readSchema(final String name) throws ErrorResultException,
      InterruptedException, LocalizedIllegalArgumentException,
      UnsupportedOperationException, IllegalStateException
  {
    return readSchema(DN.valueOf(name));
  }
  /**
   * {@inheritDoc}
   */
  public Schema readSchemaForEntry(final DN name) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException
  {
    return Schema.readSchemaForEntry(this, name);
  }
  /**
   * {@inheritDoc}
   */
  public Schema readSchemaForEntry(final String name)
      throws ErrorResultException, InterruptedException,
      LocalizedIllegalArgumentException, UnsupportedOperationException,
      IllegalStateException
  {
    return readSchemaForEntry(DN.valueOf(name));
  }
  /**
   * {@inheritDoc}
   */
  public Schema readSchemaForRootDSE() throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException
  {
    return readSchemaForEntry(DN.rootDN());
  }
  /**
   * {@inheritDoc}
   */
  public Result search(final SearchRequest request,
      final Collection<? super SearchResultEntry> entries)
      throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    return search(request, entries, null);
  }
  /**
   * {@inheritDoc}
   */
  public Result search(final SearchRequest request,
      final Collection<? super SearchResultEntry> entries,
      final Collection<? super SearchResultReference> references)
      throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    Validator.ensureNotNull(request, entries);
    // FIXME: does this need to be thread safe?
    final SearchResultHandler handler = new SearchResultHandler()
    {
      public boolean handleEntry(final SearchResultEntry entry)
      {
        entries.add(entry);
        return true;
      }
      public boolean handleReference(final SearchResultReference reference)
      {
        if (references != null)
        {
          references.add(reference);
        }
        return true;
      }
      /**
       * {@inheritDoc}
       */
      public void handleErrorResult(ErrorResultException error)
      {
        // Ignore.
      }
      /**
       * {@inheritDoc}
       */
      public void handleResult(Result result)
      {
        // Ignore.
      }
    };
    return search(request, handler);
  }
  /**
   * {@inheritDoc}
   */
  public ConnectionEntryReader search(final String baseObject,
      final SearchScope scope, final String filter,
      final String... attributeDescriptions)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    final BlockingQueue<Response> entries = new LinkedBlockingQueue<Response>();
    final SearchRequest request = Requests.newSearchRequest(baseObject, scope,
        filter, attributeDescriptions);
    return search(request, entries);
  }
  /**
   * {@inheritDoc}
   */
  public SearchResultEntry searchSingleEntry(final SearchRequest request)
      throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    final SingleEntryHandler handler = new SingleEntryHandler();
    search(request, handler);
    if (handler.entryCount == 0)
    {
      // Did not find any entries.
      final Result result = Responses.newResult(
          ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED).setDiagnosticMessage(
          ERR_NO_SEARCH_RESULT_ENTRIES.get().toString());
      throw ErrorResultException.wrap(result);
    }
    else if (handler.entryCount > 1)
    {
      // Got more entries than expected.
      final Result result = Responses.newResult(
          ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED)
          .setDiagnosticMessage(
              ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES.get(handler.entryCount)
                  .toString());
      throw ErrorResultException.wrap(result);
    }
    else if (handler.firstReference != null)
    {
      // Got an unexpected search result reference.
      final Result result = Responses.newResult(
          ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED)
          .setDiagnosticMessage(
              ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES.get(
                  handler.firstReference.getURIs().iterator().next())
                  .toString());
      throw ErrorResultException.wrap(result);
    }
    else
    {
      return handler.firstEntry;
    }
  }
  /**
   * {@inheritDoc}
   */
  public SearchResultEntry searchSingleEntry(final String baseObject,
      final SearchScope scope, final String filter,
      final String... attributeDescriptions) throws ErrorResultException,
      InterruptedException, LocalizedIllegalArgumentException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException
  {
    final SearchRequest request = Requests.newSearchRequest(baseObject, scope,
        filter, attributeDescriptions);
    return searchSingleEntry(request);
  }
  /**
   * {@inheritDoc}
   * <p>
   * Sub-classes should provide an implementation which returns an appropriate
   * description of the connection which may be used for debugging purposes.
   */
  public abstract String toString();
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnectionFactory.java
New file
@@ -0,0 +1,90 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
/**
 * This class provides a skeletal implementation of the {@code
 * ConnectionFactory} interface, to minimize the effort required to implement
 * this interface.
 */
public abstract class AbstractConnectionFactory implements ConnectionFactory
{
  /**
   * Creates a new abstract connection factory.
   */
  protected AbstractConnectionFactory()
  {
    // Nothing to do.
  }
  /**
   * {@inheritDoc}
   */
  public abstract FutureResult<AsynchronousConnection> getAsynchronousConnection(
      ResultHandler<? super AsynchronousConnection> handler);
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to convert the asynchronous connection
   * returned from {@code blockingGetAsynchronousConnection()} to a synchronous
   * connection using a {@link SynchronousConnection} as per the following code:
   *
   * <pre>
   * return new SynchronousConnection(blockingGetAsynchronousConnection());
   * </pre>
   *
   * Implementations should override this method if they wish to return a
   * different type of synchronous connection.
   *
   * @return A connection to the Directory Server associated with this
   *         connection factory.
   * @throws ErrorResultException
   *           If the connection request failed for some reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   */
  public Connection getConnection() throws ErrorResultException,
      InterruptedException
  {
    return getAsynchronousConnection(null).get().getSynchronousConnection();
  }
  /**
   * {@inheritDoc}
   */
  public abstract String toString();
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractEntry.java
New file
@@ -0,0 +1,389 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import java.util.Collection;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import com.forgerock.opendj.util.Iterables;
import com.forgerock.opendj.util.Predicate;
import com.forgerock.opendj.util.Validator;
/**
 * This class provides a skeletal implementation of the {@code Entry} interface,
 * to minimize the effort required to implement this interface.
 */
public abstract class AbstractEntry implements Entry
{
  // Predicate used for findAttributes.
  private static final Predicate<Attribute, AttributeDescription>
    FIND_ATTRIBUTES_PREDICATE = new Predicate<Attribute, AttributeDescription>()
  {
    public boolean matches(final Attribute value, final AttributeDescription p)
    {
      return value.getAttributeDescription().isSubTypeOf(p);
    }
  };
  /**
   * Returns {@code true} if {@code object} is an entry which is equal to
   * {@code entry}. Two entry are considered equal if their distinguished names
   * are equal, they both have the same number of attributes, and every
   * attribute contained in the first entry is also contained in the second
   * entry.
   *
   * @param entry
   *          The entry to be tested for equality.
   * @param object
   *          The object to be tested for equality with the entry.
   * @return {@code true} if {@code object} is an entry which is equal to
   *         {@code entry}, or {@code false} if not.
   */
  static boolean equals(final Entry entry, final Object object)
  {
    if (entry == object)
    {
      return true;
    }
    if (!(object instanceof Entry))
    {
      return false;
    }
    final Entry other = (Entry) object;
    if (!entry.getName().equals(other.getName()))
    {
      return false;
    }
    // Distinguished name is the same, compare attributes.
    if (entry.getAttributeCount() != other.getAttributeCount())
    {
      return false;
    }
    for (final Attribute attribute : entry.getAllAttributes())
    {
      final Attribute otherAttribute = other.getAttribute(attribute
          .getAttributeDescription());
      if (!attribute.equals(otherAttribute))
      {
        return false;
      }
    }
    return true;
  }
  /**
   * Returns the hash code for {@code entry}. It will be calculated as the sum
   * of the hash codes of the distinguished name and all of the attributes.
   *
   * @param entry
   *          The entry whose hash code should be calculated.
   * @return The hash code for {@code entry}.
   */
  static int hashCode(final Entry entry)
  {
    int hashCode = entry.getName().hashCode();
    for (final Attribute attribute : entry.getAllAttributes())
    {
      hashCode += attribute.hashCode();
    }
    return hashCode;
  }
  /**
   * Returns a string representation of {@code entry}.
   *
   * @param entry
   *          The entry whose string representation should be returned.
   * @return The string representation of {@code entry}.
   */
  static String toString(final Entry entry)
  {
    final StringBuilder builder = new StringBuilder();
    builder.append("Entry(");
    builder.append(entry.getName());
    builder.append(", {");
    boolean firstValue = true;
    for (final Attribute attribute : entry.getAllAttributes())
    {
      if (!firstValue)
      {
        builder.append(", ");
      }
      builder.append(attribute);
      firstValue = false;
    }
    builder.append("})");
    return builder.toString();
  }
  /**
   * Sole constructor.
   */
  protected AbstractEntry()
  {
    // No implementation required.
  }
  /**
   * {@inheritDoc}
   */
  public boolean addAttribute(final Attribute attribute)
      throws UnsupportedOperationException, NullPointerException
  {
    return addAttribute(attribute, null);
  }
  /**
   * {@inheritDoc}
   */
  public Entry addAttribute(final String attributeDescription,
      final Object... values) throws LocalizedIllegalArgumentException,
      UnsupportedOperationException, NullPointerException
  {
    addAttribute(new LinkedAttribute(attributeDescription, values), null);
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public boolean containsAttribute(final Attribute attribute,
      final Collection<ByteString> missingValues) throws NullPointerException
  {
    final Attribute a = getAttribute(attribute.getAttributeDescription());
    if (a == null)
    {
      if (missingValues != null)
      {
        missingValues.addAll(attribute);
      }
      return false;
    }
    else
    {
      boolean result = true;
      for (final ByteString value : attribute)
      {
        if (!a.contains(value))
        {
          if (missingValues != null)
          {
            missingValues.add(value);
          }
          result = false;
        }
      }
      return result;
    }
  }
  /**
   * {@inheritDoc}
   */
  public boolean containsAttribute(final String attributeDescription,
      final Object... values) throws LocalizedIllegalArgumentException,
      NullPointerException
  {
    return containsAttribute(new LinkedAttribute(attributeDescription, values),
        null);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean equals(final Object object)
  {
    return equals(this, object);
  }
  /**
   * {@inheritDoc}
   */
  public Iterable<Attribute> getAllAttributes(
      final AttributeDescription attributeDescription)
      throws NullPointerException
  {
    Validator.ensureNotNull(attributeDescription);
    return Iterables.filteredIterable(getAllAttributes(), FIND_ATTRIBUTES_PREDICATE,
        attributeDescription);
  }
  /**
   * {@inheritDoc}
   */
  public Iterable<Attribute> getAllAttributes(final String attributeDescription)
      throws LocalizedIllegalArgumentException, NullPointerException
  {
    return getAllAttributes(AttributeDescription.valueOf(attributeDescription));
  }
  /**
   * {@inheritDoc}
   */
  public Attribute getAttribute(final String attributeDescription)
      throws LocalizedIllegalArgumentException, NullPointerException
  {
    return getAttribute(AttributeDescription.valueOf(attributeDescription));
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int hashCode()
  {
    return hashCode(this);
  }
  /**
   * {@inheritDoc}
   */
  public boolean removeAttribute(final AttributeDescription attributeDescription)
      throws UnsupportedOperationException, NullPointerException
  {
    return removeAttribute(
        Attributes.emptyAttribute(attributeDescription), null);
  }
  /**
   * {@inheritDoc}
   */
  public Entry removeAttribute(final String attributeDescription,
      final Object... values) throws LocalizedIllegalArgumentException,
      UnsupportedOperationException, NullPointerException
  {
    removeAttribute(new LinkedAttribute(attributeDescription, values), null);
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public boolean replaceAttribute(final Attribute attribute)
      throws UnsupportedOperationException, NullPointerException
  {
    if (attribute.isEmpty())
    {
      return removeAttribute(attribute.getAttributeDescription());
    }
    else
    {
      removeAttribute(attribute.getAttributeDescription());
      addAttribute(attribute, null);
      return true;
    }
  }
  /**
   * {@inheritDoc}
   */
  public Entry replaceAttribute(final String attributeDescription,
      final Object... values) throws LocalizedIllegalArgumentException,
      UnsupportedOperationException, NullPointerException
  {
    replaceAttribute(new LinkedAttribute(attributeDescription, values));
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public Entry setName(final String dn)
      throws LocalizedIllegalArgumentException, UnsupportedOperationException,
      NullPointerException
  {
    return setName(DN.valueOf(dn));
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    return toString(this);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractFilterVisitor.java
New file
@@ -0,0 +1,220 @@
/*
 * 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.forgerock.opendj.ldap;
import java.util.List;
/**
 * An abstract filter visitor whose default implementation for all {@code
 * Visitor} methods is to invoke {@link #visitDefaultFilter(Object)}.
 * <p>
 * Implementations can override the methods on a case by case behavior.
 *
 * @param <R>
 *          The return type of this visitor's methods. Use
 *          {@link java.lang.Void} for visitors that do not need to return
 *          results.
 * @param <P>
 *          The type of the additional parameter to this visitor's methods. Use
 *          {@link java.lang.Void} for visitors that do not need an additional
 *          parameter.
 */
public abstract class AbstractFilterVisitor<R, P> implements
    FilterVisitor<R, P>
{
  /**
   * Default constructor.
   */
  protected AbstractFilterVisitor()
  {
    // Nothing to do.
  }
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to call {@link #visitDefaultFilter(Object)}.
   */
  public R visitAndFilter(final P p, final List<Filter> subFilters)
  {
    return visitDefaultFilter(p);
  }
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to call {@link #visitDefaultFilter(Object)}.
   */
  public R visitApproxMatchFilter(final P p, final String attributeDescription,
      final ByteString assertionValue)
  {
    return visitDefaultFilter(p);
  }
  /**
   * Visits any filters which are not explicitly handled by other visitor
   * methods.
   * <p>
   * The default implementation of this method is to return {@code null}.
   *
   * @param p
   *          A visitor specified parameter.
   * @return A visitor specified result.
   */
  public R visitDefaultFilter(final P p)
  {
    return null;
  }
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to call {@link #visitDefaultFilter(Object)}.
   */
  public R visitEqualityMatchFilter(final P p,
      final String attributeDescription, final ByteString assertionValue)
  {
    return visitDefaultFilter(p);
  }
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to call {@link #visitDefaultFilter(Object)}.
   */
  public R visitExtensibleMatchFilter(final P p, final String matchingRule,
      final String attributeDescription, final ByteString assertionValue,
      final boolean dnAttributes)
  {
    return visitDefaultFilter(p);
  }
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to call {@link #visitDefaultFilter(Object)}.
   */
  public R visitGreaterOrEqualFilter(final P p,
      final String attributeDescription, final ByteString assertionValue)
  {
    return visitDefaultFilter(p);
  }
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to call {@link #visitDefaultFilter(Object)}.
   */
  public R visitLessOrEqualFilter(final P p, final String attributeDescription,
      final ByteString assertionValue)
  {
    return visitDefaultFilter(p);
  }
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to call {@link #visitDefaultFilter(Object)}.
   */
  public R visitNotFilter(final P p, final Filter subFilter)
  {
    return visitDefaultFilter(p);
  }
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to call {@link #visitDefaultFilter(Object)}.
   */
  public R visitOrFilter(final P p, final List<Filter> subFilters)
  {
    return visitDefaultFilter(p);
  }
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to call {@link #visitDefaultFilter(Object)}.
   */
  public R visitPresentFilter(final P p, final String attributeDescription)
  {
    return visitDefaultFilter(p);
  }
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to call {@link #visitDefaultFilter(Object)}.
   */
  public R visitSubstringsFilter(final P p, final String attributeDescription,
      final ByteString initialSubstring, final List<ByteString> anySubstrings,
      final ByteString finalSubstring)
  {
    return visitDefaultFilter(p);
  }
  /**
   * {@inheritDoc}
   * <p>
   * The default implementation is to call {@link #visitDefaultFilter(Object)}.
   */
  public R visitUnrecognizedFilter(final P p, final byte filterTag,
      final ByteString filterBytes)
  {
    return visitDefaultFilter(p);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
New file
@@ -0,0 +1,446 @@
/*
 * 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 2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import org.forgerock.opendj.ldap.responses.Responses;
import com.forgerock.opendj.util.AsynchronousFutureResult;
import com.forgerock.opendj.util.StaticUtils;
import com.forgerock.opendj.util.Validator;
/**
 * An abstract load balancing algorithm providing monitoring and failover
 * capabilities.
 * <p>
 * Implementations should override the method
 * {@code getInitialConnectionFactoryIndex()} in order to provide the policy for
 * selecting the first connection factory to use for each connection request.
 */
abstract class AbstractLoadBalancingAlgorithm implements LoadBalancingAlgorithm
{
  private final class MonitoredConnectionFactory extends
      AbstractConnectionFactory implements
      ResultHandler<AsynchronousConnection>
  {
    private final ConnectionFactory factory;
    private final AtomicBoolean isOperational = new AtomicBoolean(true);
    private volatile FutureResult<?> pendingConnectFuture = null;
    private final int index;
    private MonitoredConnectionFactory(final ConnectionFactory factory,
        final int index)
    {
      this.factory = factory;
      this.index = index;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<AsynchronousConnection> getAsynchronousConnection(
        final ResultHandler<? super AsynchronousConnection> resultHandler)
    {
      final AsynchronousFutureResult<AsynchronousConnection> future =
        new AsynchronousFutureResult<AsynchronousConnection>(resultHandler);
      final ResultHandler<AsynchronousConnection> failoverHandler =
        new ResultHandler<AsynchronousConnection>()
      {
        @Override
        public void handleErrorResult(final ErrorResultException error)
        {
          // Attempt failed - try next factory.
          notifyOffline(error);
          final int nextIndex = (index + 1) % monitoredFactories.size();
          try
          {
            final MonitoredConnectionFactory nextFactory =
              getMonitoredConnectionFactory(nextIndex);
            nextFactory.getAsynchronousConnection(future);
          }
          catch (final ErrorResultException e)
          {
            future.handleErrorResult(e);
          }
        }
        @Override
        public void handleResult(final AsynchronousConnection result)
        {
          notifyOnline();
          future.handleResult(result);
        }
      };
      factory.getAsynchronousConnection(failoverHandler);
      return future;
    }
    /**
     * Handle monitoring connection request failure.
     */
    @Override
    public void handleErrorResult(final ErrorResultException error)
    {
      notifyOffline(error);
    }
    /**
     * Handle monitoring connection request success.
     */
    @Override
    public void handleResult(final AsynchronousConnection connection)
    {
      notifyOnline();
      // The connection is not going to be used, so close it immediately.
      connection.close();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String toString()
    {
      return factory.toString();
    }
    /**
     * Attempt to connect to the factory if it is offline and there is no
     * pending monitoring request.
     */
    private synchronized void checkIfAvailable()
    {
      if (!isOperational.get()
          && (pendingConnectFuture == null || pendingConnectFuture.isDone()))
      {
        if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
        {
          StaticUtils.DEBUG_LOG.fine(String
              .format("Attempting reconnect to offline factory " + this));
        }
        pendingConnectFuture = factory.getAsynchronousConnection(this);
      }
    }
    private void notifyOffline(final ErrorResultException error)
    {
      if (isOperational.getAndSet(false))
      {
        // Transition from online to offline.
        if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
        {
          StaticUtils.DEBUG_LOG.warning(String.format("Connection factory "
              + factory + " is no longer operational: " + error.getMessage()));
        }
        synchronized (stateLock)
        {
          offlineFactoriesCount++;
          if (offlineFactoriesCount == 1)
          {
            // Enable monitoring.
            if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
            {
              StaticUtils.DEBUG_LOG.fine(String
                  .format("Starting monitoring thread"));
            }
            monitoringFuture = scheduler.scheduleWithFixedDelay(
                new MonitorRunnable(), 0, monitoringInterval,
                monitoringIntervalTimeUnit);
          }
        }
      }
    }
    private void notifyOnline()
    {
      if (!isOperational.getAndSet(true))
      {
        // Transition from offline to online.
        if (StaticUtils.DEBUG_LOG.isLoggable(Level.INFO))
        {
          StaticUtils.DEBUG_LOG.info(String.format("Connection factory "
              + factory + " is now operational"));
        }
        synchronized (stateLock)
        {
          offlineFactoriesCount--;
          if (offlineFactoriesCount == 0)
          {
            if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
            {
              StaticUtils.DEBUG_LOG.fine(String
                  .format("Stopping monitoring thread"));
            }
            monitoringFuture.cancel(false);
            monitoringFuture = null;
          }
        }
      }
    }
  }
  private final class MonitorRunnable implements Runnable
  {
    private MonitorRunnable()
    {
      // Nothing to do.
    }
    @Override
    public void run()
    {
      for (final MonitoredConnectionFactory factory : monitoredFactories)
      {
        factory.checkIfAvailable();
      }
    }
  }
  private final List<MonitoredConnectionFactory> monitoredFactories;
  private final ScheduledExecutorService scheduler;
  private final Object stateLock = new Object();
  // Guarded by stateLock.
  private int offlineFactoriesCount = 0;
  private final long monitoringInterval;
  private final TimeUnit monitoringIntervalTimeUnit;
  // Guarded by stateLock.
  private ScheduledFuture<?> monitoringFuture;
  /**
   * Creates a new abstract load balancing algorithm which will monitor offline
   * connection factories every second using the default scheduler.
   *
   * @param factories
   *          The connection factories.
   */
  AbstractLoadBalancingAlgorithm(final Collection<ConnectionFactory> factories)
  {
    this(factories, 1, TimeUnit.SECONDS, StaticUtils.getDefaultScheduler());
  }
  /**
   * Creates a new abstract load balancing algorithm which will monitor offline
   * connection factories using the specified frequency using the default
   * scheduler.
   *
   * @param factories
   *          The connection factories.
   * @param interval
   *          The interval between attempts to poll offline factories.
   * @param unit
   *          The time unit for the interval between attempts to poll offline
   *          factories.
   */
  AbstractLoadBalancingAlgorithm(final Collection<ConnectionFactory> factories,
      final long interval, final TimeUnit unit)
  {
    this(factories, interval, unit, StaticUtils.getDefaultScheduler());
  }
  /**
   * Creates a new abstract load balancing algorithm which will monitor offline
   * connection factories using the specified frequency and scheduler.
   *
   * @param factories
   *          The connection factories.
   * @param interval
   *          The interval between attempts to poll offline factories.
   * @param unit
   *          The time unit for the interval between attempts to poll offline
   *          factories.
   * @param scheduler
   *          The scheduler which should for periodically monitoring dead
   *          connection factories to see if they are usable again.
   */
  AbstractLoadBalancingAlgorithm(final Collection<ConnectionFactory> factories,
      final long interval, final TimeUnit unit,
      final ScheduledExecutorService scheduler)
  {
    Validator.ensureNotNull(factories, scheduler, unit);
    this.monitoredFactories = new ArrayList<MonitoredConnectionFactory>(
        factories.size());
    int i = 0;
    for (final ConnectionFactory f : factories)
    {
      this.monitoredFactories.add(new MonitoredConnectionFactory(f, i++));
    }
    this.scheduler = scheduler;
    this.monitoringInterval = interval;
    this.monitoringIntervalTimeUnit = unit;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final ConnectionFactory getConnectionFactory()
      throws ErrorResultException
  {
    final int index = getInitialConnectionFactoryIndex();
    return getMonitoredConnectionFactory(index);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    final StringBuilder builder = new StringBuilder();
    builder.append(getAlgorithmName());
    builder.append('(');
    boolean isFirst = true;
    for (final ConnectionFactory factory : monitoredFactories)
    {
      if (!isFirst)
      {
        builder.append(',');
      }
      else
      {
        isFirst = false;
      }
      builder.append(factory);
    }
    builder.append(')');
    return builder.toString();
  }
  /**
   * Returns the name of this load balancing algorithm.
   *
   * @return The name of this load balancing algorithm.
   */
  abstract String getAlgorithmName();
  /**
   * Returns the index of the first connection factory which should be used in
   * order to satisfy the next connection request.
   *
   * @return The index of the first connection factory which should be used in
   *         order to satisfy the next connection request.
   */
  abstract int getInitialConnectionFactoryIndex();
  // Return the first factory after index which is operational.
  private MonitoredConnectionFactory getMonitoredConnectionFactory(
      final int initialIndex) throws ErrorResultException
  {
    int index = initialIndex;
    final int maxIndex = monitoredFactories.size();
    do
    {
      final MonitoredConnectionFactory factory = monitoredFactories.get(index);
      if (factory.isOperational.get())
      {
        return factory;
      }
      index = (index + 1) % maxIndex;
    }
    while (index != initialIndex);
    // All factories are offline so give up. We could have a
    // configurable policy here such as waiting indefinitely, or for a
    // configurable timeout period.
    throw ErrorResultException.wrap(Responses.newResult(
        ResultCode.CLIENT_SIDE_CONNECT_ERROR).setDiagnosticMessage(
        "No operational connection factories available"));
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractMapEntry.java
New file
@@ -0,0 +1,200 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import java.util.Collection;
import java.util.Map;
import com.forgerock.opendj.util.Validator;
/**
 * Abstract implementation for {@code Map} based entries.
 */
abstract class AbstractMapEntry extends AbstractEntry
{
  private final Map<AttributeDescription, Attribute> attributes;
  private DN name;
  /**
   * Creates an empty entry using the provided distinguished name and {@code
   * Map}.
   *
   * @param name
   *          The distinguished name of this entry.
   * @param attributes
   *          The attribute map.
   */
  AbstractMapEntry(final DN name,
      final Map<AttributeDescription, Attribute> attributes)
      throws NullPointerException
  {
    this.name = name;
    this.attributes = attributes;
  }
  /**
   * {@inheritDoc}
   */
  public final boolean addAttribute(final Attribute attribute,
      final Collection<ByteString> duplicateValues) throws NullPointerException
  {
    Validator.ensureNotNull(attribute);
    final AttributeDescription attributeDescription = attribute
        .getAttributeDescription();
    final Attribute oldAttribute = attributes.get(attributeDescription);
    if (oldAttribute != null)
    {
      return oldAttribute.addAll(attribute, duplicateValues);
    }
    else
    {
      attributes.put(attributeDescription, attribute);
      return true;
    }
  }
  /**
   * {@inheritDoc}
   */
  public final Entry clearAttributes()
  {
    attributes.clear();
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public final Iterable<Attribute> getAllAttributes()
  {
    return attributes.values();
  }
  /**
   * {@inheritDoc}
   */
  public final Attribute getAttribute(
      final AttributeDescription attributeDescription)
      throws NullPointerException
  {
    Validator.ensureNotNull(attributeDescription);
    return attributes.get(attributeDescription);
  }
  /**
   * {@inheritDoc}
   */
  public final int getAttributeCount()
  {
    return attributes.size();
  }
  /**
   * {@inheritDoc}
   */
  public final DN getName()
  {
    return name;
  }
  /**
   * {@inheritDoc}
   */
  public final boolean removeAttribute(final Attribute attribute,
      final Collection<ByteString> missingValues) throws NullPointerException
  {
    Validator.ensureNotNull(attribute);
    final AttributeDescription attributeDescription = attribute
        .getAttributeDescription();
    if (attribute.isEmpty())
    {
      return attributes.remove(attributeDescription) != null;
    }
    else
    {
      final Attribute oldAttribute = attributes.get(attributeDescription);
      if (oldAttribute != null)
      {
        final boolean modified = oldAttribute.removeAll(attribute,
            missingValues);
        if (oldAttribute.isEmpty())
        {
          attributes.remove(attributeDescription);
          return true;
        }
        return modified;
      }
      else
      {
        if (missingValues != null)
        {
          missingValues.addAll(attribute);
        }
        return false;
      }
    }
  }
  /**
   * {@inheritDoc}
   */
  public final Entry setName(final DN dn) throws NullPointerException
  {
    Validator.ensureNotNull(dn);
    this.name = dn;
    return this;
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/Assertion.java
New file
@@ -0,0 +1,48 @@
/*
 * 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.forgerock.opendj.ldap;
/**
 * A compiled attribute value assertion.
 */
public interface Assertion
{
  /**
   * Indicates whether the provided attribute value should be considered a match
   * for this assertion value according to the matching rule.
   *
   * @param attributeValue
   *          The attribute value.
   * @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 matches(ByteSequence attributeValue);
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AssertionFailureException.java
New file
@@ -0,0 +1,49 @@
/*
 * 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 2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import org.forgerock.opendj.ldap.responses.Result;
/**
 * Thrown when the result code returned in a Result indicates that the Request
 * failed because the filter contained in an assertion control failed to match
 * the target entry. More specifically, this exception is used for the
 * {@link ResultCode#ASSERTION_FAILED ASSERTION_FAILED} result code.
 */
@SuppressWarnings("serial")
public class AssertionFailureException extends ErrorResultException
{
  AssertionFailureException(final Result result)
  {
    super(result);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AsynchronousConnection.java
New file
@@ -0,0 +1,850 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import java.io.Closeable;
import java.util.Collection;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import org.forgerock.opendj.ldap.schema.Schema;
/**
 * An asynchronous connection with a Directory Server over which read and update
 * operations may be performed. See RFC 4511 for the LDAPv3 protocol
 * specification and more information about the types of operations defined in
 * LDAP.
 * <p>
 * <h3>Operation processing</h3>
 * <p>
 * All operations are performed asynchronously and return a {@link FutureResult}
 * or sub-type thereof which can be used for retrieving the result using the
 * {@link FutureResult#get} method. Operation failures, for whatever reason, are
 * signalled by the {@link FutureResult#get()} method throwing an
 * {@link ErrorResultException}.
 * <p>
 * Synchronous operations are easily simulated by immediately getting the
 * result:
 *
 * <pre>
 * Connection connection = ...;
 * AddRequest request = ...;
 * // Will block until operation completes, and
 * // throws exception on failure.
 * connection.add(request).get();
 * </pre>
 *
 * Operations can be performed in parallel while taking advantage of the
 * simplicity of a synchronous application design:
 *
 * <pre>
 * Connection connection1 = ...;
 * Connection connection2 = ...;
 * AddRequest request = ...;
 * // Add the entry to the first server (don't block).
 * FutureResult future1 = connection1.add(request);
 * // Add the entry to the second server (in parallel).
 * FutureResult future2 = connection2.add(request);
 * // Total time = is O(1) instead of O(n).
 * future1.get();
 * future2.get();
 * </pre>
 *
 * More complex client applications can take advantage of a fully asynchronous
 * event driven design using {@link ResultHandler}s:
 *
 * <pre>
 * Connection connection = ...;
 * SearchRequest request = ...;
 * // Process results in the search result handler
 * // in a separate thread.
 * SearchResponseHandler handle = ...;
 * connection.search(request, handler);
 * </pre>
 * <p>
 * <h3>Closing connections</h3>
 * <p>
 * Applications must ensure that a connection is closed by calling
 * {@link #close()} even if a fatal error occurs on the connection. Once a
 * connection has been closed by the client application, any attempts to
 * continue to use the connection will result in an
 * {@link IllegalStateException} being thrown. Note that, if a fatal error is
 * encountered on the connection, then the application can continue to use the
 * connection. In this case all requests subsequent to the failure will fail
 * with an appropriate {@link ErrorResultException} when their result is
 * retrieved.
 * <p>
 * <h3>Event notification</h3>
 * <p>
 * Applications can choose to be notified when a connection is closed by the
 * application, receives an unsolicited notification, or experiences a fatal
 * error by registering a {@link ConnectionEventListener} with the connection
 * using the {@link #addConnectionEventListener} method.
 *
 * @see <a href="http://tools.ietf.org/html/rfc4511">RFC 4511 - Lightweight
 *      Directory Access Protocol (LDAP): The Protocol </a>
 */
public interface AsynchronousConnection extends Closeable
{
  /**
   * Abandons the unfinished operation identified in the provided abandon
   * request.
   * <p>
   * Since abandon requests do not have a response, invoking the method
   * {@code get()} on the returned future will not block, nor return anything
   * (it is {@code Void}), but may throw an exception if a problem occurred
   * while sending the abandon request.
   * <p>
   * <b>Note:</b> a more convenient approach to abandoning unfinished operations
   * is provided via the {@link FutureResult#cancel(boolean)} method.
   *
   * @param request
   *          The request identifying the operation to be abandoned.
   * @return An future whose result is {@code Void}.
   * @throws UnsupportedOperationException
   *           If this connection does not support abandon operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<Void> abandon(AbandonRequest request)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Adds an entry to the Directory Server using the provided add request. Any
   * intermediate responses will be ignored.
   *
   * @param request
   *          The add request.
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support add operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<Result> add(AddRequest request,
      ResultHandler<? super Result> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Adds an entry to the Directory Server using the provided add request.
   *
   * @param request
   *          The add request.
   * @param resultHandler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @param intermediateResponseHandler
   *          An intermediate response handler which can be used to process any
   *          intermediate responses as they are received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support add operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<Result> add(AddRequest request,
      ResultHandler<? super Result> resultHandler,
      IntermediateResponseHandler intermediateResponseHandler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Registers the provided connection event listener so that it will be
   * notified when this connection is closed by the application, receives an
   * unsolicited notification, or experiences a fatal error.
   *
   * @param listener
   *          The listener which wants to be notified when events occur on this
   *          connection.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If the {@code listener} was {@code null}.
   */
  void addConnectionEventListener(ConnectionEventListener listener)
      throws IllegalStateException, NullPointerException;
  /**
   * Authenticates to the Directory Server using the provided bind request. Any
   * intermediate responses will be ignored.
   *
   * @param request
   *          The bind request.
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support bind operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<BindResult> bind(BindRequest request,
      ResultHandler<? super BindResult> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Authenticates to the Directory Server using the provided bind request.
   *
   * @param request
   *          The bind request.
   * @param resultHandler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @param intermediateResponseHandler
   *          An intermediate response handler which can be used to process any
   *          intermediate responses as they are received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support bind operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<BindResult> bind(BindRequest request,
      ResultHandler<? super BindResult> resultHandler,
      IntermediateResponseHandler intermediateResponseHandler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Releases any resources associated with this connection. For physical
   * connections to a Directory Server this will mean that an unbind request is
   * sent and the underlying socket is closed.
   * <p>
   * Other connection implementations may behave differently, and may choose not
   * to send an unbind request if its use is inappropriate (for example a pooled
   * connection will be released and returned to its connection pool without
   * ever issuing an unbind request).
   * <p>
   * This method is semantically equivalent to the following code:
   *
   * <pre>
   * UnbindRequest request = Requests.newUnbindRequest();
   * connection.close(request);
   * </pre>
   *
   * Calling {@code close} on a connection that is already closed has no effect.
   */
  void close();
  /**
   * Releases any resources associated with this connection. For physical
   * connections to a Directory Server this will mean that the provided unbind
   * request is sent and the underlying socket is closed.
   * <p>
   * Other connection implementations may behave differently, and may choose to
   * ignore the provided unbind request if its use is inappropriate (for example
   * a pooled connection will be released and returned to its connection pool
   * without ever issuing an unbind request).
   * <p>
   * Calling {@code close} on a connection that is already closed has no effect.
   *
   * @param request
   *          The unbind request to use in the case where a physical connection
   *          is closed.
   * @param reason
   *          A reason describing why the connection was closed.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  void close(UnbindRequest request, String reason) throws NullPointerException;
  /**
   * Compares an entry in the Directory Server using the provided compare
   * request. Any intermediate responses will be ignored.
   *
   * @param request
   *          The compare request.
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support compare operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<CompareResult> compare(CompareRequest request,
      ResultHandler<? super CompareResult> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Compares an entry in the Directory Server using the provided compare
   * request.
   *
   * @param request
   *          The compare request.
   * @param resultHandler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @param intermediateResponseHandler
   *          An intermediate response handler which can be used to process any
   *          intermediate responses as they are received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support compare operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<CompareResult> compare(CompareRequest request,
      ResultHandler<? super CompareResult> resultHandler,
      IntermediateResponseHandler intermediateResponseHandler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Deletes an entry from the Directory Server using the provided delete
   * request. Any intermediate responses will be ignored.
   *
   * @param request
   *          The delete request.
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support delete operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<Result> delete(DeleteRequest request,
      ResultHandler<? super Result> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Deletes an entry from the Directory Server using the provided delete
   * request.
   *
   * @param request
   *          The delete request.
   * @param resultHandler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @param intermediateResponseHandler
   *          An intermediate response handler which can be used to process any
   *          intermediate responses as they are received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support delete operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<Result> delete(DeleteRequest request,
      ResultHandler<? super Result> resultHandler,
      IntermediateResponseHandler intermediateResponseHandler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Requests that the Directory Server performs the provided extended request.
   * Any intermediate responses will be ignored.
   *
   * @param <R>
   *          The type of result returned by the extended request.
   * @param request
   *          The extended request.
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support extended operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  <R extends ExtendedResult> FutureResult<R> extendedRequest(
      ExtendedRequest<R> request, ResultHandler<? super R> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Requests that the Directory Server performs the provided extended request.
   *
   * @param <R>
   *          The type of result returned by the extended request.
   * @param request
   *          The extended request.
   * @param resultHandler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @param intermediateResponseHandler
   *          An intermediate response handler which can be used to process any
   *          intermediate responses as they are received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support extended operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  <R extends ExtendedResult> FutureResult<R> extendedRequest(
      ExtendedRequest<R> request, ResultHandler<? super R> resultHandler,
      IntermediateResponseHandler intermediateResponseHandler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Returns a synchronous connection sharing the same underlying network
   * connection as this asynchronous connection.
   *
   * @return A synchronous connection sharing the same underlying network
   *         connection as this asynchronous connection.
   */
  Connection getSynchronousConnection();
  /**
   * Indicates whether or not this connection has been explicitly closed by
   * calling {@code close}. This method will not return {@code true} if a fatal
   * error has occurred on the connection unless {@code close} has been called.
   *
   * @return {@code true} if this connection has been explicitly closed by
   *         calling {@code close}, or {@code false} otherwise.
   */
  boolean isClosed();
  /**
   * Returns {@code true} if this connection has not been closed and no fatal
   * errors have been detected. This method is guaranteed to return
   * {@code false} only when it is called after the method {@code close} has
   * been called.
   *
   * @return {@code true} if the connection is valid, {@code false} otherwise.
   */
  boolean isValid();
  /**
   * Modifies an entry in the Directory Server using the provided modify
   * request. Any intermediate responses will be ignored.
   *
   * @param request
   *          The modify request.
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support modify operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<Result> modify(ModifyRequest request,
      ResultHandler<? super Result> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Modifies an entry in the Directory Server using the provided modify
   * request.
   *
   * @param request
   *          The modify request.
   * @param resultHandler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @param intermediateResponseHandler
   *          An intermediate response handler which can be used to process any
   *          intermediate responses as they are received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support modify operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<Result> modify(ModifyRequest request,
      ResultHandler<? super Result> resultHandler,
      IntermediateResponseHandler intermediateResponseHandler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Renames an entry in the Directory Server using the provided modify DN
   * request. Any intermediate responses will be ignored.
   *
   * @param request
   *          The modify DN request.
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support modify DN operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<Result> modifyDN(ModifyDNRequest request,
      ResultHandler<? super Result> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Renames an entry in the Directory Server using the provided modify DN
   * request.
   *
   * @param request
   *          The modify DN request.
   * @param resultHandler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @param intermediateResponseHandler
   *          An intermediate response handler which can be used to process any
   *          intermediate responses as they are received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support modify DN operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<Result> modifyDN(ModifyDNRequest request,
      ResultHandler<? super Result> resultHandler,
      IntermediateResponseHandler intermediateResponseHandler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Reads the named entry from the Directory Server.
   * <p>
   * If the requested entry is not returned by the Directory Server then the
   * request will fail with an {@link EntryNotFoundException}. More
   * specifically, the returned future will never return {@code null}.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * SearchRequest request = new SearchRequest(name, SearchScope.BASE_OBJECT,
   *     &quot;(objectClass=*)&quot;, attributeDescriptions);
   * connection.searchSingleEntry(request, resultHandler, p);
   * </pre>
   *
   * @param name
   *          The distinguished name of the entry to be read.
   * @param attributeDescriptions
   *          The names of the attributes to be included with the entry, which
   *          may be {@code null} or empty indicating that all user attributes
   *          should be returned.
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If the {@code name} was {@code null}.
   */
  FutureResult<SearchResultEntry> readEntry(DN name,
      Collection<String> attributeDescriptions,
      ResultHandler<? super SearchResultEntry> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Reads the Root DSE from the Directory Server.
   * <p>
   * If the Root DSE is not returned by the Directory Server then the request
   * will fail with an {@link EntryNotFoundException}. More specifically, the
   * returned future will never return {@code null}.
   *
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   */
  FutureResult<RootDSE> readRootDSE(ResultHandler<? super RootDSE> handler)
      throws UnsupportedOperationException, IllegalStateException;
  /**
   * Reads the schema from the Directory Server contained in the named subschema
   * sub-entry.
   * <p>
   * If the requested schema is not returned by the Directory Server then the
   * request will fail with an {@link EntryNotFoundException}. More
   * specifically, the returned future will never return {@code null}.
   * <p>
   * Implementations may choose to perform optimizations such as caching.
   *
   * @param name
   *          The distinguished name of the subschema sub-entry.
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   */
  FutureResult<Schema> readSchema(DN name, ResultHandler<? super Schema> handler)
      throws UnsupportedOperationException, IllegalStateException;
  /**
   * Reads the schema from the Directory Server which applies to the named
   * entry.
   * <p>
   * If the requested entry or its associated schema are not returned by the
   * Directory Server then the request will fail with an
   * {@link EntryNotFoundException}. More specifically, the returned future will
   * never return {@code null}.
   * <p>
   * A typical implementation will first read the {@code subschemaSubentry}
   * attribute of the entry in order to locate the schema. However,
   * implementations may choose to perform other optimizations, such as caching.
   *
   * @param name
   *          The distinguished name of the entry whose schema is to be located.
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   *          Optional additional handler parameter.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   */
  FutureResult<Schema> readSchemaForEntry(DN name,
      ResultHandler<? super Schema> handler)
      throws UnsupportedOperationException, IllegalStateException;
  /**
   * Removes the provided connection event listener from this connection so that
   * it will no longer be notified when this connection is closed by the
   * application, receives an unsolicited notification, or experiences a fatal
   * error.
   *
   * @param listener
   *          The listener which no longer wants to be notified when events
   *          occur on this connection.
   * @throws NullPointerException
   *           If the {@code listener} was {@code null}.
   */
  void removeConnectionEventListener(ConnectionEventListener listener)
      throws NullPointerException;
  /**
   * Searches the Directory Server using the provided search request. Any
   * intermediate responses will be ignored.
   *
   * @param request
   *          The search request.
   * @param handler
   *          A search result handler which can be used to asynchronously
   *          process the search result entries and references as they are
   *          received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<Result> search(SearchRequest request,
      SearchResultHandler handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Searches the Directory Server using the provided search request.
   *
   * @param request
   *          The search request.
   * @param resultHandler
   *          A search result handler which can be used to asynchronously
   *          process the search result entries and references as they are
   *          received, may be {@code null}.
   * @param intermediateResponseHandler
   *          An intermediate response handler which can be used to process any
   *          intermediate responses as they are received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  FutureResult<Result> search(SearchRequest request,
      SearchResultHandler resultHandler,
      IntermediateResponseHandler intermediateResponseHandler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Searches the Directory Server for a single entry using the provided search
   * request.
   * <p>
   * If the requested entry is not returned by the Directory Server then the
   * request will fail with an {@link EntryNotFoundException}. More
   * specifically, the returned future will never return {@code null}. If
   * multiple matching entries are returned by the Directory Server then the
   * request will fail with an {@link MultipleEntriesFoundException}.
   *
   * @param request
   *          The search request.
   * @param handler
   *          A result handler which can be used to asynchronously process the
   *          operation result when it is received, may be {@code null}.
   * @return A future representing the result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if
   *           {@code isClosed() == true}.
   * @throws NullPointerException
   *           If the {@code request} was {@code null}.
   */
  FutureResult<SearchResultEntry> searchSingleEntry(SearchRequest request,
      ResultHandler<? super SearchResultEntry> handler)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/Attribute.java
New file
@@ -0,0 +1,484 @@
/*
 * 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.forgerock.opendj.ldap;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
/**
 * An attribute, comprising of an attribute description and zero or more
 * attribute values.
 * <p>
 * Any methods which perform comparisons between attribute values use the
 * equality matching rule associated with the attribute description.
 * <p>
 * Any methods which accept {@code Object} based attribute values convert the
 * attribute values to instances of {@code ByteString} as follows:
 *
 * <pre>
 * Object object = ...;
 * ByteString value = null;
 * if (object instanceof ByteSequence)
 * {
 *   value = ((ByteSequence)object).toByteString();
 * }
 * else
 * {
 *   value = ByteString.valueOf(object.toString());
 * }
 * </pre>
 * <p>
 * TODO: matching against attribute value assertions.
 */
public interface Attribute extends Set<ByteString>
{
  /**
   * Adds {@code value} to this attribute if it is not already present (optional
   * operation). If this attribute already contains {@code value}, the call
   * leaves the attribute unchanged and returns {@code false}.
   *
   * @param value
   *          The attribute value to be added to this attribute.
   * @return {@code true} if this attribute changed as a result of this call.
   * @throws UnsupportedOperationException
   *           If this attribute does not support addition of attribute values.
   * @throws NullPointerException
   *           If {@code value} was {@code null}.
   */
  boolean add(ByteString value) throws UnsupportedOperationException,
      NullPointerException;
  /**
   * Adds all of the provided attribute values to this attribute if they are not
   * already present (optional operation).
   * <p>
   * Any attribute values which are not instances of {@code ByteString} will be
   * converted using the {@link ByteString#valueOf(Object)} method.
   *
   * @param firstValue
   *          The first attribute value to be added to this attribute.
   * @param remainingValues
   *          The remaining attribute values to be added to this attribute.
   * @return {@code true} if this attribute changed as a result of this call.
   * @throws UnsupportedOperationException
   *           If this attribute does not support addition of attribute values.
   * @throws NullPointerException
   *           If {@code firstValue} was {@code null}.
   */
  boolean add(Object firstValue, Object... remainingValues)
      throws UnsupportedOperationException, NullPointerException;
  /**
   * Adds all of the attribute values contained in {@code values} to this
   * attribute if they are not already present (optional operation).
   * <p>
   * An invocation of this method is equivalent to:
   *
   * <pre>
   * attribute.addAll(values, null);
   * </pre>
   *
   * @param values
   *          The attribute values to be added to this attribute.
   * @return {@code true} if this attribute changed as a result of this call.
   * @throws UnsupportedOperationException
   *           If this attribute does not support addition of attribute values.
   * @throws NullPointerException
   *           If {@code values} was {@code null}.
   */
  boolean addAll(Collection<? extends ByteString> values)
      throws UnsupportedOperationException, NullPointerException;
  /**
   * Adds all of the attribute values contained in {@code values} to this
   * attribute if they are not already present (optional operation). Any
   * attribute values which are already present will be added to {@code
   * duplicateValues} if specified.
   *
   * @param values
   *          The attribute values to be added to this attribute.
   * @param duplicateValues
   *          A collection into which duplicate values will be added, or {@code
   *          null} if duplicate values should not be saved.
   * @return {@code true} if this attribute changed as a result of this call.
   * @throws UnsupportedOperationException
   *           If this attribute does not support addition of attribute values.
   * @throws NullPointerException
   *           If {@code values} was {@code null}.
   */
  boolean addAll(Collection<? extends ByteString> values,
      Collection<? super ByteString> duplicateValues)
      throws UnsupportedOperationException, NullPointerException;
  /**
   * Removes all of the attribute values from this attribute (optional
   * operation). This attribute will be empty after this call returns.
   *
   * @throws UnsupportedOperationException
   *           If this attribute does not support removal of attribute values.
   */
  void clear() throws UnsupportedOperationException;
  /**
   * Returns {@code true} if this attribute contains {@code value}.
   * <p>
   * If {@code value} is not an instance of {@code ByteString} then it will be
   * converted using the {@link ByteString#valueOf(Object)} method.
   *
   * @param value
   *          The attribute value whose presence in this attribute is to be
   *          tested.
   * @return {@code true} if this attribute contains {@code value}, or {@code
   *         false} if not.
   * @throws NullPointerException
   *           If {@code value} was {@code null}.
   */
  boolean contains(Object value) throws NullPointerException;
  /**
   * Returns {@code true} if this attribute contains all of the attribute values
   * contained in {@code values}.
   * <p>
   * Any attribute values which are not instances of {@code ByteString} will be
   * converted using the {@link ByteString#valueOf(Object)} method.
   *
   * @param values
   *          The attribute values whose presence in this attribute is to be
   *          tested.
   * @return {@code true} if this attribute contains all of the attribute values
   *         contained in {@code values}, or {@code false} if not.
   * @throws NullPointerException
   *           If {@code values} was {@code null}.
   */
  boolean containsAll(Collection<?> values) throws NullPointerException;
  /**
   * Returns {@code true} if {@code object} is an attribute which is equal to
   * this attribute. Two attributes are considered equal if their attribute
   * descriptions are equal, they both have the same number of attribute values,
   * and every attribute value contained in the first attribute is also
   * contained in the second attribute.
   *
   * @param object
   *          The object to be tested for equality with this attribute.
   * @return {@code true} if {@code object} is an attribute which is equal to
   *         this attribute, or {@code false} if not.
   */
  boolean equals(Object object);
  /**
   * Returns the first attribute value in this attribute.
   *
   * @return The first attribute value in this attribute.
   * @throws NoSuchElementException
   *           If this attribute is empty.
   */
  ByteString firstValue() throws NoSuchElementException;
  /**
   * Returns the first attribute value in this attribute decoded as a UTF-8
   * string.
   *
   * @return The first attribute value in this attribute decoded as a UTF-8
   *         string.
   * @throws NoSuchElementException
   *           If this attribute is empty.
   */
  String firstValueAsString() throws NoSuchElementException;
  /**
   * Returns the attribute description of this attribute, which includes its
   * attribute type and any options.
   *
   * @return The attribute description.
   */
  AttributeDescription getAttributeDescription();
  /**
   * Returns the string representation of the attribute description of this
   * attribute, which includes its attribute type and any options.
   *
   * @return The string representation of the attribute description.
   */
  String getAttributeDescriptionAsString();
  /**
   * Returns the hash code for this attribute. It will be calculated as the sum
   * of the hash codes of the attribute description and all of the attribute
   * values.
   *
   * @return The hash code for this attribute.
   */
  int hashCode();
  /**
   * Returns {@code true} if this attribute contains no attribute values.
   *
   * @return {@code true} if this attribute contains no attribute values.
   */
  boolean isEmpty();
  /**
   * Returns an iterator over the attribute values in this attribute. The
   * attribute values are returned in no particular order, unless the
   * implementation of this attribute provides such a guarantee.
   *
   * @return An iterator over the attribute values in this attribute.
   */
  Iterator<ByteString> iterator();
  /**
   * Removes {@code value} from this attribute if it is present (optional
   * operation). If this attribute does not contain {@code value}, the call
   * leaves the attribute unchanged and returns {@code false}.
   * <p>
   * If {@code value} is not an instance of {@code ByteString} then it will be
   * converted using the {@link ByteString#valueOf(Object)} method.
   *
   * @param value
   *          The attribute value to be removed from this attribute.
   * @return {@code true} if this attribute changed as a result of this call.
   * @throws UnsupportedOperationException
   *           If this attribute does not support removal of attribute values.
   * @throws NullPointerException
   *           If {@code value} was {@code null}.
   */
  boolean remove(Object value) throws UnsupportedOperationException,
      NullPointerException;
  /**
   * Removes all of the attribute values contained in {@code values} from this
   * attribute if they are present (optional operation).
   * <p>
   * Any attribute values which are not instances of {@code ByteString} will be
   * converted using the {@link ByteString#valueOf(Object)} method.
   * <p>
   * An invocation of this method is equivalent to:
   *
   * <pre>
   * attribute.removeAll(values, null);
   * </pre>
   *
   * @param values
   *          The attribute values to be removed from this attribute.
   * @return {@code true} if this attribute changed as a result of this call.
   * @throws UnsupportedOperationException
   *           If this attribute does not support removal of attribute values.
   * @throws NullPointerException
   *           If {@code values} was {@code null}.
   */
  boolean removeAll(Collection<?> values) throws UnsupportedOperationException,
      NullPointerException;
  /**
   * Removes all of the attribute values contained in {@code values} from this
   * attribute if they are present (optional operation). Any attribute values
   * which are not already present will be added to {@code missingValues} if
   * specified.
   * <p>
   * Any attribute values which are not instances of {@code ByteString} will be
   * converted using the {@link ByteString#valueOf(Object)} method.
   *
   * @param <T>
   *          The type of the attribute value objects being removed.
   * @param values
   *          The attribute values to be removed from this attribute.
   * @param missingValues
   *          A collection into which missing values will be added, or {@code
   *          null} if missing values should not be saved.
   * @return {@code true} if this attribute changed as a result of this call.
   * @throws UnsupportedOperationException
   *           If this attribute does not support removal of attribute values.
   * @throws NullPointerException
   *           If {@code values} was {@code null}.
   */
  <T> boolean removeAll(Collection<T> values,
      Collection<? super T> missingValues)
      throws UnsupportedOperationException, NullPointerException;
  /**
   * Retains only the attribute values in this attribute which are contained in
   * {@code values} (optional operation).
   * <p>
   * Any attribute values which are not instances of {@code ByteString} will be
   * converted using the {@link ByteString#valueOf(Object)} method.
   * <p>
   * An invocation of this method is equivalent to:
   *
   * <pre>
   * attribute.retainAll(values, null);
   * </pre>
   *
   * @param values
   *          The attribute values to be retained in this attribute.
   * @return {@code true} if this attribute changed as a result of this call.
   * @throws UnsupportedOperationException
   *           If this attribute does not support removal of attribute values.
   * @throws NullPointerException
   *           If {@code values} was {@code null}.
   */
  boolean retainAll(Collection<?> values) throws UnsupportedOperationException,
      NullPointerException;
  /**
   * Retains only the attribute values in this attribute which are contained in
   * {@code values} (optional operation). Any attribute values which are not
   * already present will be added to {@code missingValues} if specified.
   * <p>
   * Any attribute values which are not instances of {@code ByteString} will be
   * converted using the {@link ByteString#valueOf(Object)} method.
   *
   * @param <T>
   *          The type of the attribute value objects being retained.
   * @param values
   *          The attribute values to be retained in this attribute.
   * @param missingValues
   *          A collection into which missing values will be added, or {@code
   *          null} if missing values should not be saved.
   * @return {@code true} if this attribute changed as a result of this call.
   * @throws UnsupportedOperationException
   *           If this attribute does not support removal of attribute values.
   * @throws NullPointerException
   *           If {@code values} was {@code null}.
   */
  <T> boolean retainAll(Collection<T> values,
      Collection<? super T> missingValues)
      throws UnsupportedOperationException, NullPointerException;
  /**
   * Returns the number of attribute values in this attribute.
   *
   * @return The number of attribute values in this attribute.
   */
  int size();
  /**
   * Returns an array containing all of the attribute values contained in this
   * attribute.
   * <p>
   * If this attribute makes any guarantees as to what order its attribute
   * values are returned by its iterator, this method must return the attribute
   * values in the same order.
   * <p>
   * The returned array will be "safe" in that no references to it are
   * maintained by this attribute. The caller is thus free to modify the
   * returned array.
   *
   * @return An array containing all of the attribute values contained in this
   *         attribute.
   */
  ByteString[] toArray();
  /**
   * Returns an array containing all of the attribute values in this attribute;
   * the runtime type of the returned array is that of the specified array.
   * <p>
   * If the set fits in the specified array, it is returned therein. Otherwise,
   * a new array is allocated with the runtime type of the specified array and
   * the size of this attribute. If this attribute fits in the specified array
   * with room to spare (i.e., the array has more elements than this attribute),
   * the elements in the array immediately following the end of the set is set
   * to {@code null}.
   * <p>
   * If this attribute makes any guarantees as to what order its attribute
   * values are returned by its iterator, this method must return the attribute
   * values in the same order.
   *
   * @param <T>
   *          The type of elements contained in {@code array}.
   * @param array
   *          An array into which the elements of this attribute should be put.
   * @return An array containing all of the attribute values contained in this
   *         attribute.
   * @throws ArrayStoreException
   *           If the runtime type of {@code array} is not a supertype of
   *           {@code ByteString}.
   * @throws NullPointerException
   *           If {@code array} was {@code null}.
   */
  <T> T[] toArray(T[] array) throws ArrayStoreException, NullPointerException;
  /**
   * Returns a string representation of this attribute.
   *
   * @return The string representation of this attribute.
   */
  String toString();
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AttributeDescription.java
New file
@@ -0,0 +1,1480 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import static com.forgerock.opendj.util.StaticUtils.toLowerCase;
import static org.forgerock.opendj.ldap.CoreMessages.*;
import java.util.*;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldap.schema.UnknownSchemaElementException;
import com.forgerock.opendj.util.ASCIICharProp;
import com.forgerock.opendj.util.Iterators;
import com.forgerock.opendj.util.Validator;
/**
 * An attribute description as defined in RFC 4512 section 2.5. Attribute
 * descriptions are used to identify an attribute in an entry and are composed
 * of an attribute type and a set of zero or more attribute options.
 *
 * @see <a href="http://tools.ietf.org/html/rfc4512#section-2.5">RFC 4512 -
 *      Lightweight Directory Access Protocol (LDAP): Directory Information
 *      Models </a>
 */
public final class AttributeDescription implements
    Comparable<AttributeDescription>
{
  private static abstract class Impl implements Iterable<String>
  {
    protected Impl()
    {
      // Nothing to do.
    }
    public abstract int compareTo(Impl other);
    public abstract boolean containsOption(String normalizedOption);
    public abstract boolean equals(Impl other);
    public abstract String firstNormalizedOption();
    @Override
    public abstract int hashCode();
    public abstract boolean hasOptions();
    public abstract boolean isSubTypeOf(Impl other);
    public abstract boolean isSuperTypeOf(Impl other);
    public abstract int size();
  }
  private static final class MultiOptionImpl extends Impl
  {
    private final String[] normalizedOptions;
    private final String[] options;
    private MultiOptionImpl(final String[] options,
        final String[] normalizedOptions)
    {
      if (normalizedOptions.length < 2)
      {
        throw new AssertionError();
      }
      this.options = options;
      this.normalizedOptions = normalizedOptions;
    }
    @Override
    public int compareTo(final Impl other)
    {
      final int thisSize = normalizedOptions.length;
      final int otherSize = other.size();
      if (thisSize < otherSize)
      {
        return -1;
      }
      else if (thisSize > otherSize)
      {
        return 1;
      }
      else
      {
        // Same number of options.
        final MultiOptionImpl otherImpl = (MultiOptionImpl) other;
        for (int i = 0; i < thisSize; i++)
        {
          final String o1 = normalizedOptions[i];
          final String o2 = otherImpl.normalizedOptions[i];
          final int result = o1.compareTo(o2);
          if (result != 0)
          {
            return result;
          }
        }
        // All options the same.
        return 0;
      }
    }
    @Override
    public boolean containsOption(final String normalizedOption)
    {
      final int sz = normalizedOptions.length;
      for (int i = 0; i < sz; i++)
      {
        if (normalizedOptions[i].equals(normalizedOption))
        {
          return true;
        }
      }
      return false;
    }
    @Override
    public boolean equals(final Impl other)
    {
      if (other instanceof MultiOptionImpl)
      {
        final MultiOptionImpl tmp = (MultiOptionImpl) other;
        return Arrays.equals(normalizedOptions, tmp.normalizedOptions);
      }
      else
      {
        return false;
      }
    }
    @Override
    public String firstNormalizedOption()
    {
      return normalizedOptions[0];
    }
    @Override
    public int hashCode()
    {
      return Arrays.hashCode(normalizedOptions);
    }
    @Override
    public boolean hasOptions()
    {
      return true;
    }
    @Override
    public boolean isSubTypeOf(final Impl other)
    {
      // Must contain a super-set of other's options.
      if (other == ZERO_OPTION_IMPL)
      {
        return true;
      }
      else if (other.size() == 1)
      {
        return containsOption(other.firstNormalizedOption());
      }
      else if (other.size() > size())
      {
        return false;
      }
      else
      {
        // Check this contains other's options.
        //
        // This could be optimized more if required, but it's probably
        // not worth it.
        final MultiOptionImpl tmp = (MultiOptionImpl) other;
        for (final String normalizedOption : tmp.normalizedOptions)
        {
          if (!containsOption(normalizedOption))
          {
            return false;
          }
        }
        return true;
      }
    }
    @Override
    public boolean isSuperTypeOf(final Impl other)
    {
      // Must contain a sub-set of other's options.
      for (final String normalizedOption : normalizedOptions)
      {
        if (!other.containsOption(normalizedOption))
        {
          return false;
        }
      }
      return true;
    }
    public Iterator<String> iterator()
    {
      return Iterators.arrayIterator(options);
    }
    @Override
    public int size()
    {
      return normalizedOptions.length;
    }
  }
  private static final class SingleOptionImpl extends Impl
  {
    private final String normalizedOption;
    private final String option;
    private SingleOptionImpl(final String option, final String normalizedOption)
    {
      this.option = option;
      this.normalizedOption = normalizedOption;
    }
    @Override
    public int compareTo(final Impl other)
    {
      if (other == ZERO_OPTION_IMPL)
      {
        // If other has zero options then this sorts after.
        return 1;
      }
      else if (other.size() == 1)
      {
        // Same number of options, so compare.
        return normalizedOption.compareTo(other.firstNormalizedOption());
      }
      else
      {
        // Other has more options, so comes after.
        return -1;
      }
    }
    @Override
    public boolean containsOption(final String normalizedOption)
    {
      return this.normalizedOption.equals(normalizedOption);
    }
    @Override
    public boolean equals(final Impl other)
    {
      return other.size() == 1 && other.containsOption(normalizedOption);
    }
    @Override
    public String firstNormalizedOption()
    {
      return normalizedOption;
    }
    @Override
    public int hashCode()
    {
      return normalizedOption.hashCode();
    }
    @Override
    public boolean hasOptions()
    {
      return true;
    }
    @Override
    public boolean isSubTypeOf(final Impl other)
    {
      // Other must have no options or the same option.
      if (other == ZERO_OPTION_IMPL)
      {
        return true;
      }
      else
      {
        return equals(other);
      }
    }
    @Override
    public boolean isSuperTypeOf(final Impl other)
    {
      // Other must have this option.
      return other.containsOption(normalizedOption);
    }
    public Iterator<String> iterator()
    {
      return Iterators.singletonIterator(option);
    }
    @Override
    public int size()
    {
      return 1;
    }
  }
  private static final class ZeroOptionImpl extends Impl
  {
    private ZeroOptionImpl()
    {
      // Nothing to do.
    }
    @Override
    public int compareTo(final Impl other)
    {
      // If other has options then this sorts before.
      return this == other ? 0 : -1;
    }
    @Override
    public boolean containsOption(final String normalizedOption)
    {
      return false;
    }
    @Override
    public boolean equals(final Impl other)
    {
      return this == other;
    }
    @Override
    public String firstNormalizedOption()
    {
      // No first option.
      return null;
    }
    @Override
    public int hashCode()
    {
      // Use attribute type hash code.
      return 0;
    }
    @Override
    public boolean hasOptions()
    {
      return false;
    }
    @Override
    public boolean isSubTypeOf(final Impl other)
    {
      // Can only be a sub-type if other has no options.
      return this == other;
    }
    @Override
    public boolean isSuperTypeOf(final Impl other)
    {
      // Will always be a super-type.
      return true;
    }
    public Iterator<String> iterator()
    {
      return Iterators.emptyIterator();
    }
    @Override
    public int size()
    {
      return 0;
    }
  }
  private static final ThreadLocal<WeakHashMap<
    Schema, Map<String, AttributeDescription>>> CACHE =
      new ThreadLocal<WeakHashMap<Schema, Map<String, AttributeDescription>>>()
  {
    /**
     * {@inheritDoc}
     */
    @Override
    protected WeakHashMap<Schema, Map<String, AttributeDescription>> initialValue()
    {
      return new WeakHashMap<Schema, Map<String, AttributeDescription>>();
    }
  };
  // Object class attribute description.
  private static final ZeroOptionImpl ZERO_OPTION_IMPL = new ZeroOptionImpl();
  private static final AttributeDescription OBJECT_CLASS;
  static
  {
    final AttributeType attributeType = Schema.getCoreSchema()
        .getAttributeType("2.5.4.0");
    OBJECT_CLASS = new AttributeDescription(attributeType.getNameOrOID(),
        attributeType, ZERO_OPTION_IMPL);
  }
  // This is the size of the per-thread per-schema attribute description
  // cache. We should be conservative here in case there are many
  // threads.
  private static final int ATTRIBUTE_DESCRIPTION_CACHE_SIZE = 512;
  /**
   * Creates an attribute description having the same attribute type and options
   * as the provided attribute description and, in addition, the provided list
   * of options.
   *
   * @param attributeDescription
   *          The attribute description.
   * @param options
   *          The attribute options.
   * @return The new attribute description containing {@code options}.
   * @throws NullPointerException
   *           If {@code attributeDescription} or {@code options} was {@code
   *           null}.
   */
  public static AttributeDescription create(
      final AttributeDescription attributeDescription, final String... options)
      throws NullPointerException
  {
    Validator.ensureNotNull(attributeDescription, options);
    // This should not be called very often, so don't optimize.
    AttributeDescription newAttributeDescription = attributeDescription;
    for (final String option : options)
    {
      newAttributeDescription = create(newAttributeDescription, option);
    }
    return newAttributeDescription;
  }
  /**
   * Creates an attribute description having the same attribute type and options
   * as the provided attribute description and, in addition, the provided new
   * option.
   *
   * @param attributeDescription
   *          The attribute description.
   * @param option
   *          The attribute option.
   * @return The new attribute description containing {@code option}.
   * @throws NullPointerException
   *           If {@code attributeDescription} or {@code option} was {@code
   *           null}.
   */
  public static AttributeDescription create(
      final AttributeDescription attributeDescription, final String option)
      throws NullPointerException
  {
    Validator.ensureNotNull(attributeDescription, option);
    final String normalizedOption = toLowerCase(option);
    if (attributeDescription.pimpl.containsOption(normalizedOption))
    {
      return attributeDescription;
    }
    final String oldAttributeDescription = attributeDescription.attributeDescription;
    final StringBuilder builder = new StringBuilder(oldAttributeDescription
        .length()
        + option.length() + 1);
    builder.append(oldAttributeDescription);
    builder.append(';');
    builder.append(option);
    final String newAttributeDescription = builder.toString();
    final Impl impl = attributeDescription.pimpl;
    if (impl instanceof ZeroOptionImpl)
    {
      return new AttributeDescription(newAttributeDescription,
          attributeDescription.attributeType, new SingleOptionImpl(option,
              normalizedOption));
    }
    else if (impl instanceof SingleOptionImpl)
    {
      final SingleOptionImpl simpl = (SingleOptionImpl) impl;
      final String[] newOptions = new String[2];
      newOptions[0] = simpl.option;
      newOptions[1] = option;
      final String[] newNormalizedOptions = new String[2];
      if (normalizedOption.compareTo(simpl.normalizedOption) < 0)
      {
        newNormalizedOptions[0] = normalizedOption;
        newNormalizedOptions[1] = simpl.normalizedOption;
      }
      return new AttributeDescription(newAttributeDescription,
          attributeDescription.attributeType, new MultiOptionImpl(newOptions,
              newNormalizedOptions));
    }
    else
    {
      final MultiOptionImpl mimpl = (MultiOptionImpl) impl;
      final int sz1 = mimpl.options.length;
      final String[] newOptions = new String[sz1 + 1];
      for (int i = 0; i < sz1; i++)
      {
        newOptions[i] = mimpl.options[i];
      }
      newOptions[sz1] = option;
      final int sz2 = mimpl.normalizedOptions.length;
      final String[] newNormalizedOptions = new String[sz2 + 1];
      boolean inserted = false;
      for (int i = 0; i < sz2; i++)
      {
        if (!inserted)
        {
          final String s = mimpl.normalizedOptions[i];
          if (normalizedOption.compareTo(s) < 0)
          {
            newNormalizedOptions[i] = normalizedOption;
            newNormalizedOptions[i + 1] = s;
            inserted = true;
          }
          else
          {
            newNormalizedOptions[i] = s;
          }
        }
        else
        {
          newNormalizedOptions[i + 1] = mimpl.normalizedOptions[i];
        }
      }
      if (!inserted)
      {
        newNormalizedOptions[sz2] = normalizedOption;
      }
      return new AttributeDescription(newAttributeDescription,
          attributeDescription.attributeType, new MultiOptionImpl(newOptions,
              newNormalizedOptions));
    }
  }
  /**
   * Creates an attribute description having the provided attribute type and no
   * options.
   *
   * @param attributeType
   *          The attribute type.
   * @return The attribute description.
   * @throws NullPointerException
   *           If {@code attributeType} was {@code null}.
   */
  public static AttributeDescription create(final AttributeType attributeType)
      throws NullPointerException
  {
    Validator.ensureNotNull(attributeType);
    // Use object identity in case attribute type does not come from
    // core schema.
    if (attributeType == OBJECT_CLASS.getAttributeType())
    {
      return OBJECT_CLASS;
    }
    else
    {
      return new AttributeDescription(attributeType.getNameOrOID(),
          attributeType, ZERO_OPTION_IMPL);
    }
  }
  /**
   * Creates an attribute description having the provided attribute type and
   * single option.
   *
   * @param attributeType
   *          The attribute type.
   * @param option
   *          The attribute option.
   * @return The attribute description.
   * @throws NullPointerException
   *           If {@code attributeType} or {@code option} was {@code null}.
   */
  public static AttributeDescription create(final AttributeType attributeType,
      final String option) throws NullPointerException
  {
    Validator.ensureNotNull(attributeType, option);
    final String oid = attributeType.getNameOrOID();
    final StringBuilder builder = new StringBuilder(oid.length()
        + option.length() + 1);
    builder.append(oid);
    builder.append(';');
    builder.append(option);
    final String attributeDescription = builder.toString();
    final String normalizedOption = toLowerCase(option);
    return new AttributeDescription(attributeDescription, attributeType,
        new SingleOptionImpl(option, normalizedOption));
  }
  /**
   * Creates an attribute description having the provided attribute type and
   * options.
   *
   * @param attributeType
   *          The attribute type.
   * @param options
   *          The attribute options.
   * @return The attribute description.
   * @throws NullPointerException
   *           If {@code attributeType} or {@code options} was {@code null}.
   */
  public static AttributeDescription create(final AttributeType attributeType,
      final String... options) throws NullPointerException
  {
    Validator.ensureNotNull(attributeType, options);
    switch (options.length)
    {
    case 0:
      return create(attributeType);
    case 1:
      return create(attributeType, options[0]);
    default:
      final String[] optionsList = new String[options.length];
      final String[] normalizedOptions = new String[options.length];
      final String oid = attributeType.getNameOrOID();
      final StringBuilder builder = new StringBuilder(oid.length()
          + options[0].length() + options[1].length() + 2);
      builder.append(oid);
      int i = 0;
      for (final String option : options)
      {
        builder.append(';');
        builder.append(option);
        optionsList[i] = option;
        final String normalizedOption = toLowerCase(option);
        normalizedOptions[i++] = normalizedOption;
      }
      Arrays.sort(normalizedOptions);
      final String attributeDescription = builder.toString();
      return new AttributeDescription(attributeDescription, attributeType,
          new MultiOptionImpl(optionsList, normalizedOptions));
    }
  }
  /**
   * Returns an attribute description representing the object class attribute
   * type with no options.
   *
   * @return The object class attribute description.
   */
  public static AttributeDescription objectClass()
  {
    return OBJECT_CLASS;
  }
  /**
   * Parses the provided LDAP string representation of an attribute description
   * using the default schema.
   *
   * @param attributeDescription
   *          The LDAP string representation of an attribute description.
   * @return The parsed attribute description.
   * @throws LocalizedIllegalArgumentException
   *           If {@code attributeDescription} is not a valid LDAP string
   *           representation of an attribute description.
   * @throws NullPointerException
   *           If {@code attributeDescription} was {@code null}.
   */
  public static AttributeDescription valueOf(final String attributeDescription)
      throws LocalizedIllegalArgumentException, NullPointerException
  {
    return valueOf(attributeDescription, Schema.getDefaultSchema());
  }
  /**
   * Parses the provided LDAP string representation of an attribute description
   * using the provided schema.
   *
   * @param attributeDescription
   *          The LDAP string representation of an attribute description.
   * @param schema
   *          The schema to use when parsing the attribute description.
   * @return The parsed attribute description.
   * @throws LocalizedIllegalArgumentException
   *           If {@code attributeDescription} is not a valid LDAP string
   *           representation of an attribute description.
   * @throws NullPointerException
   *           If {@code attributeDescription} or {@code schema} was {@code
   *           null}.
   */
  @SuppressWarnings("serial")
  public static AttributeDescription valueOf(final String attributeDescription,
      final Schema schema) throws LocalizedIllegalArgumentException,
      NullPointerException
  {
    Validator.ensureNotNull(attributeDescription, schema);
    // First look up the attribute description in the cache.
    final WeakHashMap<Schema, Map<String, AttributeDescription>> threadLocalMap = CACHE
        .get();
    Map<String, AttributeDescription> schemaLocalMap = threadLocalMap
        .get(schema);
    AttributeDescription ad = null;
    if (schemaLocalMap == null)
    {
      schemaLocalMap = new LinkedHashMap<String, AttributeDescription>(
          ATTRIBUTE_DESCRIPTION_CACHE_SIZE, 0.75f, true)
      {
        @Override
        protected boolean removeEldestEntry(
            final Map.Entry<String, AttributeDescription> eldest)
        {
          return size() > ATTRIBUTE_DESCRIPTION_CACHE_SIZE;
        }
      };
      threadLocalMap.put(schema, schemaLocalMap);
    }
    else
    {
      ad = schemaLocalMap.get(attributeDescription);
    }
    // Cache miss: decode and cache.
    if (ad == null)
    {
      ad = valueOf0(attributeDescription, schema);
      schemaLocalMap.put(attributeDescription, ad);
    }
    return ad;
  }
  private static int skipTrailingWhiteSpace(final String attributeDescription,
      int i, final int length) throws LocalizedIllegalArgumentException
  {
    char c;
    while (i < length)
    {
      c = attributeDescription.charAt(i);
      if (c != ' ')
      {
        final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_INTERNAL_WHITESPACE
            .get(attributeDescription);
        throw new LocalizedIllegalArgumentException(message);
      }
      i++;
    }
    return i;
  }
  // Uncached valueOf implementation.
  private static AttributeDescription valueOf0(
      final String attributeDescription, final Schema schema)
      throws LocalizedIllegalArgumentException
  {
    int i = 0;
    final int length = attributeDescription.length();
    char c = 0;
    // Skip leading white space.
    while (i < length)
    {
      c = attributeDescription.charAt(i);
      if (c != ' ')
      {
        break;
      }
      i++;
    }
    // If we're already at the end then the attribute description only
    // contained whitespace.
    if (i == length)
    {
      final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_EMPTY
          .get(attributeDescription);
      throw new LocalizedIllegalArgumentException(message);
    }
    // Validate the first non-whitespace character.
    ASCIICharProp cp = ASCIICharProp.valueOf(c);
    if (cp == null)
    {
      final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_ILLEGAL_CHARACTER
          .get(attributeDescription, c, i);
      throw new LocalizedIllegalArgumentException(message);
    }
    // Mark the attribute type start position.
    final int attributeTypeStart = i;
    if (cp.isLetter())
    {
      // Non-numeric OID: letter + zero or more keychars.
      i++;
      while (i < length)
      {
        c = attributeDescription.charAt(i);
        if (c == ';' || c == ' ')
        {
          break;
        }
        cp = ASCIICharProp.valueOf(c);
        if (!cp.isKeyChar())
        {
          final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_ILLEGAL_CHARACTER
              .get(attributeDescription, c, i);
          throw new LocalizedIllegalArgumentException(message);
        }
        i++;
      }
      // (charAt(i) == ';' || c == ' ' || i == length)
    }
    else if (cp.isDigit())
    {
      // Numeric OID: decimal digit + zero or more dots or decimals.
      i++;
      while (i < length)
      {
        c = attributeDescription.charAt(i);
        if (c == ';' || c == ' ')
        {
          break;
        }
        cp = ASCIICharProp.valueOf(c);
        if (c != '.' && !cp.isDigit())
        {
          final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_ILLEGAL_CHARACTER
              .get(attributeDescription, c, i);
          throw new LocalizedIllegalArgumentException(message);
        }
        i++;
      }
      // (charAt(i) == ';' || charAt(i) == ' ' || i == length)
    }
    else
    {
      final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_ILLEGAL_CHARACTER
          .get(attributeDescription, c, i);
      throw new LocalizedIllegalArgumentException(message);
    }
    // Skip trailing white space.
    final int attributeTypeEnd = i;
    if (c == ' ')
    {
      i = skipTrailingWhiteSpace(attributeDescription, i + 1, length);
    }
    // Determine the portion of the string containing the attribute type
    // name.
    String oid;
    if (attributeTypeStart == 0 && attributeTypeEnd == length)
    {
      oid = attributeDescription;
    }
    else
    {
      oid = attributeDescription
          .substring(attributeTypeStart, attributeTypeEnd);
    }
    if (oid.length() == 0)
    {
      final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_NO_TYPE
          .get(attributeDescription);
      throw new LocalizedIllegalArgumentException(message);
    }
    // Get the attribute type from the schema.
    AttributeType attributeType;
    try
    {
      attributeType = schema.getAttributeType(oid);
    }
    catch (final UnknownSchemaElementException e)
    {
      final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_TYPE_NOT_FOUND
          .get(attributeDescription, e.getMessageObject());
      throw new LocalizedIllegalArgumentException(message);
    }
    // If we're already at the end of the attribute description then it
    // does not contain any options.
    if (i == length)
    {
      // Use object identity in case attribute type does not come from
      // core schema.
      if (attributeType == OBJECT_CLASS.getAttributeType()
          && attributeDescription.equals(OBJECT_CLASS.toString()))
      {
        return OBJECT_CLASS;
      }
      else
      {
        return new AttributeDescription(attributeDescription, attributeType,
            ZERO_OPTION_IMPL);
      }
    }
    // At this point 'i' must point at a semi-colon.
    i++;
    StringBuilder builder = null;
    int optionStart = i;
    while (i < length)
    {
      c = attributeDescription.charAt(i);
      if (c == ' ' || c == ';')
      {
        break;
      }
      cp = ASCIICharProp.valueOf(c);
      if (!cp.isKeyChar())
      {
        final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_ILLEGAL_CHARACTER
            .get(attributeDescription, c, i);
        throw new LocalizedIllegalArgumentException(message);
      }
      if (builder == null)
      {
        if (cp.isUpperCase())
        {
          // Need to normalize the option.
          builder = new StringBuilder(length - optionStart);
          builder.append(attributeDescription, optionStart, i);
          builder.append(cp.toLowerCase());
        }
      }
      else
      {
        builder.append(cp.toLowerCase());
      }
      i++;
    }
    String option = attributeDescription.substring(optionStart, i);
    String normalizedOption;
    if (builder != null)
    {
      normalizedOption = builder.toString();
    }
    else
    {
      normalizedOption = option;
    }
    if (option.length() == 0)
    {
      final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_EMPTY_OPTION
          .get(attributeDescription);
      throw new LocalizedIllegalArgumentException(message);
    }
    // Skip trailing white space.
    if (c == ' ')
    {
      i = skipTrailingWhiteSpace(attributeDescription, i + 1, length);
    }
    // If we're already at the end of the attribute description then it
    // only contains a single option.
    if (i == length)
    {
      return new AttributeDescription(attributeDescription, attributeType,
          new SingleOptionImpl(option, normalizedOption));
    }
    // Multiple options need sorting and duplicates removed - we could
    // optimize a bit further here for 2 option attribute descriptions.
    final List<String> options = new LinkedList<String>();
    options.add(option);
    final SortedSet<String> normalizedOptions = new TreeSet<String>();
    normalizedOptions.add(normalizedOption);
    while (i < length)
    {
      // At this point 'i' must point at a semi-colon.
      i++;
      builder = null;
      optionStart = i;
      while (i < length)
      {
        c = attributeDescription.charAt(i);
        if (c == ' ' || c == ';')
        {
          break;
        }
        cp = ASCIICharProp.valueOf(c);
        if (!cp.isKeyChar())
        {
          final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_ILLEGAL_CHARACTER
              .get(attributeDescription, c, i);
          throw new LocalizedIllegalArgumentException(message);
        }
        if (builder == null)
        {
          if (cp.isUpperCase())
          {
            // Need to normalize the option.
            builder = new StringBuilder(length - optionStart);
            builder.append(attributeDescription, optionStart, i);
            builder.append(cp.toLowerCase());
          }
        }
        else
        {
          builder.append(cp.toLowerCase());
        }
        i++;
      }
      option = attributeDescription.substring(optionStart, i);
      if (builder != null)
      {
        normalizedOption = builder.toString();
      }
      else
      {
        normalizedOption = option;
      }
      if (option.length() == 0)
      {
        final LocalizableMessage message = ERR_ATTRIBUTE_DESCRIPTION_EMPTY_OPTION
            .get(attributeDescription);
        throw new LocalizedIllegalArgumentException(message);
      }
      // Skip trailing white space.
      if (c == ' ')
      {
        i = skipTrailingWhiteSpace(attributeDescription, i + 1, length);
      }
      options.add(option);
      normalizedOptions.add(normalizedOption);
    }
    return new AttributeDescription(attributeDescription, attributeType,
        new MultiOptionImpl(options.toArray(new String[options.size()]),
            normalizedOptions.toArray(new String[normalizedOptions.size()])));
  }
  private final String attributeDescription;
  private final AttributeType attributeType;
  private final Impl pimpl;
  // Private constructor.
  private AttributeDescription(final String attributeDescription,
      final AttributeType attributeType, final Impl pimpl)
  {
    this.attributeDescription = attributeDescription;
    this.attributeType = attributeType;
    this.pimpl = pimpl;
  }
  /**
   * Compares this attribute description to the provided attribute description.
   * The attribute types are compared first and then, if equal, the options are
   * normalized, sorted, and compared.
   *
   * @param other
   *          The attribute description to be compared.
   * @return A negative integer, zero, or a positive integer as this attribute
   *         description is less than, equal to, or greater than the specified
   *         attribute description.
   * @throws NullPointerException
   *           If {@code name} was {@code null}.
   */
  public int compareTo(final AttributeDescription other)
      throws NullPointerException
  {
    final int result = attributeType.compareTo(other.attributeType);
    if (result != 0)
    {
      return result;
    }
    else
    {
      // Attribute type is the same, so compare options.
      return pimpl.compareTo(other.pimpl);
    }
  }
  /**
   * Indicates whether or not this attribute description contains the provided
   * option.
   *
   * @param option
   *          The option for which to make the determination.
   * @return {@code true} if this attribute description has the provided option,
   *         or {@code false} if not.
   * @throws NullPointerException
   *           If {@code option} was {@code null}.
   */
  public boolean containsOption(final String option)
      throws NullPointerException
  {
    final String normalizedOption = toLowerCase(option);
    return pimpl.containsOption(normalizedOption);
  }
  /**
   * Indicates whether the provided object is an attribute description which is
   * equal to this attribute description. It will be considered equal if the
   * attribute type and normalized sorted list of options are identical.
   *
   * @param o
   *          The object for which to make the determination.
   * @return {@code true} if the provided object is an attribute description
   *         that is equal to this attribute description, or {@code false} if
   *         not.
   */
  @Override
  public boolean equals(final Object o)
  {
    if (this == o)
    {
      return true;
    }
    if (!(o instanceof AttributeDescription))
    {
      return false;
    }
    final AttributeDescription other = (AttributeDescription) o;
    if (!attributeType.equals(other.attributeType))
    {
      return false;
    }
    // Attribute type is the same, compare options.
    return pimpl.equals(other.pimpl);
  }
  /**
   * Returns the attribute type associated with this attribute description.
   *
   * @return The attribute type associated with this attribute description.
   */
  public AttributeType getAttributeType()
  {
    return attributeType;
  }
  /**
   * Returns an {@code Iterable} containing the options contained in this
   * attribute description. Attempts to remove options using an iterator's
   * {@code remove()} method are not permitted and will result in an {@code
   * UnsupportedOperationException} being thrown.
   *
   * @return An {@code Iterable} containing the options.
   */
  public Iterable<String> getOptions()
  {
    return pimpl;
  }
  /**
   * Returns the hash code for this attribute description. It will be calculated
   * as the sum of the hash codes of the attribute type and normalized sorted
   * list of options.
   *
   * @return The hash code for this attribute description.
   */
  @Override
  public int hashCode()
  {
    // FIXME: should we cache this?
    return attributeType.hashCode() * 31 + pimpl.hashCode();
  }
  /**
   * Indicates whether or not this attribute description has any options.
   *
   * @return {@code true} if this attribute description has any options, or
   *         {@code false} if not.
   */
  public boolean hasOptions()
  {
    return pimpl.hasOptions();
  }
  /**
   * Indicates whether or not this attribute description is the {@code
   * objectClass} attribute description with no options.
   *
   * @return {@code true} if this attribute description is the {@code
   *         objectClass} attribute description with no options, or {@code
   *         false} if not.
   */
  public boolean isObjectClass()
  {
    return attributeType.isObjectClass() && !hasOptions();
  }
  /**
   * Indicates whether or not this attribute description is a sub-type of the
   * provided attribute description as defined in RFC 4512 section 2.5.
   * Specifically, this method will return {@code true} if and only if the
   * following conditions are both {@code true}:
   * <ul>
   * <li>This attribute description has an attribute type which is equal to, or
   * is a sub-type of, the attribute type in the provided attribute description.
   * <li>This attribute description contains all of the options contained in the
   * provided attribute description.
   * </ul>
   * Note that this method will return {@code true} if this attribute
   * description is equal to the provided attribute description.
   *
   * @param other
   *          The attribute description for which to make the determination.
   * @return {@code true} if this attribute description is a sub-type of the
   *         provided attribute description, or {@code false} if not.
   * @throws NullPointerException
   *           If {@code name} was {@code null}.
   */
  public boolean isSubTypeOf(final AttributeDescription other)
      throws NullPointerException
  {
    if (!attributeType.isSubTypeOf(other.attributeType))
    {
      return false;
    }
    else
    {
      return pimpl.isSubTypeOf(other.pimpl);
    }
  }
  /**
   * Indicates whether or not this attribute description is a super-type of the
   * provided attribute description as defined in RFC 4512 section 2.5.
   * Specifically, this method will return {@code true} if and only if the
   * following conditions are both {@code true}:
   * <ul>
   * <li>This attribute description has an attribute type which is equal to, or
   * is a super-type of, the attribute type in the provided attribute
   * description.
   * <li>This attribute description contains a sub-set of the options contained
   * in the provided attribute description.
   * </ul>
   * Note that this method will return {@code true} if this attribute
   * description is equal to the provided attribute description.
   *
   * @param other
   *          The attribute description for which to make the determination.
   * @return {@code true} if this attribute description is a super-type of the
   *         provided attribute description, or {@code false} if not.
   * @throws NullPointerException
   *           If {@code name} was {@code null}.
   */
  public boolean isSuperTypeOf(final AttributeDescription other)
      throws NullPointerException
  {
    if (!other.attributeType.isSubTypeOf(attributeType))
    {
      return false;
    }
    else
    {
      return pimpl.isSuperTypeOf(other.pimpl);
    }
  }
  /**
   * Returns the string representation of this attribute description as defined
   * in RFC4512 section 2.5.
   *
   * @return The string representation of this attribute description.
   */
  @Override
  public String toString()
  {
    return attributeDescription;
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AttributeFactory.java
New file
@@ -0,0 +1,54 @@
/*
 * 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 2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
/**
 * Attribute factories are included with a set of {@code DecodeOptions} in order
 * to allow application to control how {@code Attribute} instances are created
 * when decoding requests and responses.
 *
 * @see Attribute
 * @see DecodeOptions
 */
public interface AttributeFactory
{
  /**
   * Creates an attribute using the provided attribute description and no
   * values.
   *
   * @param attributeDescription
   *          The attribute description.
   * @return The new attribute.
   * @throws NullPointerException
   *           If {@code attributeDescription} was {@code null}.
   */
  Attribute newAttribute(AttributeDescription attributeDescription)
      throws NullPointerException;
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/Attributes.java
New file
@@ -0,0 +1,627 @@
/*
 * 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 2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.forgerock.opendj.ldap.schema.AttributeType;
import com.forgerock.opendj.util.Iterators;
import com.forgerock.opendj.util.Validator;
/**
 * This class contains methods for creating and manipulating attributes.
 */
public final class Attributes
{
  /**
   * Empty attribute.
   */
  private static final class EmptyAttribute extends AbstractAttribute
  {
    private final AttributeDescription attributeDescription;
    private EmptyAttribute(final AttributeDescription attributeDescription)
    {
      this.attributeDescription = attributeDescription;
    }
    @Override
    public boolean add(final ByteString value)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    @Override
    public void clear() throws UnsupportedOperationException
    {
      throw new UnsupportedOperationException();
    }
    @Override
    public boolean contains(final Object value) throws NullPointerException
    {
      return false;
    }
    @Override
    public AttributeDescription getAttributeDescription()
    {
      return attributeDescription;
    }
    @Override
    public boolean isEmpty()
    {
      return true;
    }
    @Override
    public Iterator<ByteString> iterator()
    {
      return Iterators.emptyIterator();
    }
    @Override
    public boolean remove(final Object value)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    @Override
    public int size()
    {
      return 0;
    }
  }
  /**
   * Renamed attribute.
   */
  private static final class RenamedAttribute implements Attribute
  {
    private final Attribute attribute;
    private final AttributeDescription attributeDescription;
    private RenamedAttribute(final Attribute attribute,
        final AttributeDescription attributeDescription)
    {
      this.attribute = attribute;
      this.attributeDescription = attributeDescription;
    }
    public boolean add(final ByteString value)
        throws UnsupportedOperationException, NullPointerException
    {
      return attribute.add(value);
    }
    public boolean add(final Object firstValue, final Object... remainingValues)
        throws UnsupportedOperationException, NullPointerException
    {
      return attribute.add(firstValue, remainingValues);
    }
    public boolean addAll(final Collection<? extends ByteString> values)
        throws UnsupportedOperationException, NullPointerException
    {
      return attribute.addAll(values);
    }
    public boolean addAll(final Collection<? extends ByteString> values,
        final Collection<? super ByteString> duplicateValues)
        throws UnsupportedOperationException, NullPointerException
    {
      return attribute.addAll(values, duplicateValues);
    }
    public void clear() throws UnsupportedOperationException
    {
      attribute.clear();
    }
    public boolean contains(final Object value) throws NullPointerException
    {
      return attribute.contains(value);
    }
    public boolean containsAll(final Collection<?> values)
        throws NullPointerException
    {
      return attribute.containsAll(values);
    }
    @Override
    public boolean equals(final Object object)
    {
      return AbstractAttribute.equals(this, object);
    }
    public ByteString firstValue() throws NoSuchElementException
    {
      return attribute.firstValue();
    }
    public String firstValueAsString() throws NoSuchElementException
    {
      return attribute.firstValueAsString();
    }
    public AttributeDescription getAttributeDescription()
    {
      return attributeDescription;
    }
    public String getAttributeDescriptionAsString()
    {
      return attributeDescription.toString();
    }
    @Override
    public int hashCode()
    {
      return AbstractAttribute.hashCode(this);
    }
    public boolean isEmpty()
    {
      return attribute.isEmpty();
    }
    public Iterator<ByteString> iterator()
    {
      return attribute.iterator();
    }
    public boolean remove(final Object value)
        throws UnsupportedOperationException, NullPointerException
    {
      return attribute.remove(value);
    }
    public boolean removeAll(final Collection<?> values)
        throws UnsupportedOperationException, NullPointerException
    {
      return attribute.removeAll(values);
    }
    public <T> boolean removeAll(final Collection<T> values,
        final Collection<? super T> missingValues)
        throws UnsupportedOperationException, NullPointerException
    {
      return attribute.removeAll(values, missingValues);
    }
    public boolean retainAll(final Collection<?> values)
        throws UnsupportedOperationException, NullPointerException
    {
      return attribute.retainAll(values);
    }
    public <T> boolean retainAll(final Collection<T> values,
        final Collection<? super T> missingValues)
        throws UnsupportedOperationException, NullPointerException
    {
      return attribute.retainAll(values, missingValues);
    }
    public int size()
    {
      return attribute.size();
    }
    public ByteString[] toArray()
    {
      return attribute.toArray();
    }
    public <T> T[] toArray(final T[] array) throws ArrayStoreException,
        NullPointerException
    {
      return attribute.toArray(array);
    }
    @Override
    public String toString()
    {
      return AbstractAttribute.toString(this);
    }
  }
  /**
   * Unmodifiable attribute.
   */
  private static final class UnmodifiableAttribute implements Attribute
  {
    private final Attribute attribute;
    private UnmodifiableAttribute(final Attribute attribute)
    {
      this.attribute = attribute;
    }
    public boolean add(final ByteString value)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    public boolean add(final Object firstValue, final Object... remainingValues)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    public boolean addAll(final Collection<? extends ByteString> values)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    public boolean addAll(final Collection<? extends ByteString> values,
        final Collection<? super ByteString> duplicateValues)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    public void clear() throws UnsupportedOperationException
    {
      throw new UnsupportedOperationException();
    }
    public boolean contains(final Object value) throws NullPointerException
    {
      return attribute.contains(value);
    }
    public boolean containsAll(final Collection<?> values)
        throws NullPointerException
    {
      return attribute.containsAll(values);
    }
    @Override
    public boolean equals(final Object object)
    {
      return (object == this || attribute.equals(object));
    }
    public ByteString firstValue() throws NoSuchElementException
    {
      return attribute.firstValue();
    }
    public String firstValueAsString() throws NoSuchElementException
    {
      return attribute.firstValueAsString();
    }
    public AttributeDescription getAttributeDescription()
    {
      return attribute.getAttributeDescription();
    }
    public String getAttributeDescriptionAsString()
    {
      return attribute.getAttributeDescriptionAsString();
    }
    @Override
    public int hashCode()
    {
      return attribute.hashCode();
    }
    public boolean isEmpty()
    {
      return attribute.isEmpty();
    }
    public Iterator<ByteString> iterator()
    {
      return Iterators.unmodifiableIterator(attribute.iterator());
    }
    public boolean remove(final Object value)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    public boolean removeAll(final Collection<?> values)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    public <T> boolean removeAll(final Collection<T> values,
        final Collection<? super T> missingValues)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    public boolean retainAll(final Collection<?> values)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    public <T> boolean retainAll(final Collection<T> values,
        final Collection<? super T> missingValues)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    public int size()
    {
      return attribute.size();
    }
    public ByteString[] toArray()
    {
      return attribute.toArray();
    }
    public <T> T[] toArray(final T[] array) throws ArrayStoreException,
        NullPointerException
    {
      return attribute.toArray(array);
    }
    @Override
    public String toString()
    {
      return attribute.toString();
    }
  }
  /**
   * Returns a read-only empty attribute having the specified attribute
   * description.
   *
   * @param attributeDescription
   *          The attribute description.
   * @return The empty attribute.
   * @throws NullPointerException
   *           If {@code attributeDescription} was {@code null}.
   */
  public static final Attribute emptyAttribute(
      final AttributeDescription attributeDescription)
      throws NullPointerException
  {
    return new EmptyAttribute(attributeDescription);
  }
  /**
   * Returns a view of {@code attribute} having a different attribute
   * description. All operations on the returned attribute "pass-through" to the
   * underlying attribute.
   *
   * @param attribute
   *          The attribute to be renamed.
   * @param attributeDescription
   *          The new attribute description for {@code attribute}, which must be
   *          compatible with {@code attribute}'s attribute description.
   * @return A renamed view of {@code attribute}.
   * @throws IllegalArgumentException
   *           If {@code attributeDescription} does not have the same attribute
   *           type as {@code attribute}'s attribute description.
   * @throws NullPointerException
   *           If {@code attribute} or {@code attributeDescription} was {@code
   *           null}.
   */
  public static final Attribute renameAttribute(final Attribute attribute,
      final AttributeDescription attributeDescription)
      throws IllegalArgumentException, NullPointerException
  {
    final AttributeType oldType = attribute.getAttributeDescription()
        .getAttributeType();
    final AttributeType newType = attributeDescription.getAttributeType();
    // We could relax a bit by ensuring that they are both compatible
    // (e.g. one sub-type of another, or same equality matching rule,
    // etc).
    Validator.ensureTrue(oldType.equals(newType),
        "Old and new attribute type are not the same");
    return new RenamedAttribute(attribute, attributeDescription);
  }
  /**
   * Returns a read-only view of {@code attribute}. Query operations on the
   * returned attribute "read-through" to the underlying attribute, and attempts
   * to modify the returned attribute either directly or indirectly via an
   * iterator result in an {@code UnsupportedOperationException}.
   *
   * @param attribute
   *          The attribute for which a read-only view is to be returned.
   * @return A read-only view of {@code attribute}.
   * @throws NullPointerException
   *           If {@code attribute} was {@code null}.
   */
  public static final Attribute unmodifiableAttribute(final Attribute attribute)
      throws NullPointerException
  {
    return new UnmodifiableAttribute(attribute);
  }
  // Prevent instantiation.
  private Attributes()
  {
    // Nothing to do.
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticatedConnectionFactory.java
New file
@@ -0,0 +1,240 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import org.forgerock.opendj.ldap.requests.BindRequest;
import org.forgerock.opendj.ldap.responses.BindResult;
import com.forgerock.opendj.util.AsynchronousConnectionDecorator;
import com.forgerock.opendj.util.FutureResultTransformer;
import com.forgerock.opendj.util.RecursiveFutureResult;
/**
 * An authenticated connection factory can be used to create pre-authenticated
 * connections to a Directory Server.
 * <p>
 * The connections returned by an authenticated connection factory support all
 * operations with the exception of Bind requests. Attempts to perform a Bind
 * will result in an {@code UnsupportedOperationException}.
 * <p>
 * If the Bind request fails for some reason (e.g. invalid credentials), then
 * the connection attempt will fail and an {@code ErrorResultException} will be
 * thrown.
 */
final class AuthenticatedConnectionFactory extends AbstractConnectionFactory
{
  /**
   * An authenticated asynchronous connection supports all operations except
   * Bind operations.
   */
  public static final class AuthenticatedAsynchronousConnection extends
      AsynchronousConnectionDecorator
  {
    private AuthenticatedAsynchronousConnection(
        final AsynchronousConnection connection)
    {
      super(connection);
    }
    /**
     * Bind operations are not supported by pre-authenticated connections. This
     * method will always throw {@code UnsupportedOperationException}.
     */
    public FutureResult<BindResult> bind(final BindRequest request,
        final ResultHandler<? super BindResult> handler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    /**
     * Bind operations are not supported by pre-authenticated connections. This
     * method will always throw {@code UnsupportedOperationException}.
     */
    public FutureResult<BindResult> bind(final BindRequest request,
        final ResultHandler<? super BindResult> resultHandler,
        final IntermediateResponseHandler intermediateResponseHandler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    /**
     * {@inheritDoc}
     */
    public String toString()
    {
      StringBuilder builder = new StringBuilder();
      builder.append("AuthenticatedConnection(");
      builder.append(connection);
      builder.append(')');
      return builder.toString();
    }
  }
  private static final class FutureResultImpl
  {
    private final FutureResultTransformer<BindResult, AsynchronousConnection> futureBindResult;
    private final RecursiveFutureResult<AsynchronousConnection, BindResult> futureConnectionResult;
    private final BindRequest bindRequest;
    private AsynchronousConnection connection;
    private FutureResultImpl(final BindRequest request,
        final ResultHandler<? super AsynchronousConnection> handler)
    {
      this.bindRequest = request;
      this.futureBindResult = new FutureResultTransformer<BindResult, AsynchronousConnection>(
          handler)
      {
        @Override
        protected ErrorResultException transformErrorResult(
            final ErrorResultException errorResult)
        {
          // Ensure that the connection is closed.
          try
          {
            connection.close();
            connection = null;
          }
          catch (final Exception e)
          {
            // Ignore.
          }
          return errorResult;
        }
        @Override
        protected AsynchronousConnection transformResult(final BindResult result)
            throws ErrorResultException
        {
          return new AuthenticatedAsynchronousConnection(connection);
        }
      };
      this.futureConnectionResult = new RecursiveFutureResult<AsynchronousConnection, BindResult>(
          futureBindResult)
      {
        @Override
        protected FutureResult<? extends BindResult> chainResult(
            final AsynchronousConnection innerResult,
            final ResultHandler<? super BindResult> handler)
            throws ErrorResultException
        {
          connection = innerResult;
          return connection.bind(bindRequest, handler);
        }
      };
      futureBindResult.setFutureResult(futureConnectionResult);
    }
  }
  private final BindRequest request;
  private final ConnectionFactory parentFactory;
  /**
   * Creates a new authenticated connection factory which will obtain
   * connections using the provided connection factory and immediately perform
   * the provided Bind request.
   *
   * @param factory
   *          The connection factory to use for connecting to the Directory
   *          Server.
   * @param request
   *          The Bind request to use for authentication.
   */
  AuthenticatedConnectionFactory(final ConnectionFactory factory,
      final BindRequest request)
  {
    this.parentFactory = factory;
    // FIXME: should do a defensive copy.
    this.request = request;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public FutureResult<AsynchronousConnection> getAsynchronousConnection(
      final ResultHandler<? super AsynchronousConnection> handler)
  {
    final FutureResultImpl future = new FutureResultImpl(request, handler);
    future.futureConnectionResult.setFutureResult(parentFactory
        .getAsynchronousConnection(future.futureConnectionResult));
    return future.futureBindResult;
  }
  /**
   * {@inheritDoc}
   */
  public String toString()
  {
    final StringBuilder builder = new StringBuilder();
    builder.append("AuthenticatedConnectionFactory(");
    builder.append(String.valueOf(parentFactory));
    builder.append(')');
    return builder.toString();
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticationException.java
New file
@@ -0,0 +1,60 @@
/*
 * 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 2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import org.forgerock.opendj.ldap.responses.Result;
/**
 * Thrown when the result code returned in a Result indicates that the Bind
 * Request failed due to an authentication failure. More specifically, this
 * exception is used for the following error result codes:
 * <ul>
 * <li>{@link ResultCode#AUTH_METHOD_NOT_SUPPORTED AUTH_METHOD_NOT_SUPPORTED} -
 * the Bind request failed because it referenced an invalid SASL mechanism.
 * <li>{@link ResultCode#CLIENT_SIDE_AUTH_UNKNOWN CLIENT_SIDE_AUTH_UNKNOWN} -
 * the Bind request failed because the user requested an authentication
 * mechanism which is unknown or unsupported by the OpenDS SDK.
 * <li>{@link ResultCode#INAPPROPRIATE_AUTHENTICATION
 * INAPPROPRIATE_AUTHENTICATION} - the Bind request failed because the requested
 * type of authentication was not appropriate for the targeted entry.
 * <li>{@link ResultCode#INVALID_CREDENTIALS INVALID_CREDENTIALS} - the Bind
 * request failed because the user did not provide a valid set of credentials.
 * </ul>
 */
@SuppressWarnings("serial")
public class AuthenticationException extends ErrorResultException
{
  AuthenticationException(final Result result)
  {
    super(result);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/AuthorizationException.java
New file
@@ -0,0 +1,62 @@
/*
 * 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 2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import org.forgerock.opendj.ldap.responses.Result;
/**
 * Thrown when the result code returned in a Result indicates that the Request
 * failed due to an authorization failure. More specifically, this exception is
 * used for the following error result codes:
 * <ul>
 * <li>{@link ResultCode#AUTHORIZATION_DENIED AUTHORIZATION_DENIED} - the
 * Request failed because the server has not allowed the client to use the
 * requested authorization.
 * <li>{@link ResultCode#CONFIDENTIALITY_REQUIRED CONFIDENTIALITY_REQUIRED} -
 * the Request failed because it requires confidentiality for the communication
 * between the client and the server.
 * <li>{@link ResultCode#INSUFFICIENT_ACCESS_RIGHTS INSUFFICIENT_ACCESS_RIGHTS}
 * - the Request failed because the client does not have sufficient permission
 * to perform the requested operation.
 * <li>{@link ResultCode#STRONG_AUTH_REQUIRED STRONG_AUTH_REQUIRED} - the
 * Request failed because it requires that the client has completed a strong
 * form of authentication.
 * </ul>
 */
@SuppressWarnings("serial")
public class AuthorizationException extends ErrorResultException
{
  AuthorizationException(final Result result)
  {
    super(result);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java
New file
@@ -0,0 +1,326 @@
/*
 * 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.forgerock.opendj.ldap;
import java.io.IOException;
import java.io.OutputStream;
/**
 * A {@code ByteSequence} is a readable sequence of byte values. This interface
 * provides uniform, read-only access to many different kinds of byte sequences.
 */
public interface ByteSequence extends Comparable<ByteSequence>
{
  /**
   * Returns a {@link ByteSequenceReader} which can be used to incrementally
   * read and decode data from this byte sequence.
   * <p>
   * <b>NOTE:</b> any concurrent changes to the underlying byte sequence (if
   * mutable) may cause subsequent reads to overrun and fail.
   *
   * @return The {@link ByteSequenceReader} which can be used to incrementally
   *         read and decode data from this byte sequence.
   */
  ByteSequenceReader asReader();
  /**
   * Returns the byte value at the specified index.
   * <p>
   * An index ranges from zero to {@code length() - 1}. The first byte value of
   * the sequence is at index zero, the next at index one, and so on, as for
   * array indexing.
   *
   * @param index
   *          The index of the byte to be returned.
   * @return The byte value at the specified index.
   * @throws IndexOutOfBoundsException
   *           If the index argument is negative or not less than length().
   */
  byte byteAt(int index) throws IndexOutOfBoundsException;
  /**
   * Compares this byte sequence with the specified byte array sub-sequence for
   * order. Returns a negative integer, zero, or a positive integer depending on
   * whether this byte sequence is less than, equal to, or greater than the
   * specified byte array sub-sequence.
   *
   * @param b
   *          The byte array to compare.
   * @param offset
   *          The offset of the sub-sequence in the byte array to be compared;
   *          must be non-negative and no larger than {@code b.length} .
   * @param length
   *          The length of the sub-sequence in the byte array to be compared;
   *          must be non-negative and no larger than {@code b.length - offset}.
   * @return A negative integer, zero, or a positive integer depending on
   *         whether this byte sequence is less than, equal to, or greater than
   *         the specified byte array sub-sequence.
   * @throws IndexOutOfBoundsException
   *           If {@code offset} is negative or if {@code length} is negative or
   *           if {@code offset + length} is greater than {@code b.length}.
   */
  int compareTo(byte[] b, int offset, int length)
      throws IndexOutOfBoundsException;
  /**
   * Compares this byte sequence with the specified byte sequence for order.
   * Returns a negative integer, zero, or a positive integer depending on
   * whether this byte sequence is less than, equal to, or greater than the
   * specified object.
   *
   * @param o
   *          The byte sequence to be compared.
   * @return A negative integer, zero, or a positive integer depending on
   *         whether this byte sequence is less than, equal to, or greater than
   *         the specified object.
   */
  int compareTo(ByteSequence o);
  /**
   * Copies the contents of this byte sequence to the provided byte array.
   * <p>
   * Copying will stop when either the entire content of this sequence has been
   * copied or if the end of the provided byte array has been reached.
   * <p>
   * An invocation of the form:
   *
   * <pre>
   * src.copyTo(b)
   * </pre>
   *
   * Behaves in exactly the same way as the invocation:
   *
   * <pre>
   * src.copyTo(b, 0);
   * </pre>
   *
   * @param b
   *          The byte array to which bytes are to be copied.
   * @return The byte array.
   */
  byte[] copyTo(byte[] b);
  /**
   * Copies the contents of this byte sequence to the specified location in the
   * provided byte array.
   * <p>
   * Copying will stop when either the entire content of this sequence has been
   * copied or if the end of the provided byte array has been reached.
   * <p>
   * An invocation of the form:
   *
   * <pre>
   * src.copyTo(b, offset)
   * </pre>
   *
   * Behaves in exactly the same way as the invocation:
   *
   * <pre>
   * int len = Math.min(src.length(), b.length - offset);
   * for (int i = 0; i &lt; len; i++)
   *   b[offset + i] = src.get(i);
   * </pre>
   *
   * Except that it is potentially much more efficient.
   *
   * @param b
   *          The byte array to which bytes are to be copied.
   * @param offset
   *          The offset within the array of the first byte to be written; must
   *          be non-negative and no larger than b.length.
   * @return The byte array.
   * @throws IndexOutOfBoundsException
   *           If {@code offset} is negative.
   */
  byte[] copyTo(byte[] b, int offset) throws IndexOutOfBoundsException;
  /**
   * Appends the entire contents of this byte sequence to the provided
   * {@link ByteStringBuilder}.
   *
   * @param builder
   *          The builder to copy to.
   * @return The builder.
   */
  ByteStringBuilder copyTo(ByteStringBuilder builder);
  /**
   * Copies the entire contents of this byte sequence to the provided {@code
   * OutputStream}.
   *
   * @param stream
   *          The {@code OutputStream} to copy to.
   * @return The {@code OutputStream}.
   * @throws IOException
   *           If an error occurs while writing to the {@code OutputStream}.
   */
  OutputStream copyTo(OutputStream stream) throws IOException;
  /**
   * Indicates whether the provided byte array sub-sequence is equal to this
   * byte sequence. In order for it to be considered equal, the provided byte
   * array sub-sequence must contain the same bytes in the same order.
   *
   * @param b
   *          The byte array for which to make the determination.
   * @param offset
   *          The offset of the sub-sequence in the byte array to be compared;
   *          must be non-negative and no larger than {@code b.length} .
   * @param length
   *          The length of the sub-sequence in the byte array to be compared;
   *          must be non-negative and no larger than {@code b.length - offset}.
   * @return {@code true} if the content of the provided byte array sub-sequence
   *         is equal to that of this byte sequence, or {@code false} if not.
   * @throws IndexOutOfBoundsException
   *           If {@code offset} is negative or if {@code length} is negative or
   *           if {@code offset + length} is greater than {@code b.length}.
   */
  boolean equals(byte[] b, int offset, int length)
      throws IndexOutOfBoundsException;
  /**
   * Indicates whether the provided object is equal to this byte sequence. In
   * order for it to be considered equal, the provided object must be a byte
   * sequence containing the same bytes in the same order.
   *
   * @param o
   *          The object for which to make the determination.
   * @return {@code true} if the provided object is a byte sequence whose
   *         content is equal to that of this byte sequence, or {@code false} if
   *         not.
   */
  boolean equals(Object o);
  /**
   * Returns a hash code for this byte sequence. It will be the sum of all of
   * the bytes contained in the byte sequence.
   *
   * @return A hash code for this byte sequence.
   */
  int hashCode();
  /**
   * Returns the length of this byte sequence.
   *
   * @return The length of this byte sequence.
   */
  int length();
  /**
   * Returns a new byte sequence that is a subsequence of this byte sequence.
   * <p>
   * The subsequence starts with the byte value at the specified {@code start}
   * index and ends with the byte value at index {@code end - 1}. The length (in
   * bytes) of the returned sequence is {@code end - start}, so if {@code start
   * == end} then an empty sequence is returned.
   * <p>
   * <b>NOTE:</b> changes to the underlying byte sequence (if mutable) may
   * render the returned sub-sequence invalid.
   *
   * @param start
   *          The start index, inclusive.
   * @param end
   *          The end index, exclusive.
   * @return The newly created byte subsequence.
   * @throws IndexOutOfBoundsException
   *           If {@code start} or {@code end} are negative, if {@code end} is
   *           greater than {@code length()}, or if {@code start} is greater
   *           than {@code end}.
   */
  ByteSequence subSequence(int start, int end) throws IndexOutOfBoundsException;
  /**
   * Returns a byte array containing the bytes in this sequence in the same
   * order as this sequence. The length of the byte array will be the length of
   * this sequence.
   * <p>
   * An invocation of the form:
   *
   * <pre>
   * src.toByteArray()
   * </pre>
   *
   * Behaves in exactly the same way as the invocation:
   *
   * <pre>
   * src.copyTo(new byte[src.length()]);
   * </pre>
   *
   * @return A byte array consisting of exactly this sequence of bytes.
   */
  byte[] toByteArray();
  /**
   * Returns the {@link ByteString} representation of this byte sequence.
   *
   * @return The {@link ByteString} representation of this byte sequence.
   */
  ByteString toByteString();
  /**
   * Returns the UTF-8 decoded string representation of this byte sequence. If
   * UTF-8 decoding fails, the platform's default encoding will be used.
   *
   * @return The string representation of this byte sequence.
   */
  String toString();
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ByteSequenceReader.java
New file
@@ -0,0 +1,505 @@
/*
 * 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.forgerock.opendj.ldap;
/**
 * An interface for iteratively reading date from a {@link ByteSequence} .
 * {@code ByteSequenceReader} must be created using the associated {@code
 * ByteSequence}'s {@code asReader()} method.
 */
public final class ByteSequenceReader
{
  // The current position in the byte sequence.
  private int pos = 0;
  // The underlying byte sequence.
  private final ByteSequence sequence;
  /**
   * Creates a new byte sequence reader whose source is the provided byte
   * sequence.
   * <p>
   * <b>NOTE:</b> any concurrent changes to the underlying byte sequence (if
   * mutable) may cause subsequent reads to overrun and fail.
   * <p>
   * This constructor is package private: construction must be performed using
   * {@link ByteSequence#asReader()}.
   *
   * @param sequence
   *          The byte sequence to be read.
   */
  ByteSequenceReader(final ByteSequence sequence)
  {
    this.sequence = sequence;
  }
  /**
   * Relative get method. Reads the byte at the current position.
   *
   * @return The byte at this reader's current position.
   * @throws IndexOutOfBoundsException
   *           If there are fewer bytes remaining in this reader than are
   *           required to satisfy the request, that is, if {@code remaining()
   *           &lt; 1}.
   */
  public byte get() throws IndexOutOfBoundsException
  {
    final byte b = sequence.byteAt(pos);
    pos++;
    return b;
  }
  /**
   * Relative bulk get method. This method transfers bytes from this reader into
   * the given destination array. An invocation of this method of the form:
   *
   * <pre>
   * src.get(b);
   * </pre>
   *
   * Behaves in exactly the same way as the invocation:
   *
   * <pre>
   * src.get(b, 0, b.length);
   * </pre>
   *
   * @param b
   *          The byte array into which bytes are to be written.
   * @throws IndexOutOfBoundsException
   *           If there are fewer bytes remaining in this reader than are
   *           required to satisfy the request, that is, if {@code remaining()
   *           &lt; b.length}.
   */
  public void get(final byte[] b) throws IndexOutOfBoundsException
  {
    get(b, 0, b.length);
  }
  /**
   * Relative bulk get method. Copies {@code length} bytes from this reader into
   * the given array, starting at the current position of this reader and at the
   * given {@code offset} in the array. The position of this reader is then
   * incremented by {@code length}. In other words, an invocation of this method
   * of the form:
   *
   * <pre>
   * src.get(b, offset, length);
   * </pre>
   *
   * Has exactly the same effect as the loop:
   *
   * <pre>
   * for (int i = offset; i &lt; offset + length; i++)
   *   b[i] = src.get();
   * </pre>
   *
   * Except that it first checks that there are sufficient bytes in this buffer
   * and it is potentially much more efficient.
   *
   * @param b
   *          The byte array into which bytes are to be written.
   * @param offset
   *          The offset within the array of the first byte to be written; must
   *          be non-negative and no larger than {@code b.length}.
   * @param length
   *          The number of bytes to be written to the given array; must be
   *          non-negative and no larger than {@code b.length} .
   * @throws IndexOutOfBoundsException
   *           If there are fewer bytes remaining in this reader than are
   *           required to satisfy the request, that is, if {@code remaining()
   *           &lt; length}.
   */
  public void get(final byte[] b, final int offset, final int length)
      throws IndexOutOfBoundsException
  {
    if (offset < 0 || length < 0 || offset + length > b.length
        || length > remaining())
    {
      throw new IndexOutOfBoundsException();
    }
    sequence.subSequence(pos, pos + length).copyTo(b, offset);
    pos += length;
  }
  /**
   * Relative get method for reading a multi-byte BER length. Reads the next one
   * to five bytes at this reader's current position, composing them into a
   * integer value and then increments the position by the number of bytes read.
   *
   * @return The integer value representing the length at this reader's current
   *         position.
   * @throws IndexOutOfBoundsException
   *           If there are fewer bytes remaining in this reader than are
   *           required to satisfy the request.
   */
  public int getBERLength() throws IndexOutOfBoundsException
  {
    // Make sure we have at least one byte to read.
    int newPos = pos + 1;
    if (newPos > sequence.length())
    {
      throw new IndexOutOfBoundsException();
    }
    int length = sequence.byteAt(pos) & 0x7F;
    if (length != sequence.byteAt(pos))
    {
      // Its a multi-byte length
      final int numLengthBytes = length;
      newPos = pos + 1 + numLengthBytes;
      // Make sure we have the bytes needed
      if (numLengthBytes > 4 || newPos > sequence.length())
      {
        // Shouldn't have more than 4 bytes
        throw new IndexOutOfBoundsException();
      }
      length = 0x00;
      for (int i = pos + 1; i < newPos; i++)
      {
        length = length << 8 | sequence.byteAt(i) & 0xFF;
      }
    }
    pos = newPos;
    return length;
  }
  /**
   * Relative bulk get method. Returns a {@link ByteSequence} whose content is
   * the next {@code length} bytes from this reader, starting at the current
   * position of this reader. The position of this reader is then incremented by
   * {@code length}.
   * <p>
   * <b>NOTE:</b> The value returned from this method should NEVER be cached as
   * it prevents the contents of the underlying byte stream from being garbage
   * collected.
   *
   * @param length
   *          The length of the byte sequence to be returned.
   * @return The byte sequence whose content is the next {@code length} bytes
   *         from this reader.
   * @throws IndexOutOfBoundsException
   *           If there are fewer bytes remaining in this reader than are
   *           required to satisfy the request, that is, if {@code remaining()
   *           &lt; length}.
   */
  public ByteSequence getByteSequence(final int length)
      throws IndexOutOfBoundsException
  {
    final int newPos = pos + length;
    final ByteSequence subSequence = sequence.subSequence(pos, newPos);
    pos = newPos;
    return subSequence;
  }
  /**
   * Relative bulk get method. Returns a {@link ByteString} whose content is the
   * next {@code length} bytes from this reader, starting at the current
   * position of this reader. The position of this reader is then incremented by
   * {@code length}.
   * <p>
   * An invocation of this method of the form:
   *
   * <pre>
   * src.getByteString(length);
   * </pre>
   *
   * Has exactly the same effect as:
   *
   * <pre>
   * src.getByteSequence(length).toByteString();
   * </pre>
   *
   * <b>NOTE:</b> The value returned from this method should NEVER be cached as
   * it prevents the contents of the underlying byte stream from being garbage
   * collected.
   *
   * @param length
   *          The length of the byte string to be returned.
   * @return The byte string whose content is the next {@code length} bytes from
   *         this reader.
   * @throws IndexOutOfBoundsException
   *           If there are fewer bytes remaining in this reader than are
   *           required to satisfy the request, that is, if {@code remaining()
   *           &lt; length}.
   */
  public ByteString getByteString(final int length)
      throws IndexOutOfBoundsException
  {
    return getByteSequence(length).toByteString();
  }
  /**
   * Relative get method for reading an integer value. Reads the next four bytes
   * at this reader's current position, composing them into an integer value
   * according to big-endian byte order, and then increments the position by
   * four.
   *
   * @return The integer value at this reader's current position.
   * @throws IndexOutOfBoundsException
   *           If there are fewer bytes remaining in this reader than are
   *           required to satisfy the request, that is, if {@code remaining()
   *           &lt; 4}.
   */
  public int getInt() throws IndexOutOfBoundsException
  {
    if (remaining() < 4)
    {
      throw new IndexOutOfBoundsException();
    }
    int v = 0;
    for (int i = 0; i < 4; i++)
    {
      v <<= 8;
      v |= sequence.byteAt(pos++) & 0xFF;
    }
    return v;
  }
  /**
   * Relative get method for reading a long value. Reads the next eight bytes at
   * this reader's current position, composing them into a long value according
   * to big-endian byte order, and then increments the position by eight.
   *
   * @return The long value at this reader's current position.
   * @throws IndexOutOfBoundsException
   *           If there are fewer bytes remaining in this reader than are
   *           required to satisfy the request, that is, if {@code remaining()
   *           &lt; 8}.
   */
  public long getLong() throws IndexOutOfBoundsException
  {
    if (remaining() < 8)
    {
      throw new IndexOutOfBoundsException();
    }
    long v = 0;
    for (int i = 0; i < 8; i++)
    {
      v <<= 8;
      v |= sequence.byteAt(pos++) & 0xFF;
    }
    return v;
  }
  /**
   * Relative get method for reading an short value. Reads the next 2 bytes at
   * this reader's current position, composing them into an short value
   * according to big-endian byte order, and then increments the position by
   * two.
   *
   * @return The integer value at this reader's current position.
   * @throws IndexOutOfBoundsException
   *           If there are fewer bytes remaining in this reader than are
   *           required to satisfy the request, that is, if {@code remaining()
   *           &lt; 2}.
   */
  public short getShort() throws IndexOutOfBoundsException
  {
    if (remaining() < 2)
    {
      throw new IndexOutOfBoundsException();
    }
    short v = 0;
    for (int i = 0; i < 2; i++)
    {
      v <<= 8;
      v |= sequence.byteAt(pos++) & 0xFF;
    }
    return v;
  }
  /**
   * Relative get method for reading a UTF-8 encoded string. Reads the next
   * number of specified bytes at this reader's current position, decoding them
   * into a string using UTF-8 and then increments the position by the number of
   * bytes read. If UTF-8 decoding fails, the platform's default encoding will
   * be used.
   *
   * @param length
   *          The number of bytes to read and decode.
   * @return The string value at the reader's current position.
   * @throws IndexOutOfBoundsException
   *           If there are fewer bytes remaining in this reader than are
   *           required to satisfy the request, that is, if {@code remaining()
   *           &lt; length}.
   */
  public String getString(final int length) throws IndexOutOfBoundsException
  {
    if (remaining() < length)
    {
      throw new IndexOutOfBoundsException();
    }
    final int newPos = pos + length;
    final String str = sequence.subSequence(pos, pos + length).toString();
    pos = newPos;
    return str;
  }
  /**
   * Returns this reader's position.
   *
   * @return The position of this reader.
   */
  public int position()
  {
    return pos;
  }
  /**
   * Sets this reader's position.
   *
   * @param pos
   *          The new position value; must be non-negative and no larger than
   *          the length of the underlying byte sequence.
   * @throws IndexOutOfBoundsException
   *           If the position is negative or larger than the length of the
   *           underlying byte sequence.
   */
  public void position(final int pos) throws IndexOutOfBoundsException
  {
    if (pos > sequence.length() || pos < 0)
    {
      throw new IndexOutOfBoundsException();
    }
    this.pos = pos;
  }
  /**
   * Returns the number of bytes between the current position and the end of the
   * underlying byte sequence.
   *
   * @return The number of bytes between the current position and the end of the
   *         underlying byte sequence.
   */
  public int remaining()
  {
    return sequence.length() - pos;
  }
  /**
   * Rewinds this reader's position to zero.
   * <p>
   * An invocation of this method of the form:
   *
   * <pre>
   * src.rewind();
   * </pre>
   *
   * Has exactly the same effect as:
   *
   * <pre>
   * src.position(0);
   * </pre>
   */
  public void rewind()
  {
    position(0);
  }
  /**
   * Skips the given number of bytes. Negative values are allowed.
   * <p>
   * An invocation of this method of the form:
   *
   * <pre>
   * src.skip(length);
   * </pre>
   *
   * Has exactly the same effect as:
   *
   * <pre>
   * src.position(position() + length);
   * </pre>
   *
   * @param length
   *          The number of bytes to skip.
   * @throws IndexOutOfBoundsException
   *           If the new position is less than 0 or greater than the length of
   *           the underlying byte sequence.
   */
  public void skip(final int length) throws IndexOutOfBoundsException
  {
    position(pos + length);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    return sequence.toString();
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ByteString.java
New file
@@ -0,0 +1,717 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.logging.Level;
import com.forgerock.opendj.util.StaticUtils;
/**
 * An immutable sequence of bytes backed by a byte array.
 */
public final class ByteString implements ByteSequence
{
  // Singleton empty byte string.
  private static final ByteString EMPTY = wrap(new byte[0]);
  /**
   * Returns an empty byte string.
   *
   * @return An empty byte string.
   */
  public static ByteString empty()
  {
    return EMPTY;
  }
  /**
   * Returns a byte string containing the big-endian encoded bytes of the
   * provided integer.
   *
   * @param i
   *          The integer to encode.
   * @return The byte string containing the big-endian encoded bytes of the
   *         provided integer.
   */
  public static ByteString valueOf(int i)
  {
    final byte[] bytes = new byte[4];
    for (int j = 3; j >= 0; j--)
    {
      bytes[j] = (byte) (i & 0xFF);
      i >>>= 8;
    }
    return wrap(bytes);
  }
  /**
   * Returns a byte string containing the big-endian encoded bytes of the
   * provided long.
   *
   * @param l
   *          The long to encode.
   * @return The byte string containing the big-endian encoded bytes of the
   *         provided long.
   */
  public static ByteString valueOf(long l)
  {
    final byte[] bytes = new byte[8];
    for (int i = 7; i >= 0; i--)
    {
      bytes[i] = (byte) (l & 0xFF);
      l >>>= 8;
    }
    return wrap(bytes);
  }
  /**
   * Returns a byte string containing the provided object. If the object is an
   * instance of {@code ByteSequence} then it is converted to a byte string
   * using the {@code toByteString()} method. Otherwise a new byte string is
   * created containing the UTF-8 encoded bytes of the string representation of
   * the provided object.
   *
   * @param o
   *          The object to use.
   * @return The byte string containing the provided object.
   */
  public static ByteString valueOf(final Object o)
  {
    if (o instanceof ByteSequence)
    {
      return ((ByteSequence) o).toByteString();
    }
    else
    {
      return wrap(StaticUtils.getBytes(o.toString()));
    }
  }
  /**
   * Returns a byte string containing the UTF-8 encoded bytes of the provided
   * string.
   *
   * @param s
   *          The string to use.
   * @return The byte string with the encoded bytes of the provided string.
   */
  public static ByteString valueOf(final String s)
  {
    return wrap(StaticUtils.getBytes(s));
  }
  /**
   * Returns a byte string containing the UTF-8 encoded bytes of the provided
   * char array.
   *
   * @param chars
   *          The char array to use.
   * @return A byte string containing the UTF-8 encoded bytes of the provided
   *         char array.
   */
  public static ByteString valueOf(final char[] chars)
  {
    Charset utf8 = Charset.forName("UTF-8");
    ByteBuffer buffer = utf8.encode(CharBuffer.wrap(chars));
    byte[] bytes = new byte[buffer.remaining()];
    buffer.get(bytes);
    return wrap(bytes);
  }
  /**
   * Returns a byte string that wraps the provided byte array.
   * <p>
   * <b>NOTE:</b> this method takes ownership of the provided byte array and,
   * therefore, the byte array MUST NOT be altered directly after this method
   * returns.
   *
   * @param b
   *          The byte array to wrap.
   * @return The byte string that wraps the given byte array.
   */
  public static ByteString wrap(final byte[] b)
  {
    return new ByteString(b, 0, b.length);
  }
  /**
   * Returns a byte string that wraps a subsequence of the provided byte array.
   * <p>
   * <b>NOTE:</b> this method takes ownership of the provided byte array and,
   * therefore, the byte array MUST NOT be altered directly after this method
   * returns.
   *
   * @param b
   *          The byte array to wrap.
   * @param offset
   *          The offset of the byte array to be used; must be non-negative and
   *          no larger than {@code b.length} .
   * @param length
   *          The length of the byte array to be used; must be non-negative and
   *          no larger than {@code b.length - offset}.
   * @return The byte string that wraps the given byte array.
   * @throws IndexOutOfBoundsException
   *           If {@code offset} is negative or if {@code length} is negative or
   *           if {@code offset + length} is greater than {@code b.length}.
   */
  public static ByteString wrap(final byte[] b, final int offset,
      final int length) throws IndexOutOfBoundsException
  {
    checkArrayBounds(b, offset, length);
    return new ByteString(b, offset, length);
  }
  /**
   * Checks the array bounds of the provided byte array sub-sequence, throwing
   * an {@code IndexOutOfBoundsException} if they are illegal.
   *
   * @param b
   *          The byte array.
   * @param offset
   *          The offset of the byte array to be checked; must be non-negative
   *          and no larger than {@code b.length}.
   * @param length
   *          The length of the byte array to be checked; must be non-negative
   *          and no larger than {@code b.length - offset}.
   * @throws IndexOutOfBoundsException
   *           If {@code offset} is negative or if {@code length} is negative or
   *           if {@code offset + length} is greater than {@code b.length}.
   */
  static void checkArrayBounds(final byte[] b, final int offset,
      final int length) throws IndexOutOfBoundsException
  {
    if (offset < 0 || offset > b.length || length < 0
        || offset + length > b.length || offset + length < 0)
    {
      throw new IndexOutOfBoundsException();
    }
  }
  /**
   * Compares two byte array sub-sequences and returns a value that indicates
   * their relative order.
   *
   * @param b1
   *          The byte array containing the first sub-sequence.
   * @param offset1
   *          The offset of the first byte array sub-sequence.
   * @param length1
   *          The length of the first byte array sub-sequence.
   * @param b2
   *          The byte array containing the second sub-sequence.
   * @param offset2
   *          The offset of the second byte array sub-sequence.
   * @param length2
   *          The length of the second byte array sub-sequence.
   * @return A negative integer if first byte array sub-sequence should come
   *         before the second byte array sub-sequence in ascending order, a
   *         positive integer if the first byte array sub-sequence should come
   *         after the byte array sub-sequence in ascending order, or zero if
   *         there is no difference between the two byte array sub-sequences
   *         with regard to ordering.
   */
  static int compareTo(final byte[] b1, final int offset1, final int length1,
      final byte[] b2, final int offset2, final int length2)
  {
    int count = Math.min(length1, length2);
    int i = offset1;
    int j = offset2;
    while (count-- != 0)
    {
      final int firstByte = 0xFF & b1[i++];
      final int secondByte = 0xFF & b2[j++];
      if (firstByte != secondByte)
      {
        return firstByte - secondByte;
      }
    }
    return length1 - length2;
  }
  /**
   * Indicates whether two byte array sub-sequences are equal. In order for them
   * to be considered equal, they must contain the same bytes in the same order.
   *
   * @param b1
   *          The byte array containing the first sub-sequence.
   * @param offset1
   *          The offset of the first byte array sub-sequence.
   * @param length1
   *          The length of the first byte array sub-sequence.
   * @param b2
   *          The byte array containing the second sub-sequence.
   * @param offset2
   *          The offset of the second byte array sub-sequence.
   * @param length2
   *          The length of the second byte array sub-sequence.
   * @return {@code true} if the two byte array sub-sequences have the same
   *         content, or {@code false} if not.
   */
  static boolean equals(final byte[] b1, final int offset1, final int length1,
      final byte[] b2, final int offset2, final int length2)
  {
    if (length1 != length2)
    {
      return false;
    }
    int i = offset1;
    int j = offset2;
    int count = length1;
    while (count-- != 0)
    {
      if (b1[i++] != b2[j++])
      {
        return false;
      }
    }
    return true;
  }
  /**
   * Returns a hash code for the provided byte array sub-sequence.
   *
   * @param b
   *          The byte array.
   * @param offset
   *          The offset of the byte array sub-sequence.
   * @param length
   *          The length of the byte array sub-sequence.
   * @return A hash code for the provided byte array sub-sequence.
   */
  static int hashCode(final byte[] b, final int offset, final int length)
  {
    int hashCode = 1;
    int i = offset;
    int count = length;
    while (count-- != 0)
    {
      hashCode = 31 * hashCode + b[i++];
    }
    return hashCode;
  }
  /**
   * Returns the UTF-8 decoded string representation of the provided byte array
   * sub-sequence. If UTF-8 decoding fails, the platform's default encoding will
   * be used.
   *
   * @param b
   *          The byte array.
   * @param offset
   *          The offset of the byte array sub-sequence.
   * @param length
   *          The length of the byte array sub-sequence.
   * @return The string representation of the byte array sub-sequence.
   */
  static String toString(final byte[] b, final int offset, final int length)
  {
    String stringValue;
    try
    {
      stringValue = new String(b, offset, length, "UTF-8");
    }
    catch (final Exception e)
    {
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
      {
        StaticUtils.DEBUG_LOG.warning("Unable to decode ByteString "
            + "bytes as UTF-8 string: " + e.toString());
      }
      stringValue = new String(b, offset, length);
    }
    return stringValue;
  }
  // These are package private so that compression and crypto
  // functionality may directly access the fields.
  // The buffer where data is stored.
  final byte[] buffer;
  // The number of bytes to expose from the buffer.
  final int length;
  // The start index of the range of bytes to expose through this byte
  // string.
  final int offset;
  /**
   * Creates a new byte string that wraps a subsequence of the provided byte
   * array.
   * <p>
   * <b>NOTE:</b> this method takes ownership of the provided byte array and,
   * therefore, the byte array MUST NOT be altered directly after this method
   * returns.
   *
   * @param b
   *          The byte array to wrap.
   * @param offset
   *          The offset of the byte array to be used; must be non-negative and
   *          no larger than {@code b.length} .
   * @param length
   *          The length of the byte array to be used; must be non-negative and
   *          no larger than {@code b.length - offset}.
   */
  private ByteString(final byte[] b, final int offset, final int length)
  {
    this.buffer = b;
    this.offset = offset;
    this.length = length;
  }
  /**
   * Returns a {@link ByteSequenceReader} which can be used to incrementally
   * read and decode data from this byte string.
   *
   * @return The {@link ByteSequenceReader} which can be used to incrementally
   *         read and decode data from this byte string.
   */
  public ByteSequenceReader asReader()
  {
    return new ByteSequenceReader(this);
  }
  /**
   * {@inheritDoc}
   */
  public byte byteAt(final int index) throws IndexOutOfBoundsException
  {
    if (index >= length || index < 0)
    {
      throw new IndexOutOfBoundsException();
    }
    return buffer[offset + index];
  }
  /**
   * {@inheritDoc}
   */
  public int compareTo(final byte[] b, final int offset, final int length)
      throws IndexOutOfBoundsException
  {
    checkArrayBounds(b, offset, length);
    return compareTo(this.buffer, this.offset, this.length, b, offset, length);
  }
  /**
   * {@inheritDoc}
   */
  public int compareTo(final ByteSequence o)
  {
    if (this == o)
    {
      return 0;
    }
    return -o.compareTo(buffer, offset, length);
  }
  /**
   * {@inheritDoc}
   */
  public byte[] copyTo(final byte[] b)
  {
    copyTo(b, 0);
    return b;
  }
  /**
   * {@inheritDoc}
   */
  public byte[] copyTo(final byte[] b, final int offset)
      throws IndexOutOfBoundsException
  {
    if (offset < 0)
    {
      throw new IndexOutOfBoundsException();
    }
    System.arraycopy(buffer, this.offset, b, offset, Math.min(length, b.length
        - offset));
    return b;
  }
  /**
   * {@inheritDoc}
   */
  public ByteStringBuilder copyTo(final ByteStringBuilder builder)
  {
    builder.append(buffer, offset, length);
    return builder;
  }
  /**
   * {@inheritDoc}
   */
  public OutputStream copyTo(final OutputStream stream) throws IOException
  {
    stream.write(buffer, offset, length);
    return stream;
  }
  /**
   * {@inheritDoc}
   */
  public boolean equals(final byte[] b, final int offset, final int length)
      throws IndexOutOfBoundsException
  {
    checkArrayBounds(b, offset, length);
    return equals(this.buffer, this.offset, this.length, b, offset, length);
  }
  /**
   * Indicates whether the provided object is equal to this byte string. In
   * order for it to be considered equal, the provided object must be a byte
   * sequence containing the same bytes in the same order.
   *
   * @param o
   *          The object for which to make the determination.
   * @return {@code true} if the provided object is a byte sequence whose
   *         content is equal to that of this byte string, or {@code false} if
   *         not.
   */
  @Override
  public boolean equals(final Object o)
  {
    if (this == o)
    {
      return true;
    }
    else if (o instanceof ByteSequence)
    {
      final ByteSequence other = (ByteSequence) o;
      return other.equals(buffer, offset, length);
    }
    else
    {
      return false;
    }
  }
  /**
   * Returns a hash code for this byte string. It will be the sum of all of the
   * bytes contained in the byte string.
   *
   * @return A hash code for this byte string.
   */
  @Override
  public int hashCode()
  {
    return hashCode(buffer, offset, length);
  }
  /**
   * {@inheritDoc}
   */
  public int length()
  {
    return length;
  }
  /**
   * {@inheritDoc}
   */
  public ByteString subSequence(final int start, final int end)
      throws IndexOutOfBoundsException
  {
    if (start < 0 || start > end || end > length)
    {
      throw new IndexOutOfBoundsException();
    }
    return new ByteString(buffer, offset + start, end - start);
  }
  /**
   * {@inheritDoc}
   */
  public byte[] toByteArray()
  {
    return copyTo(new byte[length]);
  }
  /**
   * {@inheritDoc}
   */
  public ByteString toByteString()
  {
    return this;
  }
  /**
   * Returns the UTF-8 decoded char array representation of this byte sequence.
   *
   * @return The UTF-8 decoded char array representation of this byte sequence.
   */
  public char[] toCharArray()
  {
    Charset utf8 = Charset.forName("UTF-8");
    CharBuffer charBuffer = utf8
        .decode(ByteBuffer.wrap(buffer, offset, length));
    char[] chars = new char[charBuffer.remaining()];
    charBuffer.get(chars);
    return chars;
  }
  /**
   * Returns the integer value represented by the first four bytes of this byte
   * string in big-endian order.
   *
   * @return The integer value represented by the first four bytes of this byte
   *         string in big-endian order.
   * @throws IndexOutOfBoundsException
   *           If this byte string has less than four bytes.
   */
  public int toInt() throws IndexOutOfBoundsException
  {
    if (length < 4)
    {
      throw new IndexOutOfBoundsException();
    }
    int v = 0;
    for (int i = 0; i < 4; i++)
    {
      v <<= 8;
      v |= buffer[offset + i] & 0xFF;
    }
    return v;
  }
  /**
   * Returns the long value represented by the first eight bytes of this byte
   * string in big-endian order.
   *
   * @return The long value represented by the first eight bytes of this byte
   *         string in big-endian order.
   * @throws IndexOutOfBoundsException
   *           If this byte string has less than eight bytes.
   */
  public long toLong() throws IndexOutOfBoundsException
  {
    if (length < 8)
    {
      throw new IndexOutOfBoundsException();
    }
    long v = 0;
    for (int i = 0; i < 8; i++)
    {
      v <<= 8;
      v |= buffer[offset + i] & 0xFF;
    }
    return v;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    return toString(buffer, offset, length);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java
New file
@@ -0,0 +1,1118 @@
/*
 * 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.forgerock.opendj.ldap;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import com.forgerock.opendj.util.StaticUtils;
/**
 * A mutable sequence of bytes backed by a byte array.
 */
public final class ByteStringBuilder implements ByteSequence
{
  /**
   * A sub-sequence of the parent byte string builder. The sub-sequence will be
   * robust against all updates to the byte string builder except for
   * invocations of the method {@code clear()}.
   */
  private final class SubSequence implements ByteSequence
  {
    // The length of the sub-sequence.
    private final int subLength;
    // The offset of the sub-sequence.
    private final int subOffset;
    /**
     * Creates a new sub-sequence.
     *
     * @param offset
     *          The offset of the sub-sequence.
     * @param length
     *          The length of the sub-sequence.
     */
    private SubSequence(final int offset, final int length)
    {
      this.subOffset = offset;
      this.subLength = length;
    }
    /**
     * {@inheritDoc}
     */
    public ByteSequenceReader asReader()
    {
      return new ByteSequenceReader(this);
    }
    /**
     * {@inheritDoc}
     */
    public byte byteAt(final int index) throws IndexOutOfBoundsException
    {
      if (index >= subLength || index < 0)
      {
        throw new IndexOutOfBoundsException();
      }
      // Protect against reallocation: use builder's buffer.
      return buffer[subOffset + index];
    }
    /**
     * {@inheritDoc}
     */
    public int compareTo(final byte[] b, final int offset, final int length)
        throws IndexOutOfBoundsException
    {
      ByteString.checkArrayBounds(b, offset, length);
      // Protect against reallocation: use builder's buffer.
      return ByteString.compareTo(buffer, subOffset, subLength, b, offset,
          length);
    }
    /**
     * {@inheritDoc}
     */
    public int compareTo(final ByteSequence o)
    {
      if (this == o)
      {
        return 0;
      }
      // Protect against reallocation: use builder's buffer.
      return -o.compareTo(buffer, subOffset, subLength);
    }
    /**
     * {@inheritDoc}
     */
    public byte[] copyTo(final byte[] b)
    {
      copyTo(b, 0);
      return b;
    }
    /**
     * {@inheritDoc}
     */
    public byte[] copyTo(final byte[] b, final int offset)
        throws IndexOutOfBoundsException
    {
      if (offset < 0)
      {
        throw new IndexOutOfBoundsException();
      }
      // Protect against reallocation: use builder's buffer.
      System.arraycopy(buffer, subOffset, b, offset, Math.min(subLength,
          b.length - offset));
      return b;
    }
    /**
     * {@inheritDoc}
     */
    public ByteStringBuilder copyTo(final ByteStringBuilder builder)
    {
      // Protect against reallocation: use builder's buffer.
      return builder.append(buffer, subOffset, subLength);
    }
    /**
     * {@inheritDoc}
     */
    public OutputStream copyTo(final OutputStream stream) throws IOException
    {
      // Protect against reallocation: use builder's buffer.
      stream.write(buffer, subOffset, subLength);
      return stream;
    }
    /**
     * {@inheritDoc}
     */
    public boolean equals(final byte[] b, final int offset, final int length)
        throws IndexOutOfBoundsException
    {
      ByteString.checkArrayBounds(b, offset, length);
      // Protect against reallocation: use builder's buffer.
      return ByteString.equals(buffer, subOffset, subLength, b, offset, length);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(final Object o)
    {
      if (this == o)
      {
        return true;
      }
      else if (o instanceof ByteSequence)
      {
        final ByteSequence other = (ByteSequence) o;
        // Protect against reallocation: use builder's buffer.
        return other.equals(buffer, subOffset, subLength);
      }
      else
      {
        return false;
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode()
    {
      // Protect against reallocation: use builder's buffer.
      return ByteString.hashCode(buffer, subOffset, subLength);
    }
    /**
     * {@inheritDoc}
     */
    public int length()
    {
      return subLength;
    }
    /**
     * {@inheritDoc}
     */
    public ByteSequence subSequence(final int start, final int end)
        throws IndexOutOfBoundsException
    {
      if (start < 0 || start > end || end > subLength)
      {
        throw new IndexOutOfBoundsException();
      }
      return new SubSequence(subOffset + start, end - start);
    }
    /**
     * {@inheritDoc}
     */
    public byte[] toByteArray()
    {
      return copyTo(new byte[subLength]);
    }
    /**
     * {@inheritDoc}
     */
    public ByteString toByteString()
    {
      // Protect against reallocation: use builder's buffer.
      final byte[] b = new byte[subLength];
      System.arraycopy(buffer, subOffset, b, 0, subLength);
      return ByteString.wrap(b);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String toString()
    {
      // Protect against reallocation: use builder's buffer.
      return ByteString.toString(buffer, subOffset, subLength);
    }
  }
  // These are package private so that compression and crypto
  // functionality may directly access the fields.
  // The buffer where data is stored.
  byte[] buffer;
  // The number of bytes to expose from the buffer.
  int length;
  /**
   * Creates a new byte string builder with an initial capacity of 32 bytes.
   */
  public ByteStringBuilder()
  {
    // Initially create a 32 byte buffer.
    this(32);
  }
  /**
   * Creates a new byte string builder with the specified initial capacity.
   *
   * @param capacity
   *          The initial capacity.
   * @throws IllegalArgumentException
   *           If the {@code capacity} is negative.
   */
  public ByteStringBuilder(final int capacity) throws IllegalArgumentException
  {
    if (capacity < 0)
    {
      throw new IllegalArgumentException();
    }
    this.buffer = new byte[capacity];
    this.length = 0;
  }
  /**
   * Appends the provided byte to this byte string builder.
   *
   * @param b
   *          The byte to be appended to this byte string builder.
   * @return This byte string builder.
   */
  public ByteStringBuilder append(final byte b)
  {
    ensureAdditionalCapacity(1);
    buffer[length++] = b;
    return this;
  }
  /**
   * Appends the provided byte array to this byte string builder.
   * <p>
   * An invocation of the form:
   *
   * <pre>
   * src.append(b)
   * </pre>
   *
   * Behaves in exactly the same way as the invocation:
   *
   * <pre>
   * src.append(b, 0, b.length);
   * </pre>
   *
   * @param b
   *          The byte array to be appended to this byte string builder.
   * @return This byte string builder.
   */
  public ByteStringBuilder append(final byte[] b)
  {
    return append(b, 0, b.length);
  }
  /**
   * Appends the provided byte array to this byte string builder.
   *
   * @param b
   *          The byte array to be appended to this byte string builder.
   * @param offset
   *          The offset of the byte array to be used; must be non-negative and
   *          no larger than {@code b.length} .
   * @param length
   *          The length of the byte array to be used; must be non-negative and
   *          no larger than {@code b.length - offset}.
   * @return This byte string builder.
   * @throws IndexOutOfBoundsException
   *           If {@code offset} is negative or if {@code length} is negative or
   *           if {@code offset + length} is greater than {@code b.length}.
   */
  public ByteStringBuilder append(final byte[] b, final int offset,
      final int length) throws IndexOutOfBoundsException
  {
    ByteString.checkArrayBounds(b, offset, length);
    if (length != 0)
    {
      ensureAdditionalCapacity(length);
      System.arraycopy(b, offset, buffer, this.length, length);
      this.length += length;
    }
    return this;
  }
  /**
   * Appends the provided {@code ByteBuffer} to this byte string builder.
   *
   * @param buffer
   *          The byte buffer to be appended to this byte string builder.
   * @param length
   *          The number of bytes to be appended from {@code buffer}.
   * @return This byte string builder.
   * @throws IndexOutOfBoundsException
   *           If {@code length} is less than zero or greater than {@code
   *           buffer.remaining()}.
   */
  public ByteStringBuilder append(final ByteBuffer buffer, final int length)
      throws IndexOutOfBoundsException
  {
    if (length < 0 || length > buffer.remaining())
    {
      throw new IndexOutOfBoundsException();
    }
    if (length != 0)
    {
      ensureAdditionalCapacity(length);
      buffer.get(this.buffer, this.length, length);
      this.length += length;
    }
    return this;
  }
  /**
   * Appends the provided {@link ByteSequence} to this byte string builder.
   *
   * @param bytes
   *          The byte sequence to be appended to this byte string builder.
   * @return This byte string builder.
   */
  public ByteStringBuilder append(final ByteSequence bytes)
  {
    return bytes.copyTo(this);
  }
  /**
   * Appends the provided {@link ByteSequenceReader} to this byte string
   * builder.
   *
   * @param reader
   *          The byte sequence reader to be appended to this byte string
   *          builder.
   * @param length
   *          The number of bytes to be appended from {@code reader}.
   * @return This byte string builder.
   * @throws IndexOutOfBoundsException
   *           If {@code length} is less than zero or greater than {@code
   *           reader.remaining()}.
   */
  public ByteStringBuilder append(final ByteSequenceReader reader,
      final int length) throws IndexOutOfBoundsException
  {
    if (length < 0 || length > reader.remaining())
    {
      throw new IndexOutOfBoundsException();
    }
    if (length != 0)
    {
      ensureAdditionalCapacity(length);
      reader.get(buffer, this.length, length);
      this.length += length;
    }
    return this;
  }
  /**
   * Appends the provided {@code InputStream} to this byte string builder.
   *
   * @param stream
   *          The input stream to be appended to this byte string builder.
   * @param length
   *          The maximum number of bytes to be appended from {@code buffer}.
   * @return The number of bytes read from the input stream, or {@code -1} if
   *         the end of the input stream has been reached.
   * @throws IndexOutOfBoundsException
   *           If {@code length} is less than zero.
   * @throws IOException
   *           If an I/O error occurs.
   */
  public int append(final InputStream stream, final int length)
      throws IndexOutOfBoundsException, IOException
  {
    if (length < 0)
    {
      throw new IndexOutOfBoundsException();
    }
    ensureAdditionalCapacity(length);
    final int bytesRead = stream.read(buffer, this.length, length);
    if (bytesRead > 0)
    {
      this.length += bytesRead;
    }
    return bytesRead;
  }
  /**
   * Appends the big-endian encoded bytes of the provided integer to this byte
   * string builder.
   *
   * @param i
   *          The integer whose big-endian encoding is to be appended to this
   *          byte string builder.
   * @return This byte string builder.
   */
  public ByteStringBuilder append(int i)
  {
    ensureAdditionalCapacity(4);
    for (int j = length + 3; j >= length; j--)
    {
      buffer[j] = (byte) (i & 0xFF);
      i >>>= 8;
    }
    length += 4;
    return this;
  }
  /**
   * Appends the big-endian encoded bytes of the provided long to this byte
   * string builder.
   *
   * @param l
   *          The long whose big-endian encoding is to be appended to this byte
   *          string builder.
   * @return This byte string builder.
   */
  public ByteStringBuilder append(long l)
  {
    ensureAdditionalCapacity(8);
    for (int i = length + 7; i >= length; i--)
    {
      buffer[i] = (byte) (l & 0xFF);
      l >>>= 8;
    }
    length += 8;
    return this;
  }
  /**
   * Appends the provided object to this byte string builder. If the object is
   * an instance of {@code ByteSequence} then its contents will be appended
   * directly to this byte string builder using the {@code append(ByteSequence)}
   * method. Otherwise the string representation of the object will be appended
   * using the {@code append(String)} method.
   *
   * @param o
   *          The object to be appended to this byte string builder.
   * @return This byte string builder.
   */
  public ByteStringBuilder append(final Object o)
  {
    if (o == null)
    {
      return this;
    }
    else if (o instanceof ByteSequence)
    {
      return append((ByteSequence) o);
    }
    else
    {
      return append(o.toString());
    }
  }
  /**
   * Appends the big-endian encoded bytes of the provided short to this byte
   * string builder.
   *
   * @param i
   *          The short whose big-endian encoding is to be appended to this byte
   *          string builder.
   * @return This byte string builder.
   */
  public ByteStringBuilder append(short i)
  {
    ensureAdditionalCapacity(2);
    for (int j = length + 1; j >= length; j--)
    {
      buffer[j] = (byte) (i & 0xFF);
      i >>>= 8;
    }
    length += 2;
    return this;
  }
  /**
   * Appends the UTF-8 encoded bytes of the provided string to this byte string
   * builder.
   *
   * @param s
   *          The string whose UTF-8 encoding is to be appended to this byte
   *          string builder.
   * @return This byte string builder.
   */
  public ByteStringBuilder append(final String s)
  {
    if (s == null)
    {
      return this;
    }
    // Assume that each char is 1 byte
    final int len = s.length();
    ensureAdditionalCapacity(len);
    for (int i = 0; i < len; i++)
    {
      final char c = s.charAt(i);
      final byte b = (byte) (c & 0x0000007F);
      if (c == b)
      {
        buffer[this.length + i] = b;
      }
      else
      {
        // There is a multi-byte char. Defer to JDK
        try
        {
          return append(s.getBytes("UTF-8"));
        }
        catch (final Exception e)
        {
          if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
          {
            StaticUtils.DEBUG_LOG.warning("Unable to encode String "
                + "to UTF-8 bytes: " + e.toString());
          }
          return append(s.getBytes());
        }
      }
    }
    // The 1 byte char assumption was correct
    this.length += len;
    return this;
  }
  /**
   * Appends the ASN.1 BER length encoding representation of the provided
   * integer to this byte string builder.
   *
   * @param length
   *          The value to encode using the BER length encoding rules.
   * @return This byte string builder.
   */
  public ByteStringBuilder appendBERLength(final int length)
  {
    if ((length & 0x0000007F) == length)
    {
      ensureAdditionalCapacity(1);
      buffer[this.length++] = (byte) (length & 0xFF);
    }
    else if ((length & 0x000000FF) == length)
    {
      ensureAdditionalCapacity(2);
      buffer[this.length++] = (byte) 0x81;
      buffer[this.length++] = (byte) (length & 0xFF);
    }
    else if ((length & 0x0000FFFF) == length)
    {
      ensureAdditionalCapacity(3);
      buffer[this.length++] = (byte) 0x82;
      buffer[this.length++] = (byte) (length >> 8 & 0xFF);
      buffer[this.length++] = (byte) (length & 0xFF);
    }
    else if ((length & 0x00FFFFFF) == length)
    {
      ensureAdditionalCapacity(4);
      buffer[this.length++] = (byte) 0x83;
      buffer[this.length++] = (byte) (length >> 16 & 0xFF);
      buffer[this.length++] = (byte) (length >> 8 & 0xFF);
      buffer[this.length++] = (byte) (length & 0xFF);
    }
    else
    {
      ensureAdditionalCapacity(5);
      buffer[this.length++] = (byte) 0x84;
      buffer[this.length++] = (byte) (length >> 24 & 0xFF);
      buffer[this.length++] = (byte) (length >> 16 & 0xFF);
      buffer[this.length++] = (byte) (length >> 8 & 0xFF);
      buffer[this.length++] = (byte) (length & 0xFF);
    }
    return this;
  }
  /**
   * Returns a {@link ByteSequenceReader} which can be used to incrementally
   * read and decode data from this byte string builder.
   * <p>
   * <b>NOTE:</b> all concurrent updates to this byte string builder are
   * supported with the exception of {@link #clear()}. Any invocations of
   * {@link #clear()} must be accompanied by a subsequent call to {@code
   * ByteSequenceReader.rewind()}.
   *
   * @return The {@link ByteSequenceReader} which can be used to incrementally
   *         read and decode data from this byte string builder.
   * @see #clear()
   */
  public ByteSequenceReader asReader()
  {
    return new ByteSequenceReader(this);
  }
  /**
   * {@inheritDoc}
   */
  public byte byteAt(final int index) throws IndexOutOfBoundsException
  {
    if (index >= length || index < 0)
    {
      throw new IndexOutOfBoundsException();
    }
    return buffer[index];
  }
  /**
   * Sets the length of this byte string builder to zero.
   * <p>
   * <b>NOTE:</b> if this method is called, then {@code
   * ByteSequenceReader.rewind()} must also be called on any associated byte
   * sequence readers in order for them to remain valid.
   *
   * @return This byte string builder.
   * @see #asReader()
   */
  public ByteStringBuilder clear()
  {
    length = 0;
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public int compareTo(final byte[] b, final int offset, final int length)
      throws IndexOutOfBoundsException
  {
    ByteString.checkArrayBounds(b, offset, length);
    return ByteString.compareTo(this.buffer, 0, this.length, b, offset, length);
  }
  /**
   * {@inheritDoc}
   */
  public int compareTo(final ByteSequence o)
  {
    if (this == o)
    {
      return 0;
    }
    return -o.compareTo(buffer, 0, length);
  }
  /**
   * {@inheritDoc}
   */
  public byte[] copyTo(final byte[] b)
  {
    copyTo(b, 0);
    return b;
  }
  /**
   * {@inheritDoc}
   */
  public byte[] copyTo(final byte[] b, final int offset)
      throws IndexOutOfBoundsException
  {
    if (offset < 0)
    {
      throw new IndexOutOfBoundsException();
    }
    System.arraycopy(buffer, 0, b, offset, Math.min(length, b.length - offset));
    return b;
  }
  /**
   * {@inheritDoc}
   */
  public ByteStringBuilder copyTo(final ByteStringBuilder builder)
  {
    builder.append(buffer, 0, length);
    return builder;
  }
  /**
   * {@inheritDoc}
   */
  public OutputStream copyTo(final OutputStream stream) throws IOException
  {
    stream.write(buffer, 0, length);
    return stream;
  }
  /**
   * Ensures that the specified number of additional bytes will fit in this byte
   * string builder and resizes it if necessary.
   *
   * @param size
   *          The number of additional bytes.
   * @return This byte string builder.
   */
  public ByteStringBuilder ensureAdditionalCapacity(final int size)
  {
    final int newCount = this.length + size;
    if (newCount > buffer.length)
    {
      final byte[] newbuffer = new byte[Math.max(buffer.length << 1, newCount)];
      System.arraycopy(buffer, 0, newbuffer, 0, buffer.length);
      buffer = newbuffer;
    }
    return this;
  }
  /**
   * {@inheritDoc}
   */
  public boolean equals(final byte[] b, final int offset, final int length)
      throws IndexOutOfBoundsException
  {
    ByteString.checkArrayBounds(b, offset, length);
    return ByteString.equals(this.buffer, 0, this.length, b, offset, length);
  }
  /**
   * Indicates whether the provided object is equal to this byte string builder.
   * In order for it to be considered equal, the provided object must be a byte
   * sequence containing the same bytes in the same order.
   *
   * @param o
   *          The object for which to make the determination.
   * @return {@code true} if the provided object is a byte sequence whose
   *         content is equal to that of this byte string builder, or {@code
   *         false} if not.
   */
  @Override
  public boolean equals(final Object o)
  {
    if (this == o)
    {
      return true;
    }
    else if (o instanceof ByteSequence)
    {
      final ByteSequence other = (ByteSequence) o;
      return other.equals(buffer, 0, length);
    }
    else
    {
      return false;
    }
  }
  /**
   * Returns the byte array that backs this byte string builder. Modifications
   * to this byte string builder's content may cause the returned array's
   * content to be modified, and vice versa.
   * <p>
   * Note that the length of the returned array is only guaranteed to be the
   * same as the length of this byte string builder immediately after a call to
   * {@link #trimToSize()}.
   * <p>
   * In addition, subsequent modifications to this byte string builder may cause
   * the backing byte array to be reallocated thus decoupling the returned byte
   * array from this byte string builder.
   *
   * @return The byte array that backs this byte string builder.
   */
  public byte[] getBackingArray()
  {
    return buffer;
  }
  /**
   * Returns a hash code for this byte string builder. It will be the sum of all
   * of the bytes contained in the byte string builder.
   * <p>
   * <b>NOTE:</b> subsequent changes to this byte string builder will invalidate
   * the returned hash code.
   *
   * @return A hash code for this byte string builder.
   */
  @Override
  public int hashCode()
  {
    return ByteString.hashCode(buffer, 0, length);
  }
  /**
   * {@inheritDoc}
   */
  public int length()
  {
    return length;
  }
  /**
   * Sets the length of this byte string builder.
   * <p>
   * If the <code>newLength</code> argument is less than the current length, the
   * length is changed to the specified length.
   * <p>
   * If the <code>newLength</code> argument is greater than or equal to the
   * current length, then the capacity is increased and sufficient null bytes
   * are appended so that length becomes the <code>newLength</code> argument.
   * <p>
   * The <code>newLength</code> argument must be greater than or equal to
   * <code>0</code>.
   *
   * @param newLength
   *          The new length.
   * @return This byte string builder.
   * @throws IndexOutOfBoundsException
   *           If the <code>newLength</code> argument is negative.
   */
  public ByteStringBuilder setLength(final int newLength)
      throws IndexOutOfBoundsException
  {
    if (newLength < 0)
    {
      throw new IndexOutOfBoundsException("Negative newLength: " + newLength);
    }
    if (newLength > length)
    {
      ensureAdditionalCapacity(newLength - length);
      // Pad with zeros.
      for (int i = length; i < newLength; i++)
      {
        buffer[i] = 0;
      }
    }
    length = newLength;
    return this;
  }
  /**
   * Returns a new byte sequence that is a subsequence of this byte sequence.
   * <p>
   * The subsequence starts with the byte value at the specified {@code start}
   * index and ends with the byte value at index {@code end - 1}. The length (in
   * bytes) of the returned sequence is {@code end - start}, so if {@code start
   * == end} then an empty sequence is returned.
   * <p>
   * <b>NOTE:</b> the returned sub-sequence will be robust against all updates
   * to the byte string builder except for invocations of the method
   * {@link #clear()}. If a permanent immutable byte sequence is required then
   * callers should invoke {@code toByteString()} on the returned byte sequence.
   *
   * @param start
   *          The start index, inclusive.
   * @param end
   *          The end index, exclusive.
   * @return The newly created byte subsequence.
   * @throws IndexOutOfBoundsException
   *           If {@code start} or {@code end} are negative, if {@code end} is
   *           greater than {@code length()}, or if {@code start} is greater
   *           than {@code end}.
   */
  public ByteSequence subSequence(final int start, final int end)
      throws IndexOutOfBoundsException
  {
    if (start < 0 || start > end || end > length)
    {
      throw new IndexOutOfBoundsException();
    }
    return new SubSequence(start, end - start);
  }
  /**
   * {@inheritDoc}
   */
  public byte[] toByteArray()
  {
    return copyTo(new byte[length]);
  }
  /**
   * Returns the {@link ByteString} representation of this byte string builder.
   * Subsequent changes to this byte string builder will not modify the returned
   * {@link ByteString}.
   *
   * @return The {@link ByteString} representation of this byte sequence.
   */
  public ByteString toByteString()
  {
    final byte[] b = new byte[length];
    System.arraycopy(buffer, 0, b, 0, length);
    return ByteString.wrap(b);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    return ByteString.toString(buffer, 0, length);
  }
  /**
   * Attempts to reduce storage used for this byte string builder. If the buffer
   * is larger than necessary to hold its current sequence of bytes, then it may
   * be resized to become more space efficient.
   *
   * @return This byte string builder.
   */
  public ByteStringBuilder trimToSize()
  {
    if (buffer.length > length)
    {
      final byte[] newBuffer = new byte[length];
      System.arraycopy(buffer, 0, newBuffer, 0, length);
      buffer = newBuffer;
    }
    return this;
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/CancelledResultException.java
New file
@@ -0,0 +1,54 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import org.forgerock.opendj.ldap.responses.Result;
/**
 * Thrown when the result code returned in a Result indicates that the Request
 * was cancelled. More specifically, this exception is used for the following
 * error result codes:
 * <ul>
 * <li>{@link ResultCode#CANCELLED CANCELLED} - the requested operation was
 * cancelled.
 * <li>{@link ResultCode#CLIENT_SIDE_USER_CANCELLED CLIENT_SIDE_USER_CANCELLED}
 * - the requested operation was cancelled by the user.
 * </ul>
 */
@SuppressWarnings("serial")
public class CancelledResultException extends ErrorResultException
{
  CancelledResultException(final Result result)
  {
    super(result);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ConditionResult.java
New file
@@ -0,0 +1,298 @@
/*
 * 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.forgerock.opendj.ldap;
/**
 * The result of a tri-state logical expression. Condition results are used to
 * represent the result of a conditional evaluation that can yield three
 * possible values: {@code FALSE} (i.e. "no"), {@code TRUE} (i.e. "yes"), or
 * {@code UNDEFINED} (i.e. "maybe"). A result of {@code UNDEFINED} indicates
 * that further investigation may be required.
 */
public enum ConditionResult
{
  /**
   * Indicates that the condition evaluated to {@code false}.
   */
  FALSE("false"),
  /**
   * Indicates that the condition could not be evaluated and its result is
   * undefined.
   */
  UNDEFINED("undefined"),
  /**
   * Indicates that the condition evaluated to {@code true}.
   */
  TRUE("true");
  // Boolean -> ConditionResult map.
  private static final boolean[] BOOLEAN_MAP = { false, false, true };
  // AND truth table.
  private static final ConditionResult[][] LOGICAL_AND = {
      { FALSE, FALSE, FALSE }, { FALSE, UNDEFINED, UNDEFINED },
      { FALSE, UNDEFINED, TRUE }, };
  // NOT truth table.
  private static final ConditionResult[] LOGICAL_NOT = { TRUE, UNDEFINED, FALSE };
  // OR truth table.
  private static final ConditionResult[][] LOGICAL_OR = {
      { FALSE, UNDEFINED, TRUE }, { UNDEFINED, UNDEFINED, TRUE },
      { TRUE, TRUE, TRUE }, };
  /**
   * Returns the logical AND of zero condition results, which is always {@code
   * TRUE}.
   *
   * @return The logical OR of zero condition results, which is always {@code
   *         TRUE}.
   */
  public static ConditionResult and()
  {
    return TRUE;
  }
  /**
   * Returns the logical AND of the provided condition result, which is always
   * {@code r}.
   *
   * @param r
   *          The condition result.
   * @return The logical AND of the provided condition result, which is always
   *         {@code r}.
   */
  public static ConditionResult and(final ConditionResult r)
  {
    return r;
  }
  /**
   * Returns the logical AND of the provided condition results, which is {@code
   * TRUE} if all of the provided condition results are {@code TRUE}, {@code
   * FALSE} if at least one of them is {@code FALSE}, and {@code UNDEFINED}
   * otherwise. Note that {@code TRUE} is returned if the provided list of
   * results is empty.
   *
   * @param results
   *          The condition results to be compared.
   * @return The logical AND of the provided condition results.
   */
  public static ConditionResult and(final ConditionResult... results)
  {
    ConditionResult finalResult = TRUE;
    for (final ConditionResult result : results)
    {
      finalResult = and(finalResult, result);
      if (finalResult == FALSE)
      {
        break;
      }
    }
    return finalResult;
  }
  /**
   * Returns the logical AND of the provided condition results, which is {@code
   * TRUE} if both of the provided condition results are {@code TRUE}, {@code
   * FALSE} if at least one of them is {@code FALSE} , and {@code UNDEFINED}
   * otherwise.
   *
   * @param r1
   *          The first condition result to be compared.
   * @param r2
   *          The second condition result to be compared.
   * @return The logical AND of the provided condition results.
   */
  public static ConditionResult and(final ConditionResult r1,
      final ConditionResult r2)
  {
    return LOGICAL_AND[r1.ordinal()][r2.ordinal()];
  }
  /**
   * Returns the logical NOT of the provided condition result, which is {@code
   * TRUE} if the provided condition result is {@code FALSE}, {@code TRUE} if it
   * is {@code FALSE}, and {@code UNDEFINED} otherwise.
   *
   * @param r
   *          The condition result to invert.
   * @return The logical NOT of the provided condition result.
   */
  public static ConditionResult not(final ConditionResult r)
  {
    return LOGICAL_NOT[r.ordinal()];
  }
  /**
   * Returns the logical OR of zero condition results, which is always {@code
   * FALSE}.
   *
   * @return The logical OR of zero condition results, which is always {@code
   *         FALSE}.
   */
  public static ConditionResult or()
  {
    return FALSE;
  }
  /**
   * Returns the logical OR of the provided condition result, which is always
   * {@code r}.
   *
   * @param r
   *          The condition result.
   * @return The logical OR of the provided condition result, which is always
   *         {@code r}.
   */
  public static ConditionResult or(final ConditionResult r)
  {
    return r;
  }
  /**
   * Returns the logical OR of the provided condition results, which is {@code
   * FALSE} if all of the provided condition results are {@code FALSE}, {@code
   * TRUE} if at least one of them is {@code TRUE}, and {@code UNDEFINED}
   * otherwise. Note that {@code FALSE} is returned if the provided list of
   * results is empty.
   *
   * @param results
   *          The condition results to be compared.
   * @return The logical OR of the provided condition results.
   */
  public static ConditionResult or(final ConditionResult... results)
  {
    ConditionResult finalResult = FALSE;
    for (final ConditionResult result : results)
    {
      finalResult = and(finalResult, result);
      if (finalResult == TRUE)
      {
        break;
      }
    }
    return finalResult;
  }
  /**
   * Returns the logical OR of the provided condition results, which is {@code
   * FALSE} if both of the provided condition results are {@code FALSE}, {@code
   * TRUE} if at least one of them is {@code TRUE} , and {@code UNDEFINED}
   * otherwise.
   *
   * @param r1
   *          The first condition result to be compared.
   * @param r2
   *          The second condition result to be compared.
   * @return The logical OR of the provided condition results.
   */
  public static ConditionResult or(final ConditionResult r1,
      final ConditionResult r2)
  {
    return LOGICAL_OR[r1.ordinal()][r2.ordinal()];
  }
  /**
   * Returns the condition result which is equivalent to the provided boolean
   * value.
   *
   * @param b
   *          The boolean value.
   * @return {@code TRUE} if {@code b} was {@code true}, otherwise {@code FALSE}
   *         .
   */
  public static ConditionResult valueOf(final boolean b)
  {
    return b ? TRUE : FALSE;
  }
  // The human-readable name for this result.
  private final String resultName;
  // Prevent instantiation.
  private ConditionResult(final String resultName)
  {
    this.resultName = resultName;
  }
  /**
   * Converts this condition result to a boolean value. {@code FALSE} and
   * {@code UNDEFINED} are both converted to {@code false}, and {@code TRUE} is
   * converted to {@code true}.
   *
   * @return The boolean equivalent of this condition result.
   */
  public boolean toBoolean()
  {
    return BOOLEAN_MAP[ordinal()];
  }
  /**
   * Returns the string representation of this condition result.
   *
   * @return The string representation of his condition result.
   */
  @Override
  public String toString()
  {
    return resultName;
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/Connection.java
New file
@@ -0,0 +1,1261 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import java.io.Closeable;
import java.util.Collection;
import java.util.concurrent.BlockingQueue;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldif.ConnectionEntryReader;
/**
 * A synchronous connection with a Directory Server over which read and update
 * operations may be performed. See RFC 4511 for the LDAPv3 protocol
 * specification and more information about the types of operations defined in
 * LDAP.
 * <p>
 * <h3>Operation processing</h3>
 * <p>
 * All operations are performed synchronously and return an appropriate
 * {@link Result} representing the final status of the operation. Operation
 * failures, for whatever reason, are signalled using an
 * {@link ErrorResultException}.
 * <p>
 * <h3>Closing connections</h3>
 * <p>
 * Applications must ensure that a connection is closed by calling
 * {@link #close()} even if a fatal error occurs on the connection. Once a
 * connection has been closed by the client application, any attempts to
 * continue to use the connection will result in an
 * {@link IllegalStateException} being thrown. Note that, if a fatal error is
 * encountered on the connection, then the application can continue to use the
 * connection. In this case all requests subsequent to the failure will fail
 * with an appropriate {@link ErrorResultException} when their result is
 * retrieved.
 * <p>
 * <h3>Event notification</h3>
 * <p>
 * Applications can choose to be notified when a connection is closed by the
 * application, receives an unsolicited notification, or experiences a fatal
 * error by registering a {@link ConnectionEventListener} with the connection
 * using the {@link #addConnectionEventListener} method.
 *
 * @see <a href="http://tools.ietf.org/html/rfc4511">RFC 4511 - Lightweight
 *      Directory Access Protocol (LDAP): The Protocol </a>
 */
public interface Connection extends Closeable
{
  /**
   * Adds an entry to the Directory Server using the provided add request.
   *
   * @param request
   *          The add request.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support add operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  Result add(AddRequest request) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Adds the provided entry to the Directory Server.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * AddRequest request = new AddRequest(entry);
   * connection.add(request);
   * </pre>
   *
   * @param entry
   *          The entry to be added.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support add operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code entry} was {@code null} .
   */
  Result add(Entry entry) throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Adds an entry to the Directory Server using the provided lines of LDIF.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * AddRequest request = new AddRequest(ldifLines);
   * connection.add(request);
   * </pre>
   *
   * @param ldifLines
   *          Lines of LDIF containing the an LDIF add change record or an LDIF
   *          entry record.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support add operations.
   * @throws LocalizedIllegalArgumentException
   *           If {@code ldifLines} was empty, or contained invalid LDIF, or
   *           could not be decoded using the default schema.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code ldifLines} was {@code null} .
   */
  Result add(String... ldifLines) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      LocalizedIllegalArgumentException, IllegalStateException,
      NullPointerException;
  /**
   * Registers the provided connection event listener so that it will be
   * notified when this connection is closed by the application, receives an
   * unsolicited notification, or experiences a fatal error.
   *
   * @param listener
   *          The listener which wants to be notified when events occur on this
   *          connection.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If the {@code listener} was {@code null}.
   */
  void addConnectionEventListener(ConnectionEventListener listener)
      throws IllegalStateException, NullPointerException;
  /**
   * Authenticates to the Directory Server using the provided bind request.
   *
   * @param request
   *          The bind request.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support bind operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  BindResult bind(BindRequest request) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Authenticates to the Directory Server using simple authentication and the
   * provided user name and password.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * BindRequest request = new SimpleBindRequest(name, password);
   * connection.bind(request);
   * </pre>
   *
   * @param name
   *          The distinguished name of the Directory object that the client
   *          wishes to bind as, which may be empty.
   * @param password
   *          The password of the Directory object that the client wishes to
   *          bind as, which may be empty.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws LocalizedIllegalArgumentException
   *           If {@code name} could not be decoded using the default schema.
   * @throws UnsupportedOperationException
   *           If this connection does not support bind operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code name} or {@code password} was {@code null}.
   */
  BindResult bind(String name, char[] password) throws ErrorResultException,
      InterruptedException, LocalizedIllegalArgumentException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Releases any resources associated with this connection. For physical
   * connections to a Directory Server this will mean that an unbind request is
   * sent and the underlying socket is closed.
   * <p>
   * Other connection implementations may behave differently, and may choose not
   * to send an unbind request if its use is inappropriate (for example a pooled
   * connection will be released and returned to its connection pool without
   * ever issuing an unbind request).
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * UnbindRequest request = new UnbindRequest();
   * connection.close(request);
   * </pre>
   *
   * Calling {@code close} on a connection that is already closed has no effect.
   */
  void close();
  /**
   * Releases any resources associated with this connection. For physical
   * connections to a Directory Server this will mean that the provided unbind
   * request is sent and the underlying socket is closed.
   * <p>
   * Other connection implementations may behave differently, and may choose to
   * ignore the provided unbind request if its use is inappropriate (for example
   * a pooled connection will be released and returned to its connection pool
   * without ever issuing an unbind request).
   * <p>
   * Calling {@code close} on a connection that is already closed has no effect.
   *
   * @param request
   *          The unbind request to use in the case where a physical connection
   *          is closed.
   * @param reason
   *          A reason describing why the connection was closed.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  void close(UnbindRequest request, String reason) throws NullPointerException;
  /**
   * Compares an entry in the Directory Server using the provided compare
   * request.
   *
   * @param request
   *          The compare request.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support compare operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  CompareResult compare(CompareRequest request) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Compares the named entry in the Directory Server against the provided
   * attribute value assertion.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * CompareRequest request = new CompareRequest(name, attributeDescription,
   *     assertionValue);
   * connection.compare(request);
   * </pre>
   *
   * @param name
   *          The distinguished name of the entry to be compared.
   * @param attributeDescription
   *          The name of the attribute to be compared.
   * @param assertionValue
   *          The assertion value to be compared.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws LocalizedIllegalArgumentException
   *           If {@code name} or {@code AttributeDescription} could not be
   *           decoded using the default schema.
   * @throws UnsupportedOperationException
   *           If this connection does not support compare operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code name}, {@code attributeDescription}, or {@code
   *           assertionValue} was {@code null}.
   */
  CompareResult compare(String name, String attributeDescription,
      String assertionValue) throws ErrorResultException, InterruptedException,
      LocalizedIllegalArgumentException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Deletes an entry from the Directory Server using the provided delete
   * request.
   *
   * @param request
   *          The delete request.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support delete operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  Result delete(DeleteRequest request) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Deletes the named entry from the Directory Server.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * DeleteRequest request = new DeleteRequest(name);
   * connection.delete(request);
   * </pre>
   *
   * @param name
   *          The distinguished name of the entry to be deleted.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws LocalizedIllegalArgumentException
   *           If {@code name} could not be decoded using the default schema.
   * @throws UnsupportedOperationException
   *           If this connection does not support delete operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code name} was {@code null}.
   */
  Result delete(String name) throws ErrorResultException, InterruptedException,
      LocalizedIllegalArgumentException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Requests that the Directory Server performs the provided extended request.
   *
   * @param <R>
   *          The type of result returned by the extended request.
   * @param request
   *          The extended request.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support extended operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  <R extends ExtendedResult> R extendedRequest(ExtendedRequest<R> request)
      throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Requests that the Directory Server performs the provided extended request,
   * optionally listening for any intermediate responses.
   *
   * @param <R>
   *          The type of result returned by the extended request.
   * @param request
   *          The extended request.
   * @param handler
   *          An intermediate response handler which can be used to process any
   *          intermediate responses as they are received, may be {@code null}.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support extended operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  <R extends ExtendedResult> R extendedRequest(ExtendedRequest<R> request,
      IntermediateResponseHandler handler) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Requests that the Directory Server performs the provided extended request.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * GenericExtendedRequest request = new GenericExtendedRequest(requestName,
   *     requestValue);
   * connection.extendedRequest(request);
   * </pre>
   *
   * @param requestName
   *          The dotted-decimal representation of the unique OID corresponding
   *          to the extended request.
   * @param requestValue
   *          The content of the extended request in a form defined by the
   *          extended operation, or {@code null} if there is no content.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support extended operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code requestName} was {@code null}.
   */
  GenericExtendedResult extendedRequest(String requestName,
      ByteString requestValue) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Returns an asynchronous connection sharing the same underlying network
   * connection as this synchronous connection.
   *
   * @return An asynchronous connection sharing the same underlying network
   *         connection as this synchronous connection.
   */
  AsynchronousConnection getAsynchronousConnection();
  /**
   * Indicates whether or not this connection has been explicitly closed by
   * calling {@code close}. This method will not return {@code true} if a fatal
   * error has occurred on the connection unless {@code close} has been called.
   *
   * @return {@code true} if this connection has been explicitly closed by
   *         calling {@code close}, or {@code false} otherwise.
   */
  boolean isClosed();
  /**
   * Returns {@code true} if this connection has not been closed and no fatal
   * errors have been detected. This method is guaranteed to return {@code
   * false} only when it is called after the method {@code close} has been
   * called.
   *
   * @return {@code true} if this connection is valid, {@code false} otherwise.
   */
  boolean isValid();
  /**
   * Modifies an entry in the Directory Server using the provided modify
   * request.
   *
   * @param request
   *          The modify request.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support modify operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  Result modify(ModifyRequest request) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Modifies an entry in the Directory Server using the provided lines of LDIF.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * ModifyRequest request = new ModifyRequest(name, ldifChanges);
   * connection.modify(request);
   * </pre>
   *
   * @param ldifLines
   *          Lines of LDIF containing the a single LDIF modify change record.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support modify operations.
   * @throws LocalizedIllegalArgumentException
   *           If {@code ldifLines} was empty, or contained invalid LDIF, or
   *           could not be decoded using the default schema.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code ldifLines} was {@code null} .
   */
  Result modify(String... ldifLines) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      LocalizedIllegalArgumentException, IllegalStateException,
      NullPointerException;
  /**
   * Renames an entry in the Directory Server using the provided modify DN
   * request.
   *
   * @param request
   *          The modify DN request.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support modify DN operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  Result modifyDN(ModifyDNRequest request) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Renames the named entry in the Directory Server using the provided new RDN.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * ModifyDNRequest request = new ModifyDNRequest(name, newRDN);
   * connection.modifyDN(request);
   * </pre>
   *
   * @param name
   *          The distinguished name of the entry to be renamed.
   * @param newRDN
   *          The new RDN of the entry.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws LocalizedIllegalArgumentException
   *           If {@code name} or {@code newRDN} could not be decoded using the
   *           default schema.
   * @throws UnsupportedOperationException
   *           If this connection does not support modify DN operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code name} or {@code newRDN} was {@code null}.
   */
  Result modifyDN(String name, String newRDN) throws ErrorResultException,
      LocalizedIllegalArgumentException, InterruptedException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Reads the named entry from the Directory Server.
   * <p>
   * If the requested entry is not returned by the Directory Server then the
   * request will fail with an {@link EntryNotFoundException}. More
   * specifically, this method will never return {@code null}.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * SearchRequest request = new SearchRequest(name, SearchScope.BASE_OBJECT,
   *     &quot;(objectClass=*)&quot;, attributeDescriptions);
   * connection.searchSingleEntry(request);
   * </pre>
   *
   * @param name
   *          The distinguished name of the entry to be read.
   * @param attributeDescriptions
   *          The names of the attributes to be included with the entry, which
   *          may be {@code null} or empty indicating that all user attributes
   *          should be returned.
   * @return The single search result entry returned from the search.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If the {@code name} was {@code null}.
   */
  SearchResultEntry readEntry(DN name, String... attributeDescriptions)
      throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Reads the named entry from the Directory Server.
   * <p>
   * If the requested entry is not returned by the Directory Server then the
   * request will fail with an {@link EntryNotFoundException}. More
   * specifically, this method will never return {@code null}.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * SearchRequest request = new SearchRequest(name, SearchScope.BASE_OBJECT,
   *     &quot;(objectClass=*)&quot;, attributeDescriptions);
   * connection.searchSingleEntry(request);
   * </pre>
   *
   * @param name
   *          The distinguished name of the entry to be read.
   * @param attributeDescriptions
   *          The names of the attributes to be included with the entry.
   * @return The single search result entry returned from the search.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws LocalizedIllegalArgumentException
   *           If {@code baseObject} could not be decoded using the default
   *           schema.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If the {@code name} was {@code null}.
   */
  SearchResultEntry readEntry(String name, String... attributeDescriptions)
      throws ErrorResultException, InterruptedException,
      LocalizedIllegalArgumentException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Reads the Root DSE from the Directory Server.
   * <p>
   * If the Root DSE is not returned by the Directory Server then the request
   * will fail with an {@link EntryNotFoundException}. More specifically, this
   * method will never return {@code null}.
   *
   * @return The Directory Server's Root DSE.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   */
  RootDSE readRootDSE() throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException;
  /**
   * Reads the schema from the Directory Server contained in the named subschema
   * sub-entry.
   * <p>
   * If the requested schema is not returned by the Directory Server then the
   * request will fail with an {@link EntryNotFoundException}. More
   * specifically, this method will never return {@code null}.
   * <p>
   * Implementations may choose to perform optimizations such as caching.
   *
   * @param name
   *          The distinguished name of the subschema sub-entry.
   * @return The schema from the Directory Server.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   */
  Schema readSchema(DN name) throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException;
  /**
   * Reads the schema from the Directory Server contained in the named subschema
   * sub-entry.
   * <p>
   * If the requested schema is not returned by the Directory Server then the
   * request will fail with an {@link EntryNotFoundException}. More
   * specifically, this method will never return {@code null}.
   * <p>
   * Implementations may choose to perform optimizations such as caching.
   *
   * @param name
   *          The distinguished name of the subschema sub-entry.
   * @return The schema from the Directory Server.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws LocalizedIllegalArgumentException
   *           If {@code name} could not be decoded using the default schema.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   */
  Schema readSchema(String name) throws ErrorResultException,
      InterruptedException, LocalizedIllegalArgumentException,
      UnsupportedOperationException, IllegalStateException;
  /**
   * Reads the schema from the Directory Server which applies to the named
   * entry.
   * <p>
   * If the requested entry or its associated schema are not returned by the
   * Directory Server then the request will fail with an
   * {@link EntryNotFoundException}. More specifically, this method will never
   * return {@code null}.
   * <p>
   * A typical implementation will first read the {@code subschemaSubentry}
   * attribute of the entry in order to locate the schema. However,
   * implementations may choose to perform other optimizations, such as caching.
   *
   * @param name
   *          The distinguished name of the entry whose schema is to be located.
   * @return The schema from the Directory Server which applies to the named
   *         entry.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   */
  Schema readSchemaForEntry(DN name) throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException;
  /**
   * Reads the schema from the Directory Server which applies to the named
   * entry.
   * <p>
   * If the requested entry or its associated schema are not returned by the
   * Directory Server then the request will fail with an
   * {@link EntryNotFoundException}. More specifically, this method will never
   * return {@code null}.
   * <p>
   * A typical implementation will first read the {@code subschemaSubentry}
   * attribute of the entry in order to locate the schema. However,
   * implementations may choose to perform other optimizations, such as caching.
   *
   * @param name
   *          The distinguished name of the entry whose schema is to be located.
   * @return The schema from the Directory Server which applies to the named
   *         entry.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws LocalizedIllegalArgumentException
   *           If {@code name} could not be decoded using the default schema.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   */
  Schema readSchemaForEntry(String name) throws ErrorResultException,
      InterruptedException, LocalizedIllegalArgumentException,
      UnsupportedOperationException, IllegalStateException;
  /**
   * Reads the schema from the Directory Server which applies to the Root DSE.
   * <p>
   * If the requested schema is not returned by the Directory Server then the
   * request will fail with an {@link EntryNotFoundException}. More
   * specifically, this method will never return {@code null}.
   * <p>
   * A typical implementation will first read the {@code subschemaSubentry}
   * attribute of the Root DSE in order to locate the schema. However,
   * implementations may choose to perform other optimizations, such as caching.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * connection.readSchemaForEntry(DN.rootDN());
   * </pre>
   *
   * @return The schema from the Directory Server which applies to the named
   *         entry.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   */
  Schema readSchemaForRootDSE() throws ErrorResultException,
      InterruptedException, UnsupportedOperationException,
      IllegalStateException;
  /**
   * Removes the provided connection event listener from this connection so that
   * it will no longer be notified when this connection is closed by the
   * application, receives an unsolicited notification, or experiences a fatal
   * error.
   *
   * @param listener
   *          The listener which no longer wants to be notified when events
   *          occur on this connection.
   * @throws NullPointerException
   *           If the {@code listener} was {@code null}.
   */
  void removeConnectionEventListener(ConnectionEventListener listener)
      throws NullPointerException;
  /**
   * Searches the Directory Server using the provided search request. Any
   * matching entries returned by the search will be added to {@code entries},
   * even if the final search result indicates that the search failed. Search
   * result references will be discarded.
   * <p>
   * <b>Warning:</b> Usage of this method is discouraged if the search request
   * is expected to yield a large number of search results since the entire set
   * of results will be stored in memory, potentially causing an {@code
   * OutOfMemoryError}.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * connection.search(request, entries, null);
   * </pre>
   *
   * @param request
   *          The search request.
   * @param entries
   *          The collection to which matching entries should be added.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} or {@code entries} was {@code null}.
   */
  Result search(SearchRequest request,
      Collection<? super SearchResultEntry> entries)
      throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Searches the Directory Server using the provided search request. Any
   * matching entries returned by the search will be added to {@code entries},
   * even if the final search result indicates that the search failed.
   * Similarly, search result references returned by the search will be added to
   * {@code references}.
   * <p>
   * <b>Warning:</b> Usage of this method is discouraged if the search request
   * is expected to yield a large number of search results since the entire set
   * of results will be stored in memory, potentially causing an {@code
   * OutOfMemoryError}.
   *
   * @param request
   *          The search request.
   * @param entries
   *          The collection to which matching entries should be added.
   * @param references
   *          The collection to which search result references should be added,
   *          or {@code null} if references are to be discarded.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} or {@code entries} was {@code null}.
   */
  Result search(SearchRequest request,
      Collection<? super SearchResultEntry> entries,
      Collection<? super SearchResultReference> references)
      throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Searches the Directory Server using the provided search request. Any
   * matching entries returned by the search as well as any search result
   * references will be passed to the provided search result handler.
   *
   * @param request
   *          The search request.
   * @param handler
   *          A search result handler which can be used to process the search
   *          result entries and references as they are received, may be {@code
   *          null}.
   * @return The result of the operation.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} was {@code null}.
   */
  Result search(SearchRequest request, SearchResultHandler handler)
      throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Searches the Directory Server using the provided search parameters. Any
   * matching entries returned by the search will be exposed through the
   * {@code EntryReader} interface.
   * <p>
   * <b>Warning:</b> When using a queue with an optional capacity bound,
   * the connection will stop reading responses and wait if necessary for
   * space to become available.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * SearchRequest request = new SearchRequest(baseDN, scope, filter,
   *     attributeDescriptions);
   * connection.search(request, new LinkedBlockingQueue&lt;Response&gt;());
   * </pre>
   *
   * @param baseObject
   *          The distinguished name of the base entry relative to which the
   *          search is to be performed.
   * @param scope
   *          The scope of the search.
   * @param filter
   *          The filter that defines the conditions that must be fulfilled in
   *          order for an entry to be returned.
   * @param attributeDescriptions
   *          The names of the attributes to be included with each entry.
   * @return An entry reader exposing the returned entries.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If the {@code baseObject}, {@code scope}, or {@code filter} were
   *           {@code null}.
   */
  ConnectionEntryReader search(String baseObject, SearchScope scope,
      String filter, String... attributeDescriptions)
      throws UnsupportedOperationException,
      IllegalStateException, NullPointerException;
  /**
   * Searches the Directory Server using the provided search parameters. Any
   * matching entries returned by the search will be exposed through the
   * {@code EntryReader} interface.
   * <p>
   * <b>Warning:</b> When using a queue with an optional capacity bound,
   * the connection will stop reading responses and wait if necessary for
   * space to become available.
   *
   * @param request
   *          The search request.
   * @param entries
   *          The queue to which matching entries should be added.
   * @return The result of the operation.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If {@code request} or {@code entries} was {@code null}.
   */
  ConnectionEntryReader search(SearchRequest request,
                               BlockingQueue<Response> entries)
      throws UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Searches the Directory Server for a single entry using the provided search
   * request.
   * <p>
   * If the requested entry is not returned by the Directory Server then the
   * request will fail with an {@link EntryNotFoundException}. More
   * specifically, this method will never return {@code null}. If multiple
   * matching entries are returned by the Directory Server then the request will
   * fail with an {@link MultipleEntriesFoundException}.
   *
   * @param request
   *          The search request.
   * @return The single search result entry returned from the search.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If the {@code request} was {@code null}.
   */
  SearchResultEntry searchSingleEntry(SearchRequest request)
      throws ErrorResultException, InterruptedException,
      UnsupportedOperationException, IllegalStateException,
      NullPointerException;
  /**
   * Searches the Directory Server for a single entry using the provided search
   * parameters.
   * <p>
   * If the requested entry is not returned by the Directory Server then the
   * request will fail with an {@link EntryNotFoundException}. More
   * specifically, this method will never return {@code null}. If multiple
   * matching entries are returned by the Directory Server then the request will
   * fail with an {@link MultipleEntriesFoundException}.
   * <p>
   * This method is equivalent to the following code:
   *
   * <pre>
   * SearchRequest request = new SearchRequest(baseObject, scope, filter,
   *     attributeDescriptions);
   * connection.searchSingleEntry(request);
   * </pre>
   *
   * @param baseObject
   *          The distinguished name of the base entry relative to which the
   *          search is to be performed.
   * @param scope
   *          The scope of the search.
   * @param filter
   *          The filter that defines the conditions that must be fulfilled in
   *          order for an entry to be returned.
   * @param attributeDescriptions
   *          The names of the attributes to be included with each entry.
   * @return The single search result entry returned from the search.
   * @throws ErrorResultException
   *           If the result code indicates that the request failed for some
   *           reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   * @throws LocalizedIllegalArgumentException
   *           If {@code baseObject} could not be decoded using the default
   *           schema or if {@code filter} is not a valid LDAP string
   *           representation of a filter.
   * @throws UnsupportedOperationException
   *           If this connection does not support search operations.
   * @throws IllegalStateException
   *           If this connection has already been closed, i.e. if {@code
   *           isClosed() == true}.
   * @throws NullPointerException
   *           If the {@code baseObject}, {@code scope}, or {@code filter} were
   *           {@code null}.
   */
  SearchResultEntry searchSingleEntry(String baseObject, SearchScope scope,
      String filter, String... attributeDescriptions)
      throws ErrorResultException, InterruptedException,
      LocalizedIllegalArgumentException, UnsupportedOperationException,
      IllegalStateException, NullPointerException;
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionEventListener.java
New file
@@ -0,0 +1,89 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import java.util.EventListener;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
/**
 * An object that registers to be notified when a connection is closed by the
 * application, receives an unsolicited notification, or experiences a fatal
 * error.
 */
public interface ConnectionEventListener extends EventListener
{
  /**
   * Notifies this connection event listener that the application has called
   * {@code close} on the connection. The connection event listener will be
   * notified immediately after the application calls the {@code close} method
   * on the associated connection.
   */
  void handleConnectionClosed();
  /**
   * Notifies this connection event listener that a fatal error has occurred and
   * the connection can no longer be used - the server has crashed, for example.
   * The connection implementation makes this notification just before it throws
   * the provided {@link ErrorResultException} to the application.
   * <p>
   * <b>Note:</b> disconnect notifications are treated as fatal connection
   * errors and are handled by this method. In this case
   * {@code isDisconnectNotification} will be {@code true} and {@code error}
   * will contain the result code and any diagnostic information contained in
   * the notification message.
   *
   * @param isDisconnectNotification
   *          {@code true} if the error was triggered by a disconnect
   *          notification sent by the server, otherwise {@code false}.
   * @param error
   *          The exception that is about to be thrown to the application.
   */
  void handleConnectionError(boolean isDisconnectNotification,
      ErrorResultException error);
  /**
   * Notifies this connection event listener that the connection has just
   * received the provided unsolicited notification from the server.
   * <p>
   * <b>Note:</b> disconnect notifications are treated as fatal connection
   * errors and are handled by the {@link #handleConnectionError} method.
   *
   * @param notification
   *          The unsolicited notification.
   */
  void handleUnsolicitedNotification(ExtendedResult notification);
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionException.java
New file
@@ -0,0 +1,47 @@
/*
 * 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.forgerock.opendj.ldap;
import org.forgerock.opendj.ldap.responses.Result;
/**
 * Thrown when the result code returned in a Result indicates that the Request
 * was unsuccessful because of a connection failure.
 */
@SuppressWarnings("serial")
public class ConnectionException extends ErrorResultException
{
  ConnectionException(final Result result)
  {
    super(result);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionFactory.java
New file
@@ -0,0 +1,86 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
/**
 * A connection factory provides an interface for obtaining a connection to a
 * Directory Server. Connection factories can be used to wrap other connection
 * factories in order to provide enhanced capabilities in a manner which is
 * transparent to the application. For example:
 * <ul>
 * <li>Connection pooling
 * <li>Load balancing
 * <li>Keep alive
 * <li>Transactional connections
 * <li>Connections to LDIF files
 * <li>Data transformations
 * <li>Logging connections
 * <li>Read-only connections
 * <li>Pre-authenticated connections
 * <li>Recording connections, with primitive roll-back functionality
 * </ul>
 * An application typically obtains a connection from a connection factory,
 * performs one or more operations, and then closes the connection. Applications
 * should aim to close connections as soon as possible in order to avoid
 * resource contention.
 */
public interface ConnectionFactory
{
  /**
   * Initiates an asynchronous connection request to the Directory Server
   * associated with this connection factory. The returned {@code FutureResult}
   * can be used to retrieve the completed asynchronous connection.
   * Alternatively, if a {@code ResultHandler} is provided, the handler will be
   * notified when the connection is available and ready for use.
   *
   * @param handler
   *          The completion handler, or {@code null} if no handler is to be
   *          used.
   * @return A future which can be used to retrieve the asynchronous connection.
   */
  FutureResult<AsynchronousConnection> getAsynchronousConnection(
      ResultHandler<? super AsynchronousConnection> handler);
  /**
   * Returns a connection to the Directory Server associated with this
   * connection factory. The connection returned by this method can be used
   * immediately.
   *
   * @return A connection to the Directory Server associated with this
   *         connection factory.
   * @throws ErrorResultException
   *           If the connection request failed for some reason.
   * @throws InterruptedException
   *           If the current thread was interrupted while waiting.
   */
  Connection getConnection() throws ErrorResultException, InterruptedException;
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionPool.java
New file
@@ -0,0 +1,881 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import org.forgerock.opendj.ldap.schema.Schema;
import com.forgerock.opendj.util.AsynchronousFutureResult;
import com.forgerock.opendj.util.CompletedFutureResult;
import com.forgerock.opendj.util.StaticUtils;
import com.forgerock.opendj.util.Validator;
/**
 * A simple connection pool implementation.
 */
final class ConnectionPool extends AbstractConnectionFactory
{
  /**
   * This result handler is invoked when an attempt to add a new connection to
   * the pool completes.
   */
  private final class ConnectionResultHandler implements
      ResultHandler<AsynchronousConnection>
  {
    /**
     * {@inheritDoc}
     */
    @Override
    public void handleErrorResult(final ErrorResultException error)
    {
      // Connection attempt failed, so decrease the pool size.
      currentPoolSize.release();
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
      {
        StaticUtils.DEBUG_LOG.fine(String.format(
            "Connection attempt failed: " + error.getMessage()
                + " currentPoolSize=%d, poolSize=%d",
            poolSize - currentPoolSize.availablePermits(), poolSize));
      }
      QueueElement holder;
      synchronized (queue)
      {
        if (queue.isEmpty() || !queue.getFirst().isWaitingFuture())
        {
          // No waiting futures.
          return;
        }
        else
        {
          holder = queue.removeFirst();
        }
      }
      // There was waiting future, so close it.
      holder.getWaitingFuture().handleErrorResult(error);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void handleResult(final AsynchronousConnection connection)
    {
      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
      {
        StaticUtils.DEBUG_LOG.fine(String.format(
            "Connection attempt succeeded: "
                + " currentPoolSize=%d, poolSize=%d",
                poolSize - currentPoolSize.availablePermits(), poolSize));
      }
      publishConnection(connection);
    }
  }
  /**
   * A pooled connection is passed to the client. It wraps an underlying
   * "pooled" connection obtained from the underlying factory and lasts until
   * the client application closes this connection. More specifically, pooled
   * connections are not actually stored in the internal queue.
   */
  private final class PooledConnection implements AsynchronousConnection
  {
    // Connection event listeners registed against this pooled connection should
    // have the same life time as the pooled connection.
    private final List<ConnectionEventListener> listeners =
      new CopyOnWriteArrayList<ConnectionEventListener>();
    private final AsynchronousConnection connection;
    private final AtomicBoolean isClosed = new AtomicBoolean(false);
    PooledConnection(final AsynchronousConnection connection)
    {
      this.connection = connection;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Void> abandon(final AbandonRequest request)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.abandon(request);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Result> add(final AddRequest request,
        final ResultHandler<? super Result> handler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.add(request, handler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Result> add(final AddRequest request,
        final ResultHandler<? super Result> resultHandler,
        final IntermediateResponseHandler intermediateResponseHandler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection
          .add(request, resultHandler, intermediateResponseHandler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void addConnectionEventListener(
        final ConnectionEventListener listener) throws IllegalStateException,
        NullPointerException
    {
      Validator.ensureNotNull(listener);
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      listeners.add(listener);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<BindResult> bind(final BindRequest request,
        final ResultHandler<? super BindResult> handler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.bind(request, handler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<BindResult> bind(final BindRequest request,
        final ResultHandler<? super BindResult> resultHandler,
        final IntermediateResponseHandler intermediateResponseHandler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.bind(request, resultHandler,
          intermediateResponseHandler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void close()
    {
      if (!isClosed.compareAndSet(false, true))
      {
        // Already closed.
        return;
      }
      // Don't put invalid connections back in the pool.
      if (connection.isValid())
      {
        publishConnection(connection);
      }
      else
      {
        // The connection may have been disconnected by the remote server, but
        // the server may still be available. In order to avoid leaving pending
        // futures hanging indefinitely, we should try to reconnect immediately.
        // Close the dead connection.
        connection.close();
        // Try to get a new connection to replace it.
        factory.getAsynchronousConnection(connectionResultHandler);
        if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
        {
          StaticUtils.DEBUG_LOG.warning(String.format(
              "Connection no longer valid. "
                  + "currentPoolSize=%d, poolSize=%d",
                  poolSize - currentPoolSize.availablePermits(), poolSize));
        }
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void close(final UnbindRequest request, final String reason)
        throws NullPointerException
    {
      close();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<CompareResult> compare(final CompareRequest request,
        final ResultHandler<? super CompareResult> handler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.compare(request, handler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<CompareResult> compare(final CompareRequest request,
        final ResultHandler<? super CompareResult> resultHandler,
        final IntermediateResponseHandler intermediateResponseHandler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.compare(request, resultHandler,
          intermediateResponseHandler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Result> delete(final DeleteRequest request,
        final ResultHandler<? super Result> handler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.delete(request, handler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Result> delete(final DeleteRequest request,
        final ResultHandler<? super Result> resultHandler,
        final IntermediateResponseHandler intermediateResponseHandler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.delete(request, resultHandler,
          intermediateResponseHandler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public <R extends ExtendedResult> FutureResult<R> extendedRequest(
        final ExtendedRequest<R> request, final ResultHandler<? super R> handler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.extendedRequest(request, handler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public <R extends ExtendedResult> FutureResult<R> extendedRequest(
        final ExtendedRequest<R> request,
        final ResultHandler<? super R> resultHandler,
        final IntermediateResponseHandler intermediateResponseHandler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.extendedRequest(request, resultHandler,
          intermediateResponseHandler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Connection getSynchronousConnection()
    {
      return new SynchronousConnection(this);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isClosed()
    {
      return isClosed.get();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isValid()
    {
      return connection.isValid() && !isClosed();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Result> modify(final ModifyRequest request,
        final ResultHandler<? super Result> handler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.modify(request, handler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Result> modify(final ModifyRequest request,
        final ResultHandler<? super Result> resultHandler,
        final IntermediateResponseHandler intermediateResponseHandler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.modify(request, resultHandler,
          intermediateResponseHandler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Result> modifyDN(final ModifyDNRequest request,
        final ResultHandler<? super Result> handler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.modifyDN(request, handler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Result> modifyDN(final ModifyDNRequest request,
        final ResultHandler<? super Result> resultHandler,
        final IntermediateResponseHandler intermediateResponseHandler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.modifyDN(request, resultHandler,
          intermediateResponseHandler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<SearchResultEntry> readEntry(final DN name,
        final Collection<String> attributeDescriptions,
        final ResultHandler<? super SearchResultEntry> resultHandler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.readEntry(name, attributeDescriptions, resultHandler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<RootDSE> readRootDSE(
        final ResultHandler<? super RootDSE> handler)
        throws UnsupportedOperationException, IllegalStateException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.readRootDSE(handler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Schema> readSchema(final DN name,
        final ResultHandler<? super Schema> handler)
        throws UnsupportedOperationException, IllegalStateException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.readSchema(name, handler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Schema> readSchemaForEntry(final DN name,
        final ResultHandler<? super Schema> handler)
        throws UnsupportedOperationException, IllegalStateException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.readSchemaForEntry(name, handler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void removeConnectionEventListener(
        final ConnectionEventListener listener) throws NullPointerException
    {
      Validator.ensureNotNull(listener);
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      listeners.remove(listener);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Result> search(final SearchRequest request,
        final SearchResultHandler handler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.search(request, handler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<Result> search(final SearchRequest request,
        final SearchResultHandler resultHandler,
        final IntermediateResponseHandler intermediateResponseHandler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.search(request, resultHandler,
          intermediateResponseHandler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public FutureResult<SearchResultEntry> searchSingleEntry(
        final SearchRequest request,
        final ResultHandler<? super SearchResultEntry> resultHandler)
        throws UnsupportedOperationException, IllegalStateException,
        NullPointerException
    {
      if (isClosed())
      {
        throw new IllegalStateException();
      }
      return connection.searchSingleEntry(request, resultHandler);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String toString()
    {
      final StringBuilder builder = new StringBuilder();
      builder.append("PooledConnection(");
      builder.append(connection);
      builder.append(')');
      return builder.toString();
    }
  }
  /**
   * A queue element is either a pending connection request future awaiting an
   * {@code AsynchronousConnection} or it is an unused
   * {@code AsynchronousConnection} awaiting a connection request.
   */
  private static final class QueueElement
  {
    private final Object value;
    QueueElement(final AsynchronousConnection connection)
    {
      this.value = connection;
    }
    QueueElement(final ResultHandler<? super AsynchronousConnection> handler)
    {
      this.value = new AsynchronousFutureResult<AsynchronousConnection>(handler);
    }
    AsynchronousConnection getWaitingConnection()
    {
      if (value instanceof AsynchronousConnection)
      {
        return (AsynchronousConnection) value;
      }
      else
      {
        throw new IllegalStateException();
      }
    }
    @SuppressWarnings("unchecked")
    AsynchronousFutureResult<AsynchronousConnection> getWaitingFuture()
    {
      if (value instanceof AsynchronousFutureResult)
      {
        return (AsynchronousFutureResult<AsynchronousConnection>) value;
      }
      else
      {
        throw new IllegalStateException();
      }
    }
    boolean isWaitingFuture()
    {
      return value instanceof AsynchronousFutureResult;
    }
    public String toString()
    {
      return String.valueOf(value);
    }
  }
  // Guarded by queue.
  private final LinkedList<QueueElement> queue = new LinkedList<QueueElement>();
  private final ConnectionFactory factory;
  private final int poolSize;
  private final Semaphore currentPoolSize;
  private final ResultHandler<AsynchronousConnection> connectionResultHandler =
    new ConnectionResultHandler();
  /**
   * Creates a new connection pool which will maintain {@code poolSize}
   * connections created using the provided connection factory.
   *
   * @param factory
   *          The connection factory to use for creating new connections.
   * @param poolSize
   *          The maximum size of the connection pool.
   */
  ConnectionPool(final ConnectionFactory factory, final int poolSize)
  {
    this.factory = factory;
    this.poolSize = poolSize;
    this.currentPoolSize = new Semaphore(poolSize);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public FutureResult<AsynchronousConnection> getAsynchronousConnection(
      final ResultHandler<? super AsynchronousConnection> handler)
  {
    QueueElement holder;
    synchronized (queue)
    {
      if (queue.isEmpty() || queue.getFirst().isWaitingFuture())
      {
        holder = new QueueElement(handler);
        queue.add(holder);
      }
      else
      {
        holder = queue.removeFirst();
      }
    }
    if (!holder.isWaitingFuture())
    {
      // There was a completed connection attempt.
      final AsynchronousConnection connection = holder.getWaitingConnection();
      final PooledConnection pooledConnection = new PooledConnection(connection);
      if (handler != null)
      {
        handler.handleResult(pooledConnection);
      }
      return new CompletedFutureResult<AsynchronousConnection>(pooledConnection);
    }
    else
    {
      // Grow the pool if needed.
      final FutureResult<AsynchronousConnection> future = holder
          .getWaitingFuture();
      if (!future.isDone() && currentPoolSize.tryAcquire())
      {
        factory.getAsynchronousConnection(connectionResultHandler);
      }
      return future;
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    final StringBuilder builder = new StringBuilder();
    builder.append("ConnectionPool(");
    builder.append(String.valueOf(factory));
    builder.append(',');
    builder.append(poolSize);
    builder.append(')');
    return builder.toString();
  }
  private void publishConnection(final AsynchronousConnection connection)
  {
    QueueElement holder;
    synchronized (queue)
    {
      if (queue.isEmpty() || !queue.getFirst().isWaitingFuture())
      {
        holder = new QueueElement(connection);
        queue.add(holder);
        return;
      }
      else
      {
        holder = queue.removeFirst();
      }
    }
    // There was waiting future, so close it.
    final PooledConnection pooledConnection = new PooledConnection(connection);
    holder.getWaitingFuture().handleResult(pooledConnection);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionSecurityLayer.java
New file
@@ -0,0 +1,83 @@
/*
 * 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 2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
/**
 * An interface for providing additional connection security to a connection.
 */
public interface ConnectionSecurityLayer
{
  /**
   * Disposes of any system resources or security-sensitive information that
   * this connection security layer might be using. Invoking this method
   * invalidates this instance.
   */
  void dispose();
  /**
   * Unwraps a byte array received from the peer.
   *
   * @param incoming
   *          A non-{@code null} byte array containing the encoded bytes from
   *          the peer.
   * @param offset
   *          The starting position in {@code incoming} of the bytes to be
   *          unwrapped.
   * @param len
   *          The number of bytes from {@code incoming} to be unwrapped.
   * @return A non-{@code null} byte array containing the unwrapped bytes.
   * @throws org.forgerock.opendj.ldap.ErrorResultException
   *           If {@code incoming} cannot be successfully unwrapped.
   */
  byte[] unwrap(byte[] incoming, int offset, int len)
      throws ErrorResultException;
  /**
   * Wraps a byte array to be sent to the peer.
   *
   * @param outgoing
   *          A non-{@code null} byte array containing the unencoded bytes to be
   *          sent to the peer.
   * @param offset
   *          The starting position in {@code outgoing} of the bytes to be
   *          wrapped.
   * @param len
   *          The number of bytes from {@code outgoing} to be wrapped.
   * @return A non-{@code null} byte array containing the wrapped bytes.
   * @throws ErrorResultException
   *           If {@code outgoing} cannot be successfully wrapped.
   */
  byte[] wrap(byte[] outgoing, int offset, int len) throws ErrorResultException;
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java
New file
@@ -0,0 +1,342 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.forgerock.opendj.ldap.requests.BindRequest;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import com.forgerock.opendj.util.Validator;
/**
 * This class contains methods for creating and manipulating connection
 * factories and connections.
 */
public final class Connections
{
  /**
   * Creates a new authenticated connection factory which will obtain
   * connections using the provided connection factory and immediately perform
   * the provided Bind request.
   * <p>
   * The connections returned by an authenticated connection factory support all
   * operations with the exception of Bind requests. Attempts to perform a Bind
   * will result in an {@code UnsupportedOperationException}.
   * <p>
   * If the Bind request fails for some reason (e.g. invalid credentials), then
   * the connection attempt will fail and an {@code ErrorResultException} will
   * be thrown.
   *
   * @param factory
   *          The connection factory to use for connecting to the Directory
   *          Server.
   * @param request
   *          The Bind request to use for authentication.
   * @return The new connection pool.
   * @throws NullPointerException
   *           If {@code factory} or {@code request} was {@code null}.
   */
  public static ConnectionFactory newAuthenticatedConnectionFactory(
      final ConnectionFactory factory, final BindRequest request)
      throws NullPointerException
  {
    Validator.ensureNotNull(factory, request);
    return new AuthenticatedConnectionFactory(factory, request);
  }
  /**
   * Creates a new connection pool which will maintain {@code poolSize}
   * connections created using the provided connection factory.
   *
   * @param factory
   *          The connection factory to use for creating new connections.
   * @param poolSize
   *          The maximum size of the connection pool.
   * @return The new connection pool.
   * @throws IllegalArgumentException
   *           If {@code poolSize} is negative.
   * @throws NullPointerException
   *           If {@code factory} was {@code null}.
   */
  public static ConnectionFactory newConnectionPool(
      final ConnectionFactory factory, final int poolSize)
      throws IllegalArgumentException, NullPointerException
  {
    Validator.ensureNotNull(factory);
    Validator.ensureTrue(poolSize >= 0, "negative pool size");
    return new ConnectionPool(factory, poolSize);
  }
  /**
   * Creates a new heart-beat connection factory which will create connections
   * using the provided connection factory and periodically ping any created
   * connections in order to detect that they are still alive every 10 seconds
   * using the default scheduler.
   *
   * @param factory
   *          The connection factory to use for creating connections.
   * @return The new heart-beat connection factory.
   * @throws NullPointerException
   *           If {@code factory} was {@code null}.
   */
  public static ConnectionFactory newHeartBeatConnectionFactory(
      final ConnectionFactory factory) throws NullPointerException
  {
    return new HeartBeatConnectionFactory(factory);
  }
  /**
   * Creates a new heart-beat connection factory which will create connections
   * using the provided connection factory and periodically ping any created
   * connections in order to detect that they are still alive using the
   * specified frequency and the default scheduler.
   *
   * @param factory
   *          The connection factory to use for creating connections.
   * @param interval
   *          The interval between keepalive pings.
   * @param unit
   *          The time unit for the interval between keepalive pings.
   * @return The new heart-beat connection factory.
   * @throws IllegalArgumentException
   *           If {@code interval} was negative.
   * @throws NullPointerException
   *           If {@code factory} or {@code unit} was {@code null}.
   */
  public static ConnectionFactory newHeartBeatConnectionFactory(
      final ConnectionFactory factory, final long interval, final TimeUnit unit)
      throws IllegalArgumentException, NullPointerException
  {
    return new HeartBeatConnectionFactory(factory, interval, unit);
  }
  /**
   * Creates a new heart-beat connection factory which will create connections
   * using the provided connection factory and periodically ping any created
   * connections using the specified search request in order to detect that they
   * are still alive.
   *
   * @param factory
   *          The connection factory to use for creating connections.
   * @param interval
   *          The interval between keepalive pings.
   * @param unit
   *          The time unit for the interval between keepalive pings.
   * @param heartBeat
   *          The search request to use for keepalive pings.
   * @return The new heart-beat connection factory.
   * @throws IllegalArgumentException
   *           If {@code interval} was negative.
   * @throws NullPointerException
   *           If {@code factory}, {@code unit}, or {@code heartBeat} was {@code null}.
   */
  public static ConnectionFactory newHeartBeatConnectionFactory(
      final ConnectionFactory factory, final long interval, final TimeUnit unit,
      final SearchRequest heartBeat) throws IllegalArgumentException,
      NullPointerException
  {
    return new HeartBeatConnectionFactory(factory, interval, unit, heartBeat);
  }
  /**
   * Creates a new heart-beat connection factory which will create connections
   * using the provided connection factory and periodically ping any created
   * connections using the specified search request in order to detect that they
   * are still alive.
   *
   * @param factory
   *          The connection factory to use for creating connections.
   * @param interval
   *          The interval between keepalive pings.
   * @param unit
   *          The time unit for the interval between keepalive pings.
   * @param heartBeat
   *          The search request to use for keepalive pings.
   * @param scheduler
   *          The scheduler which should for periodically sending keepalive
   *          pings.
   * @return The new heart-beat connection factory.
   * @throws IllegalArgumentException
   *           If {@code interval} was negative.
   * @throws NullPointerException
   *           If {@code factory}, {@code unit}, or {@code heartBeat} was
   *           {@code null}.
   */
  public static ConnectionFactory newHeartBeatConnectionFactory(
      final ConnectionFactory factory, final long interval,
      final TimeUnit unit, final SearchRequest heartBeat,
      final ScheduledExecutorService scheduler)
      throws IllegalArgumentException, NullPointerException
  {
    return new HeartBeatConnectionFactory(factory, interval, unit, heartBeat,
        scheduler);
  }
  /**
   * Creates a new connection factory which binds internal client connections to
   * {@link ServerConnection}s created using the provided
   * {@link ServerConnectionFactory}.
   * <p>
   * When processing requests, {@code ServerConnection} implementations are
   * passed an integer as the first parameter. This integer represents a pseudo
   * {@code requestID} which is incremented for each successive internal request
   * on a per client connection basis. The request ID may be useful for logging
   * purposes.
   * <p>
   * An internal connection factory does not require {@code ServerConnection}
   * implementations to return a result when processing requests. However, it is
   * recommended that implementations do always return results even for
   * abandoned requests. This is because application client threads may block
   * indefinitely waiting for results.
   *
   * @param <C>
   *          The type of client context.
   * @param factory
   *          The server connection factory to use for creating connections.
   * @param clientContext
   *          The client context.
   * @return The new internal connection factory.
   * @throws NullPointerException
   *           If {@code factory} was {@code null}.
   */
  public static <C> ConnectionFactory newInternalConnectionFactory(
      final ServerConnectionFactory<C, Integer> factory, final C clientContext)
      throws NullPointerException
  {
    Validator.ensureNotNull(factory);
    return new InternalConnectionFactory<C>(factory, clientContext);
  }
  /**
   * Creates a new load balancer which will obtain connections using the
   * provided load balancing algorithm.
   *
   * @param algorithm
   *          The load balancing algorithm which will be used to obtain the next
   * @return The new load balancer.
   * @throws NullPointerException
   *           If {@code algorithm} was {@code null}.
   */
  public static ConnectionFactory newLoadBalancer(
      final LoadBalancingAlgorithm algorithm) throws NullPointerException
  {
    return new LoadBalancer(algorithm);
  }
  /**
   * Creates a new connection factory which forwards connection requests to the
   * provided factory, but whose {@code toString} method will always return
   * {@code name}.
   * <p>
   * This method may be useful for debugging purposes in order to more easily
   * identity connection factories.
   *
   * @param factory
   *          The connection factory to be named.
   * @param name
   *          The name of the connection factory.
   * @return The named connection factory.
   * @throws NullPointerException
   *           If {@code factory} or {@code name} was {@code null}.
   */
  public static ConnectionFactory newNamedConnectionFactory(
      final ConnectionFactory factory, final String name)
      throws NullPointerException
  {
    Validator.ensureNotNull(factory, name);
    return new ConnectionFactory()
    {
      @Override
      public FutureResult<AsynchronousConnection> getAsynchronousConnection(
          final ResultHandler<? super AsynchronousConnection> handler)
      {
        return factory.getAsynchronousConnection(handler);
      }
      @Override
      public Connection getConnection() throws ErrorResultException,
          InterruptedException
      {
        return factory.getConnection();
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public String toString()
      {
        return name;
      }
    };
  }
  // Prevent instantiation.
  private Connections()
  {
    // Do nothing.
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ConstraintViolationException.java
New file
@@ -0,0 +1,80 @@
/*
 * 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 2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import org.forgerock.opendj.ldap.responses.Result;
/**
 * Thrown when the result code returned in a Result indicates that the update
 * Request failed because it would have left the Directory in an inconsistent
 * state. More specifically, this exception is used for the following error
 * result codes:
 * <ul>
 * <li>{@link ResultCode#ATTRIBUTE_OR_VALUE_EXISTS ATTRIBUTE_OR_VALUE_EXISTS} -
 * the Request failed because it would have resulted in a conflict with an
 * existing attribute or attribute value in the target entry.
 * <li>{@link ResultCode#CONSTRAINT_VIOLATION CONSTRAINT_VIOLATION} - the
 * Request failed because it would have violated some constraint defined in the
 * server.
 * <li>{@link ResultCode#ENTRY_ALREADY_EXISTS ENTRY_ALREADY_EXISTS} - the
 * Request failed because it would have resulted in an entry that conflicts with
 * an entry that already exists.
 * <li>{@link ResultCode#INVALID_ATTRIBUTE_SYNTAX INVALID_ATTRIBUTE_SYNTAX} -
 * the Request failed because it violated the syntax for a specified attribute.
 * <li>{@link ResultCode#INVALID_DN_SYNTAX INVALID_DN_SYNTAX} - the Request
 * failed because it would have resulted in an entry with an invalid or
 * malformed DN.
 * <li>{@link ResultCode#NAMING_VIOLATION NAMING_VIOLATION} - the Request failed
 * becauseit would have violated the server's naming configuration.
 * <li>{@link ResultCode#NOT_ALLOWED_ON_NONLEAF NOT_ALLOWED_ON_NONLEAF} - the
 * Request failed because it is not allowed for non-leaf entries.
 * <li>{@link ResultCode#NOT_ALLOWED_ON_RDN NOT_ALLOWED_ON_RDN} - the Request
 * failed because it is not allowed on an RDN attribute.
 * <li>{@link ResultCode#OBJECTCLASS_MODS_PROHIBITED
 * OBJECTCLASS_MODS_PROHIBITED} - the Request failed because it would have
 * modified the objectclasses associated with an entry in an illegal manner.
 * <li>{@link ResultCode#OBJECTCLASS_VIOLATION OBJECTCLASS_VIOLATION} - the
 * Request failed because it would have resulted in an entry that violated the
 * server schema.
 * <li>{@link ResultCode#UNDEFINED_ATTRIBUTE_TYPE UNDEFINED_ATTRIBUTE_TYPE} -
 * the Request failed because it referenced an attribute that is not defined in
 * the server schema.
 * </ul>
 */
@SuppressWarnings("serial")
public class ConstraintViolationException extends ErrorResultException
{
  ConstraintViolationException(final Result result)
  {
    super(result);
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/DN.java
New file
@@ -0,0 +1,815 @@
/*
 * 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-2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_DN_TYPE_NOT_FOUND;
import java.util.*;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldap.schema.UnknownSchemaElementException;
import com.forgerock.opendj.util.SubstringReader;
import com.forgerock.opendj.util.Validator;
/**
 * A distinguished name (DN) as defined in RFC 4512 section 2.3 is the
 * concatenation of its relative distinguished name (RDN) and its immediate
 * superior's DN. A DN unambiguously refers to an entry in the Directory.
 * <p>
 * The following are examples of string representations of DNs:
 *
 * <pre>
 * UID=nobody@example.com,DC=example,DC=com CN=John
 * Smith,OU=Sales,O=ACME Limited,L=Moab,ST=Utah,C=US
 * </pre>
 *
 * @see <a href="http://tools.ietf.org/html/rfc4512#section-2.3">RFC 4512 -
 *      Lightweight Directory Access Protocol (LDAP): Directory Information
 *      Models </a>
 */
public final class DN implements Iterable<RDN>, Comparable<DN>
{
  private static final DN ROOT_DN = new DN(null, null, "");
  // This is the size of the per-thread per-schema DN cache. We should
  // be conservative here in case there are many threads. We will only
  // cache parent DNs, so there's no need for it to be big.
  private static final int DN_CACHE_SIZE = 32;
  private static final ThreadLocal<WeakHashMap<Schema, Map<String, DN>>> CACHE =
    new ThreadLocal<WeakHashMap<Schema, Map<String, DN>>>()
  {
    /**
     * {@inheritDoc}
     */
    @Override
    protected WeakHashMap<Schema, Map<String, DN>> initialValue()
    {
      return new WeakHashMap<Schema, Map<String, DN>>();
    }
  };
  /**
   * Returns the Root DN. The Root DN does not contain and RDN components and is
   * superior to all other DNs.
   *
   * @return The Root DN.
   */
  public static DN rootDN()
  {
    return ROOT_DN;
  }
  /**
   * Parses the provided LDAP string representation of a DN using the default
   * schema.
   *
   * @param dn
   *          The LDAP string representation of a DN.
   * @return The parsed DN.
   * @throws LocalizedIllegalArgumentException
   *           If {@code dn} is not a valid LDAP string representation of a DN.
   * @throws NullPointerException
   *           If {@code dn} was {@code null}.
   */
  public static DN valueOf(final String dn)
      throws LocalizedIllegalArgumentException, NullPointerException
  {
    return valueOf(dn, Schema.getDefaultSchema());
  }
  /**
   * Parses the provided LDAP string representation of a DN using the provided
   * schema.
   *
   * @param dn
   *          The LDAP string representation of a DN.
   * @param schema
   *          The schema to use when parsing the DN.
   * @return The parsed DN.
   * @throws LocalizedIllegalArgumentException
   *           If {@code dn} is not a valid LDAP string representation of a DN.
   * @throws NullPointerException
   *           If {@code dn} or {@code schema} was {@code null}.
   */
  public static DN valueOf(final String dn, final Schema schema)
      throws LocalizedIllegalArgumentException, NullPointerException
  {
    Validator.ensureNotNull(dn, schema);
    if (dn.length() == 0)
    {
      return ROOT_DN;
    }
    // First check if DN is already cached.
    final Map<String, DN> cache = getCache(schema);
    final DN cachedDN = cache.get(dn);
    if (cachedDN != null)
    {
      return cachedDN;
    }
    // Not in cache so decode.
    final SubstringReader reader = new SubstringReader(dn);
    return decode(dn, reader, schema, cache);
  }
  /**
   * Compares the provided DN values to determine their relative order in a
   * sorted list.
   *
   * @param dn1
   *          The first DN to be compared. It must not be {@code null}.
   * @param dn2
   *          The second DN to be compared. It must not be {@code null}.
   * @return A negative integer if the first DN should come before the second DN
   *         in a sorted list, a positive integer if the first DN should come
   *         after the second DN in a sorted list, or zero if the two DN values
   *         can be considered equal.
   */
  private static int compareTo(final DN dn1, final DN dn2)
  {
    // Quickly check if we are comparing against root dse.
    if (dn1.isRootDN())
    {
      if (dn2.isRootDN())
      {
        // both are equal.
        return 0;
      }
      else
      {
        // dn1 comes before dn2.
        return -1;
      }
    }
    if (dn2.isRootDN())
    {
      // dn1 comes after dn2.
      return 1;
    }
    int dn1Size = dn1.size - 1;
    int dn2Size = dn2.size - 1;
    while (dn1Size >= 0 && dn2Size >= 0)
    {
      final DN dn1Parent = dn1.parent(dn1Size--);
      final DN dn2Parent = dn2.parent(dn2Size--);
      if (dn1Parent.isRootDN())
      {
        if (dn2Parent.isRootDN())
        {
          break;
        }
        return -1;
      }
      if (dn2Parent.isRootDN())
      {
        return 1;
      }
      final int result = dn1Parent.rdn.compareTo(dn2Parent.rdn);
      if (result > 0)
      {
        return 1;
      }
      else if (result < 0)
      {
        return -1;
      }
    }
    // What do we have here?
    if (dn1Size > dn2Size)
    {
      return 1;
    }
    else if (dn1Size < dn2Size)
    {
      return -1;
    }
    return 0;
  }
  // Decodes a DN using the provided reader and schema.
  private static DN decode(final String dnString, final SubstringReader reader,
      final Schema schema, final Map<String, DN> cache)
      throws LocalizedIllegalArgumentException
  {
    reader.skipWhitespaces();
    if (reader.remaining() == 0)
    {
      return ROOT_DN;
    }
    RDN rdn;
    try
    {
      rdn = RDN.decode(null, reader, schema);
    }
    catch (final UnknownSchemaElementException e)
    {
      final LocalizableMessage message = ERR_DN_TYPE_NOT_FOUND.get(reader
          .getString(), e.getMessageObject());
      throw new LocalizedIllegalArgumentException(message);
    }
    DN parent;
    if (reader.remaining() > 0 && reader.read() == ',')
    {
      reader.mark();
      final String parentString = reader.read(reader.remaining());
      parent = cache.get(parentString);
      if (parent == null)
      {
        reader.reset();
        parent = decode(parentString, reader, schema, cache);
        // Only cache parent DNs since leaf DNs are likely to make the
        // cache to volatile.
        cache.put(parentString, parent);
      }
    }
    else
    {
      parent = ROOT_DN;
    }
    return new DN(rdn, parent, dnString);
  }
  @SuppressWarnings("serial")
  private static Map<String, DN> getCache(final Schema schema)
  {
    final WeakHashMap<Schema, Map<String, DN>> threadLocalMap = CACHE.get();
    Map<String, DN> schemaLocalMap = threadLocalMap.get(schema);
    if (schemaLocalMap == null)
    {
      schemaLocalMap = new LinkedHashMap<String, DN>(DN_CACHE_SIZE, 0.75f, true)
      {
        @Override
        protected boolean removeEldestEntry(final Map.Entry<String, DN> e)
        {
          return size() > DN_CACHE_SIZE;
        }
      };
      threadLocalMap.put(schema, schemaLocalMap);
    }
    return schemaLocalMap;
  }
  private final RDN rdn;
  private final DN parent;
  private final int size;
  // We need to store the original string value if provided in order to
  // preserve the original whitespace.
  private String stringValue;
  // Private constructor.
  private DN(final RDN rdn, final DN parent, final String stringValue)
  {
    this.rdn = rdn;
    this.parent = parent;
    this.stringValue = stringValue;
    this.size = parent != null ? parent.size + 1 : 0;
  }
  /**
   * Returns a DN which is subordinate to this DN and having the additional RDN
   * components contained in the provided DN.
   *
   * @param dn
   *          The DN containing the RDN components to be added to this DN.
   * @return The subordinate DN.
   * @throws NullPointerException
   *           If {@code dn} was {@code null}.
   */
  public DN child(final DN dn) throws NullPointerException
  {
    Validator.ensureNotNull(dn);
    if (dn.isRootDN())
    {
      return this;
    }
    else if (isRootDN())
    {
      return dn;
    }
    else
    {
      final RDN[] rdns = new RDN[dn.size()];
      int i = rdns.length;
      for (DN next = dn; next.rdn != null; next = next.parent)
      {
        rdns[--i] = next.rdn;
      }
      DN newDN = this;
      for (i = 0; i < rdns.length; i++)
      {
        newDN = new DN(rdns[i], newDN, null);
      }
      return newDN;
    }
  }
  /**
   * Returns a DN which is an immediate child of this DN and having the
   * specified RDN.
   *
   * @param rdn
   *          The RDN for the child DN.
   * @return The child DN.
   * @throws NullPointerException
   *           If {@code rdn} was {@code null}.
   */
  public DN child(final RDN rdn) throws NullPointerException
  {
    Validator.ensureNotNull(rdn);
    return new DN(rdn, this, null);
  }
  /**
   * Returns a DN which is subordinate to this DN and having the additional RDN
   * components contained in the provided DN decoded using the default schema.
   *
   * @param dn
   *          The DN containing the RDN components to be added to this DN.
   * @return The subordinate DN.
   * @throws LocalizedIllegalArgumentException
   *           If {@code dn} is not a valid LDAP string representation of a DN.
   * @throws NullPointerException
   *           If {@code dn} was {@code null}.
   */
  public DN child(final String dn) throws LocalizedIllegalArgumentException,
      NullPointerException
  {
    Validator.ensureNotNull(dn);
    return child(valueOf(dn));
  }
  /**
   * {@inheritDoc}
   */
  public int compareTo(final DN dn)
  {
    return compareTo(this, dn);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean equals(final Object obj)
  {
    if (this == obj)
    {
      return true;
    }
    else if (obj instanceof DN)
    {
      DN other = (DN)obj;
      if(size == other.size())
      {
        if(size == 0)
        {
          return true;
        }
        if(rdn.equals(other.rdn))
        {
          return parent.equals(other.parent);
        }
      }
    }
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int hashCode()
  {
    if (size == 0)
    {
      return 0;
    }
    else
    {
      return 31 * parent.hashCode() + rdn.hashCode();
    }
  }
  /**
   * Returns {@code true} if this DN is an immediate child of the provided DN.
   *
   * @param dn
   *          The potential parent DN.
   * @return {@code true} if this DN is the immediate child of the provided DN,
   *         otherwise {@code false}.
   * @throws NullPointerException
   *           If {@code dn} was {@code null}.
   */
  public boolean isChildOf(final DN dn) throws NullPointerException
  {
    // If this is the Root DN then parent will be null but this is ok.
    return dn.equals(parent);
  }
  /**
   * Returns {@code true} if this DN is an immediate child of the provided DN
   * decoded using the default schema.
   *
   * @param dn
   *          The potential parent DN.
   * @return {@code true} if this DN is the immediate child of the provided DN,
   *         otherwise {@code false}.
   * @throws LocalizedIllegalArgumentException
   *           If {@code dn} is not a valid LDAP string representation of a DN.
   * @throws NullPointerException
   *           If {@code dn} was {@code null}.
   */
  public boolean isChildOf(final String dn)
      throws LocalizedIllegalArgumentException, NullPointerException
  {
    // If this is the Root DN then parent will be null but this is ok.
    return isChildOf(valueOf(dn));
  }
  /**
   * Returns {@code true} if this DN is the immediate parent of the provided DN.
   *
   * @param dn
   *          The potential child DN.
   * @return {@code true} if this DN is the immediate parent of the provided DN,
   *         otherwise {@code false}.
   * @throws NullPointerException
   *           If {@code dn} was {@code null}.
   */
  public boolean isParentOf(final DN dn) throws NullPointerException
  {
    // If dn is the Root DN then parent will be null but this is ok.
    return equals(dn.parent);
  }
  /**
   * Returns {@code true} if this DN is the immediate parent of the provided DN.
   *
   * @param dn
   *          The potential child DN.
   * @return {@code true} if this DN is the immediate parent of the provided DN,
   *         otherwise {@code false}.
   * @throws LocalizedIllegalArgumentException
   *           If {@code dn} is not a valid LDAP string representation of a DN.
   * @throws NullPointerException
   *           If {@code dn} was {@code null}.
   */
  public boolean isParentOf(final String dn)
      throws LocalizedIllegalArgumentException, NullPointerException
  {
    // If dn is the Root DN then parent will be null but this is ok.
    return isParentOf(valueOf(dn));
  }
  /**
   * Returns {@code true} if this DN is the Root DN.
   *
   * @return {@code true} if this DN is the Root DN, otherwise {@code false}.
   */
  public boolean isRootDN()
  {
    return size == 0;
  }
  /**
   * Returns {@code true} if this DN is subordinate to or equal to the provided
   * DN.
   *
   * @param dn
   *          The potential child DN.
   * @return {@code true} if this DN is subordinate to or equal to the provided
   *         DN, otherwise {@code false}.
   * @throws NullPointerException
   *           If {@code dn} was {@code null}.
   */
  public boolean isSubordinateOrEqualTo(final DN dn)
      throws NullPointerException
  {
    if (size < dn.size)
    {
      return false;
    }
    else if (size == dn.size)
    {
      return equals(dn);
    }
    else
    {
      // dn is a potential superior of this.
      return parent(size - dn.size).equals(dn);
    }
  }
  /**
   * Returns {@code true} if this DN is subordinate to or equal to the provided
   * DN.
   *
   * @param dn
   *          The potential child DN.
   * @return {@code true} if this DN is subordinate to or equal to the provided
   *         DN, otherwise {@code false}.
   * @throws LocalizedIllegalArgumentException
   *           If {@code dn} is not a valid LDAP string representation of a DN.
   * @throws NullPointerException
   *           If {@code dn} was {@code null}.
   */
  public boolean isSubordinateOrEqualTo(final String dn)
      throws LocalizedIllegalArgumentException, NullPointerException
  {
    return isSubordinateOrEqualTo(valueOf(dn));
  }
  /**
   * Returns {@code true} if this DN is superior to or equal to the provided DN.
   *
   * @param dn
   *          The potential child DN.
   * @return {@code true} if this DN is superior to or equal to the provided DN,
   *         otherwise {@code false}.
   * @throws NullPointerException
   *           If {@code dn} was {@code null}.
   */
  public boolean isSuperiorOrEqualTo(final DN dn) throws NullPointerException
  {
    if (size > dn.size)
    {
      return false;
    }
    else if (size == dn.size)
    {
      return equals(dn);
    }
    else
    {
      // dn is a potential subordinate of this.
      return dn.parent(dn.size - size).equals(this);
    }
  }
  /**
   * Returns {@code true} if this DN is superior to or equal to the provided DN.
   *
   * @param dn
   *          The potential child DN.
   * @return {@code true} if this DN is superior to or equal to the provided DN,
   *         otherwise {@code false}.
   * @throws LocalizedIllegalArgumentException
   *           If {@code dn} is not a valid LDAP string representation of a DN.
   * @throws NullPointerException
   *           If {@code dn} was {@code null}.
   */
  public boolean isSuperiorOrEqualTo(final String dn)
      throws LocalizedIllegalArgumentException, NullPointerException
  {
    return isSuperiorOrEqualTo(valueOf(dn));
  }
  /**
   * Returns an iterator of the RDNs contained in this DN. The RDNs will be
   * returned in the order starting with this DN's RDN, followed by the RDN of
   * the parent DN, and so on.
   * <p>
   * Attempts to remove RDNs using an iterator's {@code remove()} method are not
   * permitted and will result in an {@code UnsupportedOperationException} being
   * thrown.
   *
   * @return An iterator of the RDNs contained in this DN.
   */
  public Iterator<RDN> iterator()
  {
    return new Iterator<RDN>()
    {
      private DN dn = DN.this;
      public boolean hasNext()
      {
        return dn.rdn != null;
      }
      public RDN next()
      {
        if (dn.rdn == null)
        {
          throw new NoSuchElementException();
        }
        final RDN rdn = dn.rdn;
        dn = dn.parent;
        return rdn;
      }
      public void remove()
      {
        throw new UnsupportedOperationException();
      }
    };
  }
  /**
   * Returns the DN which is the immediate parent of this DN, or {@code null} if
   * this DN is the Root DN.
   * <p>
   * This method is equivalent to:
   *
   * <pre>
   * parent(1);
   * </pre>
   *
   * @return The DN which is the immediate parent of this DN, or {@code null} if
   *         this DN is the Root DN.
   */
  public DN parent()
  {
    return parent;
  }
  /**
   * Returns the DN which is equal to this DN with the specified number of RDNs
   * removed. Note that if {@code index} is zero then this DN will be returned
   * (identity).
   *
   * @param index
   *          The number of RDNs to be removed.
   * @return The DN which is equal to this DN with the specified number of RDNs
   *         removed, or {@code null} if the parent of the Root DN is reached.
   * @throws IllegalArgumentException
   *           If {@code index} is less than zero.
   */
  public DN parent(final int index) throws IllegalArgumentException
  {
    // We allow size + 1 so that we can return null as the parent of the
    // Root DN.
    Validator.ensureTrue(index >= 0, "index less than zero");
    DN parentDN = this;
    for (int i = 0; parentDN != null && i < index; i++)
    {
      parentDN = parentDN.parent;
    }
    return parentDN;
  }
  /**
   * Returns the RDN of this DN, or {@code null} if this DN is the Root DN.
   *
   * @return The RDN of this DN, or {@code null} if this DN is the Root DN.
   */
  public RDN rdn()
  {
    return rdn;
  }
  /**
   * Returns the number of RDN components in this DN.
   *
   * @return The number of RDN components in this DN.
   */
  public int size()
  {
    return size;
  }
  /**
   * Returns the RFC 4514 string representation of this DN.
   *
   * @return The RFC 4514 string representation of this DN.
   * @see <a href="http://tools.ietf.org/html/rfc4514">RFC 4514 - Lightweight
   *      Directory Access Protocol (LDAP): String Representation of
   *      Distinguished Names </a>
   */
  @Override
  public String toString()
  {
    // We don't care about potential race conditions here.
    if (stringValue == null)
    {
      final StringBuilder builder = new StringBuilder();
      rdn.toString(builder);
      if (!parent.isRootDN())
      {
        builder.append(',');
        builder.append(parent.toString());
      }
      stringValue = builder.toString();
    }
    return stringValue;
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/DecodeException.java
New file
@@ -0,0 +1,153 @@
/*
 * 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.forgerock.opendj.ldap;
import java.io.IOException;
import org.forgerock.i18n.LocalizableException;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Thrown when data from an input source cannot be decoded, perhaps due to the
 * data being malformed in some way. By default decoding exceptions are fatal,
 * indicating that the associated input source is no longer usable.
 */
@SuppressWarnings("serial")
public final class DecodeException extends IOException implements
    LocalizableException
{
  /**
   * Creates a new non-fatal decode exception with the provided message.
   *
   * @param message
   *          The message that explains the problem that occurred.
   * @return The new non-fatal decode exception.
   */
  public static DecodeException error(final LocalizableMessage message)
  {
    return new DecodeException(message, false, null);
  }
  /**
   * Creates a new non-fatal decode exception with the provided message and root
   * cause.
   *
   * @param message
   *          The message that explains the problem that occurred.
   * @param cause
   *          The underlying cause of this exception.
   * @return The new non-fatal decode exception.
   */
  public static DecodeException error(final LocalizableMessage message,
      final Throwable cause)
  {
    return new DecodeException(message, false, cause);
  }
  /**
   * Creates a new fatal decode exception with the provided message. The
   * associated input source can no longer be used.
   *
   * @param message
   *          The message that explains the problem that occurred.
   * @return The new fatal decode exception.
   */
  public static DecodeException fatalError(final LocalizableMessage message)
  {
    return new DecodeException(message, true, null);
  }
  /**
   * Creates a new fatal decode exception with the provided message and root
   * cause. The associated input source can no longer be used.
   *
   * @param message
   *          The message that explains the problem that occurred.
   * @param cause
   *          The underlying cause of this exception.
   * @return The new fatal decode exception.
   */
  public static DecodeException fatalError(final LocalizableMessage message,
      final Throwable cause)
  {
    return new DecodeException(message, true, cause);
  }
  private final LocalizableMessage message;
  private final boolean isFatal;
  // Construction is provided via factory methods.
  private DecodeException(final LocalizableMessage message,
      final boolean isFatal, final Throwable cause)
  {
    super(message.toString(), cause);
    this.message = message;
    this.isFatal = isFatal;
  }
  /**
   * Returns the message that explains the problem that occurred.
   *
   * @return LocalizableMessage of the problem
   */
  public LocalizableMessage getMessageObject()
  {
    return message;
  }
  /**
   * Indicates whether or not the error was fatal and the associated input
   * source can no longer be used.
   *
   * @return {@code true} if the error was fatal and the associated input source
   *         can no longer be used, otherwise {@code false} .
   */
  public boolean isFatal()
  {
    return isFatal;
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/DecodeOptions.java
New file
@@ -0,0 +1,242 @@
/*
 * 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.
 *      Portions copyright 2011 ForgeRock AS
 */
package org.forgerock.opendj.ldap;
import org.forgerock.opendj.ldap.schema.Schema;
import com.forgerock.opendj.util.Validator;
/**
 * Decode options allow applications to control how requests and responses are
 * decoded. In particular:
 * <ul>
 * <li>The strategy for selecting which {@code Schema} should be used for
 * decoding distinguished names, attribute descriptions, and other objects which
 * require a schema in order to be decoded.
 * <li>The {@code Attribute} implementation which should be used when decoding
 * attributes.
 * <li>The {@code Entry} implementation which should be used when decoding
 * entries or entry like objects.
 * </ul>
 */
public final class DecodeOptions
{
  private static final class FixedSchemaResolver implements SchemaResolver
  {
    private final Schema schema;
    private FixedSchemaResolver(final Schema schema)
    {
      this.schema = schema;
    }
    /**
     * {@inheritDoc}
     */
    public Schema resolveSchema(final String dn)
    {
      return schema;
    }
  }
  private SchemaResolver schemaResolver;
  private EntryFactory entryFactory;
  private AttributeFactory attributeFactory;
  /**
   * Creates a new set of decode options which will always use the default
   * schema returned by {@link Schema#getDefaultSchema()},
   * {@link LinkedAttribute}, and {@link LinkedHashMapEntry}.
   */
  public DecodeOptions()
  {
    this.attributeFactory = LinkedAttribute.FACTORY;
    this.entryFactory = LinkedHashMapEntry.FACTORY;
    this.schemaResolver = SchemaResolver.DEFAULT;
  }
  /**
   * Creates a new set of decode options having the same initial set of options
   * as the provided set of decode options.
   *
   * @param options
   *          The set of decode options to be copied.
   */
  public DecodeOptions(final DecodeOptions options)
  {
    this.attributeFactory = options.attributeFactory;
    this.entryFactory = options.entryFactory;
    this.schemaResolver = options.schemaResolver;
  }
  /**
   * Returns the {@code AttributeFactory} which will be used for creating new
   * {@code Attribute} instances when decoding attributes.
   *
   * @return The {@code AttributeFactory} which will be used for creating new
   *         {@code Attribute} instances when decoding attributes.
   */
  public final AttributeFactory getAttributeFactory()
  {
    return attributeFactory;
  }
  /**
   * Returns the {@code EntryFactory} which will be used for creating new
   * {@code Entry} instances when decoding entries.
   *
   * @return The {@code EntryFactory} which will be used for creating new
   *         {@code Entry} instances when decoding entries.
   */
  public final EntryFactory getEntryFactory()
  {
    return entryFactory;
  }
  /**
   * Returns the strategy for selecting which {@code Schema} should be used for
   * decoding distinguished names, attribute descriptions, and other objects
   * which require a {@code Schema} in order to be decoded.
   *
   * @return The schema resolver which will be used for decoding.
   */
  public final SchemaResolver getSchemaResolver()
  {
    return schemaResolver;
  }
  /**
   * Sets the {@code AttributeFactory} which will be used for creating new
   * {@code Attribute} instances when decoding attributes.
   *
   * @param factory
   *          The {@code AttributeFactory} which will be used for creating new
   *          {@code Attribute} instances when decoding attributes.
   * @return A reference to this set of decode options.
   * @throws NullPointerException
   *           If {@code factory} was {@code null}.
   */
  public final DecodeOptions setAttributeFactory(final AttributeFactory factory)
      throws NullPointerException
  {
    Validator.ensureNotNull(factory);
    this.attributeFactory = factory;
    return this;
  }
  /**
   * Sets the {@code EntryFactory} which will be used for creating new {@code
   * Entry} instances when decoding entries.
   *
   * @param factory
   *          The {@code EntryFactory} which will be used for creating new
   *          {@code Entry} instances when decoding entries.
   * @return A reference to this set of decode options.
   * @throws NullPointerException
   *           If {@code factory} was {@code null}.
   */
  public final DecodeOptions setEntryFactory(final EntryFactory factory)
      throws NullPointerException
  {
    Validator.ensureNotNull(factory);
    this.entryFactory = factory;
    return this;
  }
  /**
   * Sets the {@code Schema} which will be used for decoding distinguished
   * names, attribute descriptions, and other objects which require a schema in
   * order to be decoded. This setting overrides the currently active schema
   * resolver set using {@link #setSchemaResolver}.
   *
   * @param schema
   *          The {@code Schema} which will be used for decoding.
   * @return A reference to this set of decode options.
   * @throws NullPointerException
   *           If {@code schema} was {@code null}.
   */
  public final DecodeOptions setSchema(final Schema schema)
      throws NullPointerException
  {
    Validator.ensureNotNull(schema);
    this.schemaResolver = new FixedSchemaResolver(schema);
    return this;
  }
  /**
   * Sets the strategy for selecting which {@code Schema} should be used for
   * decoding distinguished names, attribute descriptions, and other objects
   * which require a {@code Schema} in order to be decoded. This setting
   * overrides the currently active schema set using {@link #setSchema}.
   *
   * @param resolver
   *          The {@code SchemaResolver} which will be used for decoding.
   * @return A reference to this set of decode options.
   * @throws NullPointerException
   *           If {@code resolver} was {@code null}.
   */
  public final DecodeOptions setSchemaResolver(final SchemaResolver resolver)
      throws NullPointerException
  {
    Validator.ensureNotNull(resolver);
    this.schemaResolver = resolver;
    return this;
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/DereferenceAliasesPolicy.java
New file
@@ -0,0 +1,218 @@
/*
 * 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.forgerock.opendj.ldap;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
 * A Search operation alias dereferencing policy as defined in RFC 4511 section
 * 4.5.1.3 is used to indicate whether or not alias entries (as defined in RFC
 * 4512) are to be dereferenced during stages of a Search operation. The act of
 * dereferencing an alias includes recursively dereferencing aliases that refer
 * to aliases.
 *
 * @see <a href="http://tools.ietf.org/html/rfc4511#section-4.5.1.3">RFC 4511 -
 *      Lightweight Directory Access Protocol (LDAP): The Protocol </a>
 * @see <a href="http://tools.ietf.org/html/rfc4512">RFC 4512 - Lightweight
 *      Directory Access Protocol (LDAP): Directory Information Models </a>
 */
public final class DereferenceAliasesPolicy
{
  private static final DereferenceAliasesPolicy[] ELEMENTS = new DereferenceAliasesPolicy[4];
  private static final List<DereferenceAliasesPolicy> IMMUTABLE_ELEMENTS = Collections
      .unmodifiableList(Arrays.asList(ELEMENTS));
  /**
   * Do not dereference aliases in searching or in locating the base object of a
   * Search operation.
   */
  public static final DereferenceAliasesPolicy NEVER = register(0, "never");
  /**
   * While searching subordinates of the base object, dereference any alias
   * within the scope of the Search operation. Dereferenced objects become the
   * vertices of further search scopes where the Search operation is also
   * applied. If the search scope is {@code WHOLE_SUBTREE}, the Search continues
   * in the subtree(s) of any dereferenced object. If the search scope is
   * {@code SINGLE_LEVEL}, the search is applied to any dereferenced objects and
   * is not applied to their subordinates.
   */
  public static final DereferenceAliasesPolicy IN_SEARCHING = register(1,
      "search");
  /**
   * Dereference aliases in locating the base object of a Search operation, but
   * not when searching subordinates of the base object.
   */
  public static final DereferenceAliasesPolicy FINDING_BASE = register(2,
      "find");
  /**
   * Dereference aliases both in searching and in locating the base object of a
   * Search operation.
   */
  public static final DereferenceAliasesPolicy ALWAYS = register(3, "always");
  /**
   * Returns the alias dereferencing policy having the specified integer value
   * as defined in RFC 4511 section 4.5.1.
   *
   * @param intValue
   *          The integer value of the alias dereferencing policy.
   * @return The dereference aliases policy, or {@code null} if there was no
   *         alias dereferencing policy associated with {@code intValue}.
   */
  public static DereferenceAliasesPolicy valueOf(final int intValue)
  {
    if (intValue < 0 || intValue >= ELEMENTS.length)
    {
      return null;
    }
    return ELEMENTS[intValue];
  }
  /**
   * Returns an unmodifiable list containing the set of available alias
   * dereferencing policies indexed on their integer value as defined in RFC
   * 4511 section 4.5.1.
   *
   * @return An unmodifiable list containing the set of available alias
   *         dereferencing policies.
   */
  public static List<DereferenceAliasesPolicy> values()
  {
    return IMMUTABLE_ELEMENTS;
  }
  /**
   * Creates and registers a new alias dereferencing policy with the
   * application.
   *
   * @param intValue
   *          The integer value of the alias dereferencing policy as defined in
   *          RFC 4511 section 4.5.1.
   * @param name
   *          The name of the alias dereferencing policy.
   * @return The new alias dereferencing policy.
   */
  private static DereferenceAliasesPolicy register(final int intValue,
      final String name)
  {
    final DereferenceAliasesPolicy t = new DereferenceAliasesPolicy(intValue,
        name);
    ELEMENTS[intValue] = t;
    return t;
  }
  private final int intValue;
  private final String name;
  // Prevent direct instantiation.
  private DereferenceAliasesPolicy(final int intValue, final String name)
  {
    this.intValue = intValue;
    this.name = name;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean equals(final Object obj)
  {
    if (this == obj)
    {
      return true;
    }
    else if (obj instanceof DereferenceAliasesPolicy)
    {
      return this.intValue == ((DereferenceAliasesPolicy) obj).intValue;
    }
    else
    {
      return false;
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int hashCode()
  {
    return intValue;
  }
  /**
   * Returns the integer value of this alias dereferencing policy as defined in
   * RFC 4511 section 4.5.1.
   *
   * @return The integer value of this alias dereferencing policy.
   */
  public int intValue()
  {
    return intValue;
  }
  /**
   * Returns the string representation of this alias dereferencing policy.
   *
   * @return The string representation of this alias dereferencing policy.
   */
  @Override
  public String toString()
  {
    return name;
  }
}
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/Entries.java
New file
@@ -0,0 +1,516 @@
/*
 * 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 2010 Sun Microsystems, Inc.
 */
package org.forgerock.opendj.ldap;
import java.util.Collection;
import java.util.Iterator;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.forgerock.opendj.ldap.requests.ModifyRequest;
import org.forgerock.opendj.ldap.requests.Requests;
import com.forgerock.opendj.util.Function;
import com.forgerock.opendj.util.Iterables;
import com.forgerock.opendj.util.Validator;
/**
 * This class contains methods for creating and manipulating entries.
 *
 * @see Entry
 */
public final class Entries
{
  private static final class UnmodifiableEntry implements Entry
  {
    private final Entry entry;
    private UnmodifiableEntry(final Entry entry)
    {
      this.entry = entry;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean addAttribute(final Attribute attribute)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean addAttribute(final Attribute attribute,
        final Collection<ByteString> duplicateValues)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Entry addAttribute(final String attributeDescription,
        final Object... values) throws LocalizedIllegalArgumentException,
        UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    @Override
    public Entry clearAttributes() throws UnsupportedOperationException
    {
      throw new UnsupportedOperationException();
    }
    @Override
    public boolean containsAttribute(final Attribute attribute,
        final Collection<ByteString> missingValues) throws NullPointerException
    {
      return entry.containsAttribute(attribute, missingValues);
    }
    @Override
    public boolean containsAttribute(final String attributeDescription,
        final Object... values) throws LocalizedIllegalArgumentException,
        NullPointerException
    {
      return entry.containsAttribute(attributeDescription, values);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(final Object object)
    {
      return (object == this || entry.equals(object));
    }
    @Override
    public Iterable<Attribute> getAllAttributes()
    {
      return Iterables.unmodifiableIterable(Iterables.transformedIterable(
          entry.getAllAttributes(), UNMODIFIABLE_ATTRIBUTE_FUNCTION));
    }
    @Override
    public Iterable<Attribute> getAllAttributes(
        final AttributeDescription attributeDescription)
    {
      return Iterables.unmodifiableIterable(Iterables.transformedIterable(
          entry.getAllAttributes(attributeDescription),
          UNMODIFIABLE_ATTRIBUTE_FUNCTION));
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Iterable<Attribute> getAllAttributes(
        final String attributeDescription)
        throws LocalizedIllegalArgumentException, NullPointerException
    {
      return Iterables.unmodifiableIterable(Iterables.transformedIterable(
          entry.getAllAttributes(attributeDescription),
          UNMODIFIABLE_ATTRIBUTE_FUNCTION));
    }
    @Override
    public Attribute getAttribute(
        final AttributeDescription attributeDescription)
    {
      final Attribute attribute = entry.getAttribute(attributeDescription);
      if (attribute != null)
      {
        return Attributes.unmodifiableAttribute(attribute);
      }
      else
      {
        return null;
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Attribute getAttribute(final String attributeDescription)
        throws LocalizedIllegalArgumentException, NullPointerException
    {
      final Attribute attribute = entry.getAttribute(attributeDescription);
      if (attribute != null)
      {
        return Attributes.unmodifiableAttribute(attribute);
      }
      else
      {
        return null;
      }
    }
    @Override
    public int getAttributeCount()
    {
      return entry.getAttributeCount();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public DN getName()
    {
      return entry.getName();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode()
    {
      return entry.hashCode();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean removeAttribute(final Attribute attribute,
        final Collection<ByteString> missingValues)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    @Override
    public boolean removeAttribute(
        final AttributeDescription attributeDescription)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Entry removeAttribute(final String attributeDescription,
        final Object... values) throws LocalizedIllegalArgumentException,
        UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean replaceAttribute(final Attribute attribute)
        throws UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Entry replaceAttribute(final String attributeDescription,
        final Object... values) throws LocalizedIllegalArgumentException,
        UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    @Override
    public Entry setName(final DN dn) throws UnsupportedOperationException,
        NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Entry setName(final String dn)
        throws LocalizedIllegalArgumentException,
        UnsupportedOperationException, NullPointerException
    {
      throw new UnsupportedOperationException();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String toString()
    {
      return entry.toString();
    }
  }
  private static final Function<Attribute, Attribute, Void> UNMODIFIABLE_ATTRIBUTE_FUNCTION =
    new Function<Attribute, Attribute, Void>()
  {
    @Override
    public Attribute apply(final Attribute value, final Void p)
    {
      return Attributes.unmodifiableAttribute(value);
    }
  };
  /**
   * Creates a new modify request containing a list of modifications which can
   * be used to transform {@code fromEntry} into entry {@code toEntry}.
   * <p>
   * The modify request is reversible: it will contain only modifications of
   * type {@link ModificationType#ADD ADD} and {@link ModificationType#DELETE
   * DELETE}.
   * <p>
   * Finally, the modify request will use the distinguished name taken from
   * {@code fromEntry}. Moreover, this method will not check to see if both
   * {@code fromEntry} and {@code toEntry} have the same distinguished name.
   * <p>
   * This method is equivalent to:
   *
   * <pre>
   * ModifyRequest request = Requests.newModifyRequest(fromEntry, toEntry);
   * </pre>
   *
   * @param fromEntry
   *          The source entry.
   * @param toEntry
   *          The destination entry.
   * @return A modify request containing a list of modifications which can be
   *         used to transform {@code fromEntry} into entry {@code toEntry}.
   * @throws NullPointerException
   *           If {@code fromEntry} or {@code toEntry} were {@code null}.
   * @see Requests#newModifyRequest(Entry, Entry)
   */
  public static final ModifyRequest diffEntries(final Entry fromEntry,
      final Entry toEntry) throws NullPointerException
  {
    Validator.ensureNotNull(fromEntry, toEntry);
    final ModifyRequest request = Requests
        .newModifyRequest(fromEntry.getName());
    TreeMapEntry tfrom;
    if (fromEntry instanceof TreeMapEntry)
    {
      tfrom = (TreeMapEntry) fromEntry;
    }
    else
    {
      tfrom = new TreeMapEntry(fromEntry);
    }
    TreeMapEntry tto;
    if (toEntry instanceof TreeMapEntry)
    {
      tto = (TreeMapEntry) toEntry;
    }
    else
    {
      tto = new TreeMapEntry(toEntry);
    }
    final Iterator<Attribute> ifrom = tfrom.getAllAttributes().iterator();
    final Iterator<Attribute> ito = tto.getAllAttributes().iterator();
    Attribute afrom = ifrom.hasNext() ? ifrom.next() : null;
    Attribute ato = ito.hasNext() ? ito.next() : null;
    while (afrom != null && ato != null)
    {
      final AttributeDescription adfrom = afrom.getAttributeDescription();
      final AttributeDescription adto = ato.getAttributeDescription();
      final int cmp = adfrom.compareTo(adto);
      if (cmp == 0)
      {
        // Attribute is in both entries. Compute the set of values to be added
        // and removed. We won't replace the attribute because this is not
        // reversible.
        final Attribute addedValues = new LinkedAttribute(ato);
        addedValues.removeAll(afrom);
        if (!addedValues.isEmpty())
        {
          request.addModification(new Modification(ModificationType.ADD,
              addedValues));
        }
        final Attribute deletedValues = new LinkedAttribute(afrom);
        deletedValues.removeAll(ato);
        if (!deletedValues.isEmpty())
        {
          request.addModification(new Modification(ModificationType.DELETE,
              deletedValues));
        }
        afrom = ifrom.hasNext() ? ifrom.next() : null;
        ato = ito.hasNext() ? ito.next() : null;
      }
      else if (cmp < 0)
      {
        // afrom in source, but not destination.
        request
            .addModification(new Modification(ModificationType.DELETE, afrom));
        afrom = ifrom.hasNext() ? ifrom.next() : null;
      }
      else
      {
        // ato in destination, but not in source.
        request.addModification(new Modification(ModificationType.ADD, ato));
        ato = ito.hasNext() ? ito.next() : null;
      }
    }
    // Additional attributes in source entry: these must be deleted.
    if (afrom != null)
    {
      request.addModification(new Modification(ModificationType.DELETE, afrom));
    }
    while (ifrom.hasNext())
    {
      final Attribute a = ifrom.next();
      request.addModification(new Modification(ModificationType.DELETE, a));
    }
    // Additional attributes in destination entry: these must be added.
    if (ato != null)
    {
      request.addModification(new Modification(ModificationType.ADD, ato));
    }
    while (ito.hasNext())
    {
      final Attribute a = ito.next();
      request.addModification(new Modification(ModificationType.ADD, a));
    }
    return request;
  }
  /**
   * Returns a read-only view of {@code entry} and its attributes. Query
   * operations on the returned entry and its attributes "read-through" to the
   * underlying entry or attribute, and attempts to modify the returned entry
   * and its attributes either directly or indirectly via an iterator result in
   * an {@code UnsupportedOperationException}.
   *
   * @param entry
   *          The entry for which a read-only view is to be returned.
   * @return A read-only view of {@code entry}.
   * @throws NullPointerException
   *           If {@code entry} was {@code null}.
   */
  public static final Entry unmodifiableEntry(final Entry entry)
      throws NullPointerException
  {
    return new UnmodifiableEntry(entry);
  }
  // Prevent instantiation.
  private Entries()
  {
    // Nothing to do.
  }
}
Diff truncated after the above file
opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/Entry.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/EntryFactory.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/EntryNotFoundException.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ErrorResultException.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ErrorResultIOException.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/FailoverLoadBalancingAlgorithm.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/Filter.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/FilterVisitor.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/FutureResult.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/IntermediateResponseHandler.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/InternalConnectionFactory.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/KeyManagers.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPClientContext.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListener.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListenerOptions.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPOptions.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPUrl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/LinkedAttribute.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/LinkedHashMapEntry.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/LoadBalancer.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/LoadBalancingAlgorithm.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/Matcher.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/Modification.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ModificationType.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/MultipleEntriesFoundException.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/RDN.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ReferralException.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandler.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ResultCode.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ResultHandler.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/RootDSE.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/RoundRobinLoadBalancingAlgorithm.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/SSLContextBuilder.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/SchemaResolver.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/SearchResultHandler.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/SearchResultReferenceIOException.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/SearchScope.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ServerConnection.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/ServerConnectionFactory.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/SortKey.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/SynchronousConnection.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/TimeoutResultException.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/TreeMapEntry.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/TrustManagers.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/AssertionRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/AuthorizationIdentityRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/AuthorizationIdentityResponseControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/Control.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/ControlDecoder.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/EntryChangeNotificationResponseControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/GenericControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/GetEffectiveRightsRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/ManageDsaITRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/MatchedValuesRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PasswordExpiredResponseControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PasswordExpiringResponseControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyErrorType.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyResponseControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyWarningType.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PermissiveModifyRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PersistentSearchChangeType.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PersistentSearchRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PostReadRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PostReadResponseControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PreReadRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/PreReadResponseControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/ProxiedAuthV1RequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/ProxiedAuthV2RequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/ServerSideSortRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/ServerSideSortResponseControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/SimplePagedResultsControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/SubentriesRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/SubtreeDeleteRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/VirtualListViewRequestControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/VirtualListViewResponseControl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/controls/package-info.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/package-info.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AbandonRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AbandonRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AbstractBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AbstractExtendedRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AbstractRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AbstractSASLBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableExtendedRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableSASLBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AddRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AddRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AnonymousSASLBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/AnonymousSASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/BindClient.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/BindClientImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/BindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/CancelExtendedRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/CancelExtendedRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/CompareRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/CompareRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/DeleteRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/DeleteRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ExtendedRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ExtendedRequestDecoder.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/GenericBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/GenericBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/GenericExtendedRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/GenericExtendedRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ModifyDNRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ModifyDNRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ModifyRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ModifyRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/PasswordModifyExtendedRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/PasswordModifyExtendedRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/Request.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/Requests.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/SASLBindClientImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/SASLBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/SearchRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/SearchRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/SimpleBindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/SimpleBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/StartTLSExtendedRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/StartTLSExtendedRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnbindRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnbindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableAbandonRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableAddRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableAnonymousSASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableCRAMMD5SASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableCancelExtendedRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableCompareRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableDeleteRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableDigestMD5SASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableExternalSASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableGSSAPISASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableGenericBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableGenericExtendedRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableModifyDNRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableModifyRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiablePasswordModifyExtendedRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiablePlainSASLBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableSearchRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableSimpleBindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableStartTLSExtendedRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableUnbindRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableWhoAmIExtendedRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/WhoAmIExtendedRequest.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/WhoAmIExtendedRequestImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/requests/package-info.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractExtendedResult.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractExtendedResultDecoder.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractIntermediateResponse.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractResponseImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableExtendedResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableIntermediateResponseImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableResponseImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/BindResult.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/BindResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/CompareResult.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/CompareResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/ExtendedResult.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/ExtendedResultDecoder.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/GenericExtendedResult.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/GenericExtendedResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/GenericIntermediateResponse.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/GenericIntermediateResponseImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/IntermediateResponse.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/PasswordModifyExtendedResult.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/PasswordModifyExtendedResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/Response.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/Responses.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/Result.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/ResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultEntry.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultEntryImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultReference.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultReferenceImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableBindResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableCompareResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableGenericExtendedResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableGenericIntermediateResponseImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiablePasswordModifyExtendedResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableSearchResultEntryImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableSearchResultReferenceImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableWhoAmIExtendedResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/WhoAmIExtendedResult.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/WhoAmIExtendedResultImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/responses/package-info.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AbstractMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AbstractOrderingMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AbstractSubstringMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AbstractSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AttributeUsage.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AuthPasswordExactEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/AuthPasswordSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/BinarySyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/BitStringEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/BitStringSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/BooleanEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/BooleanSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactIA5EqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactIA5SubstringMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactOrderingMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactSubstringMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5EqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5SubstringMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreListEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreListSubstringMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreOrderingMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreSubstringMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CertificateListSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CertificatePairSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CertificateSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ConflictingSchemaElementException.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchema.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/CountryStringSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRule.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRule.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRuleSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DeliveryMethodSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DirectoryStringFirstComponentEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DirectoryStringSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/DoubleMetaphoneApproximateMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/EnhancedGuideSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/EnumOrderingMatchingRule.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/EnumSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/EqualLengthApproximateMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/FacsimileNumberSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/FaxSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeOrderingMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/GenerateCoreSchema.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/GuideSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/IA5StringSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/IntegerEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/IntegerFirstComponentEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/IntegerOrderingMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/IntegerSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/JPEGSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/KeywordEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxDescriptionSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUse.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NameAndOptionalUIDSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NameFormSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringOrderingMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringSubstringMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/OIDSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClass.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClassSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClassType.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierFirstComponentEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringOrderingMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringSubstringMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/OtherMailboxSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/PostalAddressSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/PresentationAddressEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/PresentationAddressSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/PrintableStringSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ProtocolInformationEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/ProtocolInformationSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/RegexSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaCompatOptions.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaConstants.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaElement.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaException.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SubstringAssertionSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SupportedAlgorithmSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/TelephoneNumberEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/TelephoneNumberSubstringMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/TelephoneNumberSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/TeletexTerminalIdentifierSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/TelexNumberSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/UUIDEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/UUIDOrderingMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/UUIDSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/UniqueMemberEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/UnknownSchemaElementException.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/UserPasswordExactEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/UserPasswordSyntaxImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/WordEqualityMatchingRuleImpl.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldap/schema/package-info.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFStream.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFWriter.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/ChangeRecord.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/ChangeRecordReader.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/ChangeRecordVisitor.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/ChangeRecordVisitorWriter.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/ChangeRecordWriter.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionChangeRecordWriter.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryWriter.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/EntryReader.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/EntryWriter.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/LDIFChangeRecordReader.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/LDIFChangeRecordWriter.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/LDIFEntryReader.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/LDIFEntryWriter.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/forgerock/opendj/ldif/package-info.java opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AVA.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AbstractAsynchronousConnection.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AbstractAttribute.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AbstractConnection.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AbstractConnectionFactory.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AbstractEntry.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AbstractFilterVisitor.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AbstractLoadBalancingAlgorithm.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AbstractMapEntry.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/Assertion.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AssertionFailureException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AsynchronousConnection.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/Attribute.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AttributeDescription.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AttributeFactory.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/Attributes.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AuthenticatedConnectionFactory.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AuthenticationException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/AuthorizationException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ByteSequence.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ByteSequenceReader.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ByteString.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ByteStringBuilder.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/CancelledResultException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ConditionResult.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/Connection.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ConnectionEventListener.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ConnectionException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ConnectionFactory.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ConnectionPool.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ConnectionSecurityLayer.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/Connections.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ConstraintViolationException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/DN.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/DecodeException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/DecodeOptions.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/DereferenceAliasesPolicy.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/Entries.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/Entry.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/EntryFactory.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/EntryNotFoundException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ErrorResultException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ErrorResultIOException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/FailoverLoadBalancingAlgorithm.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/Filter.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/FilterVisitor.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/FutureResult.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/HeartBeatConnectionFactory.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/IntermediateResponseHandler.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/InternalConnectionFactory.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/KeyManagers.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/LDAPClientContext.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/LDAPConnectionFactory.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/LDAPListener.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/LDAPListenerOptions.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/LDAPOptions.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/LDAPUrl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/LinkedAttribute.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/LinkedHashMapEntry.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/LoadBalancer.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/LoadBalancingAlgorithm.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/Matcher.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/Modification.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ModificationType.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/MultipleEntriesFoundException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/RDN.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ReferralException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/RequestHandler.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ResultCode.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ResultHandler.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/RootDSE.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/RoundRobinLoadBalancingAlgorithm.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/SSLContextBuilder.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/SchemaResolver.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/SearchResultHandler.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/SearchResultReferenceIOException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/SearchScope.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ServerConnection.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ServerConnectionFactory.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/SortKey.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/SynchronousConnection.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/TimeoutResultException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/TreeMapEntry.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/TrustManagers.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1ByteSequenceReader.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1Constants.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1InputStreamReader.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1OutputStreamWriter.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1Reader.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1Writer.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/asn1/AbstractASN1Reader.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/asn1/AbstractASN1Writer.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/asn1/package-info.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/AssertionRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/AuthorizationIdentityRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/AuthorizationIdentityResponseControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/Control.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/ControlDecoder.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/EntryChangeNotificationResponseControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/GenericControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/GetEffectiveRightsRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/ManageDsaITRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/MatchedValuesRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordExpiredResponseControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordExpiringResponseControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyErrorType.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyResponseControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyWarningType.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PermissiveModifyRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PersistentSearchChangeType.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PersistentSearchRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PostReadRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PostReadResponseControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PreReadRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/PreReadResponseControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/ProxiedAuthV1RequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/ProxiedAuthV2RequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/ServerSideSortRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/ServerSideSortResponseControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/SimplePagedResultsControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/SubentriesRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/SubtreeDeleteRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/VirtualListViewRequestControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/VirtualListViewResponseControl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/controls/package-info.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/AbstractLDIFReader.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/AbstractLDIFStream.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/AbstractLDIFWriter.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecord.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordReader.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordVisitor.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordVisitorWriter.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordWriter.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/ConnectionChangeRecordWriter.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/ConnectionEntryReader.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/ConnectionEntryWriter.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/EntryReader.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/EntryWriter.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFChangeRecordReader.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFChangeRecordWriter.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFEntryReader.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFEntryWriter.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/ldif/package-info.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/package-info.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AbandonRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AbandonRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractExtendedRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractSASLBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableExtendedRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableSASLBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AddRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AddRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AnonymousSASLBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/AnonymousSASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/BindClient.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/BindClientImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/BindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/CRAMMD5SASLBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/CRAMMD5SASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/CancelExtendedRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/CancelExtendedRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/CompareRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/CompareRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/DeleteRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/DeleteRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/DigestMD5SASLBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/ExtendedRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/ExtendedRequestDecoder.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/ExternalSASLBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/ExternalSASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/GSSAPISASLBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/GSSAPISASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericExtendedRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericExtendedRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyDNRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyDNRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/PasswordModifyExtendedRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/PasswordModifyExtendedRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/PlainSASLBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/PlainSASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/Request.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/Requests.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/SASLBindClientImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/SASLBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/SearchRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/SearchRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/SimpleBindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/SimpleBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/StartTLSExtendedRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/StartTLSExtendedRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnbindRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnbindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableAbandonRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableAddRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableAnonymousSASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableCRAMMD5SASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableCancelExtendedRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableCompareRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableDeleteRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableDigestMD5SASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableExternalSASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableGSSAPISASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableGenericBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableGenericExtendedRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableModifyDNRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableModifyRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiablePasswordModifyExtendedRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiablePlainSASLBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableSearchRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableSimpleBindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableStartTLSExtendedRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableUnbindRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableWhoAmIExtendedRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/WhoAmIExtendedRequest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/WhoAmIExtendedRequestImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/requests/package-info.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractExtendedResult.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractExtendedResultDecoder.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractIntermediateResponse.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractResponseImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableExtendedResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableIntermediateResponseImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableResponseImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/BindResult.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/BindResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/CompareResult.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/CompareResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/ExtendedResult.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/ExtendedResultDecoder.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericExtendedResult.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericExtendedResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericIntermediateResponse.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericIntermediateResponseImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/IntermediateResponse.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/PasswordModifyExtendedResult.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/PasswordModifyExtendedResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/Response.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/Responses.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/Result.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/ResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultEntry.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultEntryImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultReference.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultReferenceImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableBindResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableCompareResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableGenericExtendedResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableGenericIntermediateResponseImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiablePasswordModifyExtendedResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableSearchResultEntryImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableSearchResultReferenceImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableWhoAmIExtendedResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/WhoAmIExtendedResult.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/WhoAmIExtendedResultImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/responses/package-info.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractOrderingMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractSubstringMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/AttributeType.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/AttributeTypeSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/AttributeUsage.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/AuthPasswordExactEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/AuthPasswordSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/BinarySyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/BitStringEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/BitStringSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/BooleanEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/BooleanSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactIA5EqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactIA5SubstringMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactOrderingMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactSubstringMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreIA5EqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreIA5SubstringMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreListEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreListSubstringMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreOrderingMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreSubstringMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CertificateListSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CertificatePairSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CertificateSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/ConflictingSchemaElementException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CoreSchema.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CoreSchemaImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/CountryStringSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/DITContentRule.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/DITContentRuleSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/DITStructureRule.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/DITStructureRuleSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/DeliveryMethodSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/DirectoryStringFirstComponentEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/DirectoryStringSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/DistinguishedNameEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/DistinguishedNameSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/DoubleMetaphoneApproximateMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/EnhancedGuideSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/EnumOrderingMatchingRule.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/EnumSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/EqualLengthApproximateMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/FacsimileNumberSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/FaxSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/GeneralizedTimeEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/GeneralizedTimeOrderingMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/GeneralizedTimeSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/GenerateCoreSchema.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/GuideSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/IA5StringSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerFirstComponentEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerOrderingMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/JPEGSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/KeywordEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/LDAPSyntaxDescriptionSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRule.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleUse.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleUseSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/NameAndOptionalUIDSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/NameForm.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/NameFormSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringOrderingMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringSubstringMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/OIDSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectClass.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectClassSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectClassType.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectIdentifierEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectIdentifierFirstComponentEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringOrderingMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringSubstringMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/OtherMailboxSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/PostalAddressSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/PresentationAddressEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/PresentationAddressSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/PrintableStringSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/ProtocolInformationEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/ProtocolInformationSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/RegexSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/Schema.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaBuilder.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaCompatOptions.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaConstants.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaElement.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaUtils.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/SubstringAssertionSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/SupportedAlgorithmSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/Syntax.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/SyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/TelephoneNumberEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/TelephoneNumberSubstringMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/TelephoneNumberSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/TeletexTerminalIdentifierSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/TelexNumberSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/UTCTimeSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/UUIDEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/UUIDOrderingMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/UUIDSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/UniqueMemberEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/UnknownSchemaElementException.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/UserPasswordExactEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/UserPasswordSyntaxImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/WordEqualityMatchingRuleImpl.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/java/org/opends/sdk/schema/package-info.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/main/javadoc/overview.html opendj-sdk/opendj3/opendj-sdk/src/main/resources/org/forgerock/opendj/ldap/core.properties opendj-sdk/opendj3/opendj-sdk/src/main/resources/org/forgerock/opendj/ldap/core_de.properties opendj-sdk/opendj3/opendj-sdk/src/main/resources/org/forgerock/opendj/ldap/core_es.properties opendj-sdk/opendj3/opendj-sdk/src/main/resources/org/forgerock/opendj/ldap/core_fr.properties opendj-sdk/opendj3/opendj-sdk/src/main/resources/org/forgerock/opendj/ldap/core_ja.properties opendj-sdk/opendj3/opendj-sdk/src/main/resources/org/forgerock/opendj/ldap/core_ko.properties opendj-sdk/opendj3/opendj-sdk/src/main/resources/org/forgerock/opendj/ldap/core_zh_CN.properties opendj-sdk/opendj3/opendj-sdk/src/main/resources/org/forgerock/opendj/ldap/core_zh_TW.properties opendj-sdk/opendj3/opendj-sdk/src/test/java/com/forgerock/opendj/ldap/ASN1BufferReaderTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/com/forgerock/opendj/ldap/ASN1BufferWriterTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/com/forgerock/opendj/ldap/controls/AccountUsabilityRequestControlTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/com/forgerock/opendj/ldap/controls/AccountUsabilityResponseControlTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/com/forgerock/opendj/util/Base64TestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/com/forgerock/opendj/util/StringPrepProfileTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/com/forgerock/opendj/util/UtilTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/asn1/ASN1ByteSequenceReaderTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/asn1/ASN1InputStreamReaderTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/asn1/ASN1OutputStreamWriterTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/asn1/ASN1ReaderTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/asn1/ASN1WriterTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/AttributeDescriptionTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/ByteSequenceTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/ByteStringBuilderTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/ByteStringTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionFactoryTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/DNTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/EntriesTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/EntryTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/FilterTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPUrlTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/LinkedAttributeTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/SdkTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/SynchronousConnectionTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/TypesTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/controls/ControlsTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/AbandonRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/AddRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/AnonymousSASLBindRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/BindRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/CompareRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/DeleteRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/ExtendedRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/GenericBindRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/ModifyDNRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/ModifyRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/RequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/RequestsTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/SimpleBindRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/requests/UnbindRequestTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/responses/ResponsesTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSchemaElementTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/ApproximateMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/BitStringEqualityMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/BitStringSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/BooleanEqualityMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactEqualityMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactIA5EqualityMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactIA5SubstringMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactOrderingMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactSubstringMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreEqualityMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5EqualityMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5SubstringMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreOrderingMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreSubstringMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/CoreSchemaTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/EnumSyntaxTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/GuideSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/IA5StringSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/OrderingMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/OtherMailboxSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/RegexSyntaxTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/SchemaBuilderTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/SchemaTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/SchemaUtilsTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/SubstitutionSyntaxTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/SubstringMatchingRuleTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/SyntaxTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/TelexSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldap/schema/UUIDSyntaxTest.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldif/LDIFEntryReaderTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldif/LDIFEntryWriterTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/forgerock/opendj/ldif/LDIFTestCase.java opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/AttributeDescriptionTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/ByteSequenceTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/ByteStringBuilderTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/ByteStringTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/ConnectionFactoryTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/DNTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/EntriesTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/EntryTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/FilterTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/LDAPListenerTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/LDAPServer.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/LDAPUrlTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/LinkedAttributeTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/RDNTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/SdkTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/SynchronousConnectionTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/TestCaseUtils.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/TypesTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1ByteSequenceReaderTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1InputStreamReaderTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1OutputStreamWriterTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1ReaderTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1WriterTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/controls/ControlsTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/ldif/LDIFEntryReaderTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/ldif/LDIFEntryWriterTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/ldif/LDIFTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/AbandonRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/AddRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/AnonymousSASLBindRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/BindRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/CRAMMD5SASLBindRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/CompareRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/DeleteRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/DigestMD5SASLBindRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/ExtendedRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/ExternalSASLBindRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/GSSAPISASLBindRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/GenericBindRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/ModifyDNRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/ModifyRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/PlainSASLBindRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/RequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/RequestsTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/SimpleBindRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/requests/UnbindRequestTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/responses/ResponsesTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/AbstractSchemaElementTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/ApproximateMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/AttributeTypeSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/AttributeTypeTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/BitStringEqualityMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/BitStringSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/BooleanEqualityMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactEqualityMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactIA5EqualityMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactIA5SubstringMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactOrderingMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactSubstringMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreEqualityMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreIA5EqualityMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreIA5SubstringMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreOrderingMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreSubstringMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/CoreSchemaTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/DITContentRuleSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/DistinguishedNameEqualityMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/EnumSyntaxTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/GeneralizedTimeSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/GuideSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/IA5StringSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/LDAPSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/MatchingRuleSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/MatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/MatchingRuleUseSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/OrderingMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/OtherMailboxSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/RegexSyntaxTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/SchemaBuilderTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/SchemaTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/SchemaUtilsTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/SubstitutionSyntaxTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/SubstringMatchingRuleTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/SyntaxTestCase.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/TelexSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/UTCTimeSyntaxTest.java (deleted) opendj-sdk/opendj3/opendj-sdk/src/test/java/org/opends/sdk/schema/UUIDSyntaxTest.java (deleted)