/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 * 
 */
package org.apache.directory.api.ldap.codec.search;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.directory.api.asn1.DecoderException;
import org.apache.directory.api.asn1.EncoderException;
import org.apache.directory.api.asn1.ber.Asn1Decoder;
import org.apache.directory.api.asn1.ber.tlv.TLVStateEnum;
import org.apache.directory.api.ldap.codec.api.LdapMessageContainer;
import org.apache.directory.api.ldap.codec.api.ResponseCarryingException;
import org.apache.directory.api.ldap.codec.controls.search.subentries.SubentriesDecorator;
import org.apache.directory.api.ldap.codec.decorators.SearchRequestDecorator;
import org.apache.directory.api.ldap.codec.osgi.AbstractCodecServiceTest;
import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.filter.AndNode;
import org.apache.directory.api.ldap.model.filter.ApproximateNode;
import org.apache.directory.api.ldap.model.filter.EqualityNode;
import org.apache.directory.api.ldap.model.filter.ExprNode;
import org.apache.directory.api.ldap.model.filter.GreaterEqNode;
import org.apache.directory.api.ldap.model.filter.LessEqNode;
import org.apache.directory.api.ldap.model.filter.NotNode;
import org.apache.directory.api.ldap.model.filter.OrNode;
import org.apache.directory.api.ldap.model.filter.PresenceNode;
import org.apache.directory.api.ldap.model.filter.SubstringNode;
import org.apache.directory.api.ldap.model.message.AliasDerefMode;
import org.apache.directory.api.ldap.model.message.Control;
import org.apache.directory.api.ldap.model.message.Message;
import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
import org.apache.directory.api.ldap.model.message.SearchRequest;
import org.apache.directory.api.ldap.model.message.SearchResultDoneImpl;
import org.apache.directory.api.ldap.model.message.SearchScope;
import org.apache.directory.api.ldap.model.schema.normalizers.DeepTrimToLowerNormalizer;
import org.apache.directory.api.ldap.model.schema.normalizers.OidNormalizer;
import org.apache.directory.api.util.Strings;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.mycila.junit.concurrent.Concurrency;
import com.mycila.junit.concurrent.ConcurrentJunitRunner;


/**
 * A test case for SearchRequest messages
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
@RunWith(ConcurrentJunitRunner.class)
@Concurrency()
public class SearchRequestTest extends AbstractCodecServiceTest
{
    /** An oid normalizer map */
    static Map<String, OidNormalizer> oids = new HashMap<String, OidNormalizer>();


    @Before
    public void setUp() throws Exception
    {
        // DC normalizer
        OidNormalizer dcOidNormalizer = new OidNormalizer( "dc", new DeepTrimToLowerNormalizer(
            SchemaConstants.DOMAIN_COMPONENT_AT_OID ) );

        oids.put( "dc", dcOidNormalizer );
        oids.put( "domaincomponent", dcOidNormalizer );
        oids.put( "0.9.2342.19200300.100.1.25", dcOidNormalizer );

        // OU normalizer
        OidNormalizer ouOidNormalizer = new OidNormalizer( "ou", new DeepTrimToLowerNormalizer(
            SchemaConstants.OU_AT_OID ) );

        oids.put( "ou", ouOidNormalizer );
        oids.put( "organizationalUnitName", ouOidNormalizer );
        oids.put( "2.5.4.11", ouOidNormalizer );

        // ObjectClass normalizer
        OidNormalizer objectClassOidNormalizer = new OidNormalizer( "objectClass", new DeepTrimToLowerNormalizer(
            SchemaConstants.OBJECT_CLASS_AT_OID ) );

        oids.put( "objectclass", objectClassOidNormalizer );
        oids.put( "2.5.4.0", objectClassOidNormalizer );
    }


    /**
     * Test the decoding of a SearchRequest with no controls. The search filter
     * is : (&(|(objectclass=top)(ou=contacts))(!(objectclass=ttt)))
     */
    @Test
    public void testDecodeSearchRequestGlobalNoControls()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x90 );
        stream.put( new byte[]
            { 0x30, ( byte ) 0x81,
                ( byte ) 0x8D, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                ( byte ) 0x81,
                ( byte ) 0x87, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // sizeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF, // typesOnly  BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x3C, // Filter ::= CHOICE {
                // and [0] SET OF Filter,
                ( byte ) 0xA1,
                0x24, // or [1] SET of Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3]
                // Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                'o',
                'p',
                ( byte ) 0xA3,
                0x0E, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x02,
                'o',
                'u', // attributeDesc AttributeDescription (LDAPString),
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x08,
                'c',
                'o',
                'n',
                't',
                'a',
                'c',
                't',
                's',
                ( byte ) 0xA2,
                0x14, // not [2] Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                't',
                't',
                // attributes AttributeDescriptionList }
                0x30,
                0x15, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '0', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '1', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '2' // AttributeDescription ::= LDAPString
        } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 1000, searchRequest.getSizeLimit() );
        assertEquals( 1000, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (& (...
        ExprNode node = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) node;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();

        // (& (| (...
        assertEquals( 2, andNodes.size() );
        OrNode orFilter = ( OrNode ) andNodes.get( 0 );
        assertNotNull( orFilter );

        // (& (| (obectclass=top) (...
        List<ExprNode> orNodes = orFilter.getChildren();
        assertEquals( 2, orNodes.size() );
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) orNodes.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "objectclass", equalityNode.getAttribute() );
        assertEquals( "top", equalityNode.getValue().getString() );

        // (& (| (objectclass=top) (ou=contacts) ) (...
        equalityNode = ( EqualityNode<?> ) orNodes.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "ou", equalityNode.getAttribute() );
        assertEquals( "contacts", equalityNode.getValue().getString() );

        // (& (| (objectclass=top) (ou=contacts) ) (! ...
        NotNode notNode = ( NotNode ) andNodes.get( 1 );
        assertNotNull( notNode );

        // (& (| (objectclass=top) (ou=contacts) ) (! (objectclass=ttt) ) )
        equalityNode = ( EqualityNode<?> ) notNode.getFirstChild();
        assertNotNull( equalityNode );

        assertEquals( "objectclass", equalityNode.getAttribute() );
        assertEquals( "ttt", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();

        for ( String attribute : attributes )
        {
            assertNotNull( attribute );
        }

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x90, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x81 ), decodedPdu.substring( 0, 0x81 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest with no controls. Test the various
     * types of filter : >=, <=, ~= The search filter is :
     * (&(|(objectclass~=top)(ou<=contacts))(!(objectclass>=ttt)))
     */
    @Test
    public void testDecodeSearchRequestCompareFiltersNoControls()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x90 );
        stream.put( new byte[]
            { 0x30, ( byte ) 0x81,
                ( byte ) 0x8D, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, //     messageID MessageID
                0x63,
                ( byte ) 0x81,
                ( byte ) 0x87, //     CHOICE { ...,
                //         searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x1F, //     baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01, //     scope ENUMERATED {
                //         baseObject   (0),
                //         singleLevel  (1),
                //         wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, //     derefAliases ENUMERATED {
                //         neverDerefAliases (0),
                //         derefInSearching (1),
                //         derefFindingBaseObj (2),
                //         derefAlways (3) },
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, //     sizeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, //     timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF, //     typesOnly BOOLEAN, (TRUE)
                //     filter Filter,
                ( byte ) 0xA0,
                0x3C, // Filter ::= CHOICE {
                //      and [0] SET OF Filter,
                ( byte ) 0xA1,
                0x24, //      or [1] SET of Filter,
                ( byte ) 0xA8,
                0x12, //      approxMatch [8]
                // Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x0B, // attributeDesc AttributeDescription (LDAPString),
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                0x04,
                0x03, // attributeDesc AttributeDescription (LDAPString),
                't',
                'o',
                'p',
                ( byte ) 0xA6,
                0x0E, // lessOrEqual [3] Assertion,
                0x04,
                0x02, // Assertion ::= SEQUENCE {
                'o',
                'u', // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x08, // assertionValue AssertionValue (OCTET STRING) }
                'c',
                'o',
                'n',
                't',
                'a',
                'c',
                't',
                's',
                ( byte ) 0xA2,
                0x14, // not [2] Filter,
                ( byte ) 0xA5,
                0x12, // greaterOrEqual [5] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x0B, // attributeDesc AttributeDescription (LDAPString),
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                0x04,
                0x03,
                't',
                't',
                't', // assertionValue AssertionValue (OCTET STRING) }
                // attributes AttributeDescriptionList }
                0x30,
                0x15, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '0', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '1', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '2' // AttributeDescription ::= LDAPString
        } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 1000, searchRequest.getSizeLimit() );
        assertEquals( 1000, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (& (...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();

        // (& (| (...
        assertEquals( 2, andNodes.size() );
        OrNode orFilter = ( OrNode ) andNodes.get( 0 );
        assertNotNull( orFilter );

        // (& (| (objectclass~=top) (...
        List<ExprNode> orNodes = orFilter.getChildren();
        assertEquals( 2, orNodes.size() );
        ApproximateNode<?> approxNode = ( ApproximateNode<?> ) orNodes.get( 0 );
        assertNotNull( approxNode );

        assertEquals( "objectclass", approxNode.getAttribute() );
        assertEquals( "top", approxNode.getValue().getString() );

        // (& (| (objectclass~=top) (ou<=contacts) ) (...
        LessEqNode<?> lessOrEqualNode = ( LessEqNode<?> ) orNodes.get( 1 );
        assertNotNull( lessOrEqualNode );

        assertEquals( "ou", lessOrEqualNode.getAttribute() );
        assertEquals( "contacts", lessOrEqualNode.getValue().getString() );

        // (& (| (objectclass~=top) (ou<=contacts) ) (! ...
        NotNode notNode = ( NotNode ) andNodes.get( 1 );
        assertNotNull( notNode );

        // (& (| (objectclass~=top) (ou<=contacts) ) (! (objectclass>=ttt) ) )
        GreaterEqNode<?> greaterOrEqual = ( GreaterEqNode<?> ) notNode.getFirstChild();
        assertNotNull( greaterOrEqual );

        assertEquals( "objectclass", greaterOrEqual.getAttribute() );
        assertEquals( "ttt", greaterOrEqual.getValue().getString() );

        // The attributes
        List<String> attributes = searchRequest.getAttributes();

        for ( String attribute : attributes )
        {
            assertNotNull( attribute );
        }

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x0090, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x81 ), decodedPdu.substring( 0, 0x81 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest with no controls. Test the present
     * filter : =* The search filter is :
     * (&(|(objectclass=*)(ou=*))(!(objectclass>=ttt)))
     */
    @Test
    public void testDecodeSearchRequestPresentNoControls()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x7B );
        stream.put( new byte[]
            { 0x30,
                0x79, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x74, // CHOICE { ..., searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01, // scope
                // ENUMERATED
                // {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                // sizeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8,
                // timeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8,
                0x01,
                0x01,
                ( byte ) 0xFF, // typesOnly
                // BOOLEAN,
                // (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x29, // Filter ::= CHOICE {
                // and [0] SET OF Filter,
                ( byte ) 0xA1,
                0x11, // or [1] SET of Filter,
                ( byte ) 0x87,
                0x0B, // present [7] AttributeDescription,
                // AttributeDescription ::= LDAPString
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                ( byte ) 0x87,
                0x02,
                'o',
                'u', // present [7]
                // AttributeDescription,
                // AttributeDescription ::= LDAPString
                ( byte ) 0xA2,
                0x14, // not [2] Filter,
                ( byte ) 0xA5,
                0x12, // greaterOrEqual [5]
                // Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                't',
                't',
                // attributes AttributeDescriptionList }
                0x30,
                0x15, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '0', // AttributeDescription
                // ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '1', // AttributeDescription
                // ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '2' // AttributeDescription ::=
            // LDAPString
        } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 1000, searchRequest.getSizeLimit() );
        assertEquals( 1000, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (& (...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();

        // (& (| (...
        assertEquals( 2, andNodes.size() );
        OrNode orFilter = ( OrNode ) andNodes.get( 0 );
        assertNotNull( orFilter );

        // (& (| (objectclass=*) (...
        List<ExprNode> orNodes = orFilter.getChildren();
        assertEquals( 2, orNodes.size() );

        PresenceNode presenceNode = ( PresenceNode ) orNodes.get( 0 );
        assertNotNull( presenceNode );

        assertEquals( "objectclass", presenceNode.getAttribute() );

        // (& (| (objectclass=*) (ou=*) ) (...
        presenceNode = ( PresenceNode ) orNodes.get( 1 );
        assertNotNull( presenceNode );

        assertEquals( "ou", presenceNode.getAttribute() );

        // (& (| (objectclass=*) (ou=*) ) (! ...
        NotNode notNode = ( NotNode ) andNodes.get( 1 );
        assertNotNull( notNode );

        // (& (| (objectclass=*) (ou=*) ) (! (objectclass>=ttt) ) )
        GreaterEqNode<?> greaterOrEqual = ( GreaterEqNode<?> ) notNode.getFirstChild();
        assertNotNull( greaterOrEqual );

        assertEquals( "objectclass", greaterOrEqual.getAttribute() );
        assertEquals( "ttt", greaterOrEqual.getValue().getString() );

        // The attributes
        List<String> attributes = searchRequest.getAttributes();

        for ( String attribute : attributes )
        {
            assertNotNull( attribute );
        }

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x7B, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x6C ), decodedPdu.substring( 0, 0x6C ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest with no attributes. The search
     * filter is : (objectclass=*)
     */
    @Test
    public void testDecodeSearchRequestNoAttributes()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x40 );
        stream.put( new byte[]
            { 0x30,
                0x37, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x03, // messageID MessageID
                0x63,
                0x32, // CHOICE { ..., searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x12, // baseObject LDAPDN,
                'o',
                'u',
                '=',
                'u',
                's',
                'e',
                'r',
                's',
                ',',
                'o',
                'u',
                '=',
                's',
                'y',
                's',
                't',
                'e',
                'm',
                0x0A,
                0x01,
                0x00, // scope ENUMERATED {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                // sizeLimit INTEGER (0 .. maxInt), (infinite)
                0x02,
                0x01,
                0x00,
                // timeLimit INTEGER (0 .. maxInt), (infinite)
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0x00, // typesOnly
                // BOOLEAN,
                // (FALSE)
                // filter Filter,
                // Filter ::= CHOICE {
                ( byte ) 0x87,
                0x0B, // present [7] AttributeDescription,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'C',
                'l',
                'a',
                's',
                's',
                // attributes AttributeDescriptionList }
                0x30,
                0x00, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x00,
                0x00, // Some trailing 00, useless.
                0x00,
                0x00,
                0x00,
                0x00 } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 3, searchRequest.getMessageId() );
        assertEquals( "ou=users,ou=system", searchRequest.getBase().toString() );
        assertEquals( SearchScope.OBJECT, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( false, searchRequest.getTypesOnly() );

        // (objectClass = *)
        ExprNode filter = searchRequest.getFilter();

        PresenceNode presenceNode = ( PresenceNode ) filter;
        assertNotNull( presenceNode );
        assertEquals( "objectClass", presenceNode.getAttribute() );

        // The attributes
        List<String> attributes = searchRequest.getAttributes();

        assertEquals( 0, attributes.size() );

        // Check the encoding
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x39, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu, decodedPdu.substring( 0, decodedPdu.length() - 35 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest with an empty attribute. The search
     * filter is : (objectclass=*)
     */
    @Test
    public void testDecodeSearchRequestOneEmptyAttribute()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x3F );
        stream.put( new byte[]
            { 0x30,
                0x3D, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x03, // messageID MessageID
                0x63,
                0x38, // CHOICE { ..., searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x12, // baseObject LDAPDN,
                'o',
                'u',
                '=',
                'u',
                's',
                'e',
                'r',
                's',
                ',',
                'o',
                'u',
                '=',
                's',
                'y',
                's',
                't',
                'e',
                'm',
                0x0A,
                0x01,
                0x00, // scope ENUMERATED {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                // sizeLimit INTEGER (0 .. maxInt), (infinite)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (infinite)
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                0x00, // typesOnly
                // BOOLEAN,
                // (FALSE)
                // filter Filter,
                // Filter ::= CHOICE {
                ( byte ) 0x87,
                0x0B, // present [7] AttributeDescription,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'C',
                'l',
                'a',
                's',
                's',
                // attributes AttributeDescriptionList }
                0x30,
                0x06, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x02, // Request for sn
                's',
                'n',
                0x04,
                0x00 // Empty attribute
        } );

        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 3, searchRequest.getMessageId() );
        assertEquals( "ou=users,ou=system", searchRequest.getBase().toString() );
        assertEquals( SearchScope.OBJECT, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( false, searchRequest.getTypesOnly() );

        // (objectClass = *)
        ExprNode filter = searchRequest.getFilter();

        PresenceNode presenceNode = ( PresenceNode ) filter;
        assertNotNull( presenceNode );
        assertEquals( "objectClass", presenceNode.getAttribute() );

        // The attributes
        List<String> attributes = searchRequest.getAttributes();

        assertEquals( 1, attributes.size() );
    }


    /**
     * Test the decoding of a SearchRequest with a star and an attribute. The search
     * filter is : (objectclass=*)
     */
    @Test
    public void testDecodeSearchRequestWithStarAndAttr()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x40 );
        stream.put( new byte[]
            { 0x30,
                0x3E, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x03, // messageID MessageID
                0x63,
                0x39, // CHOICE { ..., searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x12, // baseObject LDAPDN,
                'o',
                'u',
                '=',
                'u',
                's',
                'e',
                'r',
                's',
                ',',
                'o',
                'u',
                '=',
                's',
                'y',
                's',
                't',
                'e',
                'm',
                0x0A,
                0x01,
                0x00, // scope ENUMERATED {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                // sizeLimit INTEGER (0 .. maxInt), (infinite)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (infinite)
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                0x00, // typesOnly
                // BOOLEAN,
                // (FALSE)
                // filter Filter,
                // Filter ::= CHOICE {
                ( byte ) 0x87,
                0x0B, // present [7] AttributeDescription,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'C',
                'l',
                'a',
                's',
                's',
                // attributes AttributeDescriptionList }
                0x30,
                0x07, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x02, // Request for sn
                's',
                'n',
                0x04,
                0x01,
                '*' // * attribute
        } );

        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 3, searchRequest.getMessageId() );
        assertEquals( "ou=users,ou=system", searchRequest.getBase().toString() );
        assertEquals( SearchScope.OBJECT, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( false, searchRequest.getTypesOnly() );

        // (objectClass = *)
        ExprNode filter = searchRequest.getFilter();

        PresenceNode presenceNode = ( PresenceNode ) filter;
        assertNotNull( presenceNode );
        assertEquals( "objectClass", presenceNode.getAttribute() );

        // The attributes
        List<String> attributes = searchRequest.getAttributes();

        assertEquals( 2, attributes.size() );
        Set<String> expectedAttrs = new HashSet<String>();
        expectedAttrs.add( "sn" );
        expectedAttrs.add( "*" );

        for ( String attribute : attributes )
        {
            assertTrue( expectedAttrs.contains( attribute ) );
            expectedAttrs.remove( attribute );
        }

        assertEquals( 0, expectedAttrs.size() );
    }


    /**
     * Tests an search request decode with a simple equality match filter.
     */
    @Test
    public void testDecodeSearchRequestOrFilters()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x96 );
        stream.put( new byte[]
            { 0x30, ( byte ) 0x81, ( byte ) 0x93, 0x02, 0x01,
                0x21,
                0x63,
                ( byte ) 0x81,
                ( byte ) 0x8D, // "dc=example,dc=com"
                0x04,
                0x11,
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x01,
                0x02,
                0x02,
                0x01,
                0x02,
                0x02,
                0x01,
                0x03,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA1,
                0x52, // ( |
                ( byte ) 0xA3,
                0x10, // ( uid=akarasulu )
                0x04,
                0x03,
                'u',
                'i',
                'd',
                0x04,
                0x09,
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ( byte ) 0xA3,
                0x09, // ( cn=aok )
                0x04,
                0x02,
                'c',
                'n',
                0x04,
                0x03,
                'a',
                'o',
                'k',
                ( byte ) 0xA3,
                0x15, // ( ou=Human Resources )
                0x04,
                0x02,
                'o',
                'u',
                0x04,
                0x0F,
                'H',
                'u',
                'm',
                'a',
                'n',
                ' ',
                'R',
                'e',
                's',
                'o',
                'u',
                'r',
                'c',
                'e',
                's',
                ( byte ) 0xA3,
                0x10,
                0x04,
                0x01,
                'l', // (l=Santa Clara )
                0x04,
                0x0B,
                'S',
                'a',
                'n',
                't',
                'a',
                ' ',
                'C',
                'l',
                'a',
                'r',
                'a',
                ( byte ) 0xA3,
                0x0A, // ( cn=abok ))
                0x04,
                0x02,
                'c',
                'n',
                0x04,
                0x04,
                'a',
                'b',
                'o',
                'k',
                0x30,
                0x15, // Attributes
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '0', // attr0
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '1', // attr1
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '2' // attr2
        } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 33, searchRequest.getMessageId() );
        assertEquals( "dc=example,dc=com", searchRequest.getBase().toString() );
        assertEquals( SearchScope.OBJECT, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_FINDING_BASE_OBJ, searchRequest.getDerefAliases() );
        assertEquals( 2, searchRequest.getSizeLimit() );
        assertEquals( 3, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (objectclass=t*)
        OrNode orNode = ( OrNode ) searchRequest.getFilter();
        assertNotNull( orNode );
        assertEquals( 5, orNode.getChildren().size() );

        // uid=akarasulu
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) orNode.getChildren().get( 0 );

        assertEquals( "uid", equalityNode.getAttribute() );
        assertEquals( "akarasulu", equalityNode.getValue().getString() );

        // cn=aok
        equalityNode = ( EqualityNode<?> ) orNode.getChildren().get( 1 );

        assertEquals( "cn", equalityNode.getAttribute() );
        assertEquals( "aok", equalityNode.getValue().getString() );

        // ou = Human Resources
        equalityNode = ( EqualityNode<?> ) orNode.getChildren().get( 2 );

        assertEquals( "ou", equalityNode.getAttribute() );
        assertEquals( "Human Resources", equalityNode.getValue().getString() );

        // l=Santa Clara
        equalityNode = ( EqualityNode<?> ) orNode.getChildren().get( 3 );

        assertEquals( "l", equalityNode.getAttribute() );
        assertEquals( "Santa Clara", equalityNode.getValue().getString() );

        // cn=abok
        equalityNode = ( EqualityNode<?> ) orNode.getChildren().get( 4 );

        assertEquals( "cn", equalityNode.getAttribute() );
        assertEquals( "abok", equalityNode.getValue().getString() );

        // The attributes
        List<String> attributes = searchRequest.getAttributes();

        for ( String attribute : attributes )
        {
            assertNotNull( attribute );
        }

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x0096, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x87 ), decodedPdu.substring( 0, 0x87 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest with controls.
     */
    @Test
    public void testDecodeSearchRequestWithControls()
    {
        byte[] asn1BERJava5 = new byte[]
            { 0x30, 0x7f,
                0x02, 0x01, 0x04, // messageID
                0x63,
                0x33,
                0x04,
                0x13, // baseObject
                'd',
                'c',
                '=',
                'm',
                'y',
                '-',
                'd',
                'o',
                'm',
                'a',
                'i',
                'n',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0a,
                0x01,
                0x02, // scope: subtree
                0x0a,
                0x01,
                0x03, // derefAliases: derefAlways
                0x02,
                0x01,
                0x00, // sizeLimit: 0
                0x02,
                0x01,
                0x00, // timeLimit: 0
                0x01,
                0x01,
                0x00, // typesOnly: false
                ( byte ) 0x87,
                0x0b, // Present filter: (objectClass=*)
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'C',
                'l',
                'a',
                's',
                's',
                0x30,
                0x00, // Attributes = '*'
                ( byte ) 0xa0,
                0x45, // controls
                0x30,
                0x28,
                0x04,
                0x16, // control
                '1',
                '.',
                '2',
                '.',
                '8',
                '4',
                '0',
                '.',
                '1',
                '1',
                '3',
                '5',
                '5',
                '6',
                '.',
                '1',
                '.',
                '4',
                '.',
                '3',
                '1',
                '9',
                0x01,
                0x01,
                ( byte ) 0xff, // criticality: false
                0x04,
                0x0b,
                0x30,
                0x09,
                0x02,
                0x01,
                0x02,
                0x04,
                0x04,
                0x47,
                0x00,
                0x00,
                0x00, // value: pageSize=2
                0x30,
                0x19,
                0x04,
                0x17, // control
                '2',
                '.',
                '1',
                '6',
                '.',
                '8',
                '4',
                '0',
                '.',
                '1',
                '.',
                '1',
                '1',
                '3',
                '7',
                '3',
                '0',
                '.',
                '3',
                '.',
                '4',
                '.',
                '2',
        };

        byte[] asn1BERJava6 = new byte[]
            { 0x30, 0x7f,
                0x02, 0x01, 0x04, // messageID
                0x63,
                0x33,
                0x04,
                0x13, // baseObject
                'd',
                'c',
                '=',
                'm',
                'y',
                '-',
                'd',
                'o',
                'm',
                'a',
                'i',
                'n',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0a,
                0x01,
                0x02, // scope: subtree
                0x0a,
                0x01,
                0x03, // derefAliases: derefAlways
                0x02,
                0x01,
                0x00, // sizeLimit: 0
                0x02,
                0x01,
                0x00, // timeLimit: 0
                0x01,
                0x01,
                0x00, // typesOnly: false
                ( byte ) 0x87,
                0x0b, // Present filter: (objectClass=*)
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'C',
                'l',
                'a',
                's',
                's',
                0x30,
                0x00, // Attributes = '*'
                ( byte ) 0xa0,
                0x45, // controls
                0x30,
                0x19,
                0x04,
                0x17, // control
                '2',
                '.',
                '1',
                '6',
                '.',
                '8',
                '4',
                '0',
                '.',
                '1',
                '.',
                '1',
                '1',
                '3',
                '7',
                '3',
                '0',
                '.',
                '3',
                '.',
                '4',
                '.',
                '2',
                0x30,
                0x28,
                0x04,
                0x16, // control
                '1',
                '.',
                '2',
                '.',
                '8',
                '4',
                '0',
                '.',
                '1',
                '1',
                '3',
                '5',
                '5',
                '6',
                '.',
                '1',
                '.',
                '4',
                '.',
                '3',
                '1',
                '9',
                0x01,
                0x01,
                ( byte ) 0xff, // criticality: false
                0x04,
                0x0b,
                0x30,
                0x09,
                0x02,
                0x01,
                0x02,
                0x04,
                0x04,
                0x47,
                0x00,
                0x00,
                0x00, // value: pageSize=2
            };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        // For Java6
        ByteBuffer streamJava6 = ByteBuffer.allocate( asn1BERJava6.length );
        streamJava6.put( asn1BERJava6 );
        String decodedPduJava6 = Strings.dumpBytes( streamJava6.array() );
        streamJava6.flip();

        // For Java5
        ByteBuffer streamJava5 = ByteBuffer.allocate( asn1BERJava5.length );
        streamJava5.put( asn1BERJava5 );
        String decodedPduJava5 = Strings.dumpBytes( streamJava5.array() );

        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( streamJava6, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 4, searchRequest.getMessageId() );
        assertEquals( 2, searchRequest.getControls().size() );

        // this is a constant in Java 5 API
        String pagedResultsControlOID = "1.2.840.113556.1.4.319";
        Control pagedResultsControl = searchRequest.getControl( pagedResultsControlOID );
        assertEquals( pagedResultsControlOID, pagedResultsControl.getOid() );
        assertTrue( pagedResultsControl.isCritical() );

        // this is a constant in Java 5 API
        String manageReferralControlOID = "2.16.840.1.113730.3.4.2";
        Control manageReferralControl = searchRequest.getControl( manageReferralControlOID );
        assertEquals( manageReferralControlOID, manageReferralControl.getOid() );

        assertEquals( "dc=my-domain,dc=com", searchRequest.getBase().toString() );
        assertEquals( SearchScope.SUBTREE, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( false, searchRequest.getTypesOnly() );

        ExprNode filter = searchRequest.getFilter();

        assertTrue( filter instanceof PresenceNode );
        assertEquals( "objectClass", ( ( PresenceNode ) filter ).getAttribute() );

        // Check the encoding
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x81, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertTrue( decodedPduJava5.equals( encodedPdu ) || decodedPduJava6.equals( encodedPdu ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest with no controls but with oid
     * attributes. The search filter is :
     * (&(|(objectclass=top)(2.5.4.11=contacts))(!(organizationalUnitName=ttt)))
     */
    @Test
    public void testDecodeSearchRequestGlobalNoControlsOidAndAlias()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0xA1 );
        stream.put( new byte[]
            {
                0x30,
                ( byte ) 0x81,
                ( byte ) 0x9E, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                ( byte ) 0x81,
                ( byte ) 0x98, // CHOICE { ...,
                // searchRequest
                // SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01, // scope
                // ENUMERATED
                // {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                // sizeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8,
                // timeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8,
                0x01,
                0x01,
                ( byte ) 0xFF, // typesOnly
                // BOOLEAN,
                // (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x4D, // Filter ::= CHOICE {
                // and [0] SET OF Filter,
                ( byte ) 0xA1,
                0x2A, // or [1] SET of Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3]
                // Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                'o',
                'p',
                ( byte ) 0xA3,
                0x14, // equalityMatch
                // [3]
                // Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x08,
                '2',
                '.',
                '5',
                '.',
                '4',
                '.',
                '1',
                '1', // attributeDesc
                // AttributeDescription
                // (LDAPString),
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x08,
                'c',
                'o',
                'n',
                't',
                'a',
                'c',
                't',
                's',
                ( byte ) 0xA2,
                0x1F, // not
                // [2]
                // Filter,
                ( byte ) 0xA3,
                0x1D, // equalityMatch [3]
                // Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x16,
                'o',
                'r',
                'g',
                'a',
                'n',
                'i',
                'z',
                'a',
                't',
                'i',
                'o',
                'n',
                'a',
                'l',
                'U',
                'n',
                'i',
                't',
                'N',
                'a',
                'm',
                'e',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                't',
                't',
                // attributes AttributeDescriptionList }
                0x30,
                0x15, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '0', // AttributeDescription
                // ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '1', // AttributeDescription
                // ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '2' // AttributeDescription ::=
            // LDAPString
        } );

        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 1000, searchRequest.getSizeLimit() );
        assertEquals( 1000, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (& (...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();

        // (& (| (...
        assertEquals( 2, andNodes.size() );
        OrNode orFilter = ( OrNode ) andNodes.get( 0 );
        assertNotNull( orFilter );

        // (& (| (obectclass=top) (...
        List<ExprNode> orNodes = orFilter.getChildren();
        assertEquals( 2, orNodes.size() );

        EqualityNode<?> equalityNode = ( EqualityNode<?> ) orNodes.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "objectclass", equalityNode.getAttribute() );
        assertEquals( "top", equalityNode.getValue().getString() );

        // (& (| (objectclass=top) (ou=contacts) ) (...
        equalityNode = ( EqualityNode<?> ) orNodes.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "2.5.4.11", equalityNode.getAttribute() );
        assertEquals( "contacts", equalityNode.getValue().getString() );

        // (& (| (objectclass=top) (ou=contacts) ) (! ...
        NotNode notNode = ( NotNode ) andNodes.get( 1 );
        assertNotNull( notNode );

        // (& (| (objectclass=top) (ou=contacts) ) (! (objectclass=ttt) ) )
        equalityNode = ( EqualityNode<?> ) notNode.getFirstChild();
        assertNotNull( equalityNode );

        assertEquals( "organizationalUnitName", equalityNode.getAttribute() );
        assertEquals( "ttt", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();

        for ( String attribute : attributes )
        {
            assertNotNull( attribute );
        }

        // We won't check the encoding, as it has changed because of
        // attributes transformations
    }


    /**
     * Test the decoding of a SearchRequest with SubEntry control.
     */
    @Test
    public void testDecodeSearchRequestSubEntryControl()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x5D, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x33,
                0x04,
                0x13, // baseObject: dc=my-domain,dc=com
                'd',
                'c',
                '=',
                'm',
                'y',
                '-',
                'd',
                'o',
                'm',
                'a',
                'i',
                'n',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0a,
                0x01,
                0x02, // scope: subtree
                0x0a,
                0x01,
                0x03, // derefAliases: derefAlways
                0x02,
                0x01,
                0x00, // sizeLimit: 0
                0x02,
                0x01,
                0x00, // timeLimit: 0
                0x01,
                0x01,
                0x00, // typesOnly: false
                ( byte ) 0x87,
                0x0b, // filter: (objectClass=*)
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'C',
                'l',
                'a',
                's',
                's',
                0x30,
                0x00,
                ( byte ) 0xa0,
                0x23, // controls
                0x30,
                0x21,
                0x04,
                0x17,
                '1',
                '.',
                '3',
                '.',
                '6',
                '.',
                '1',
                '.',
                '4',
                '.',
                '1',
                '.',
                '4',
                '2',
                '0',
                '3',
                '.',
                '1',
                '.',
                '1',
                '0',
                '.',
                '1', // SubEntry OID
                0x01,
                0x01,
                ( byte ) 0xFF, // criticality: true
                0x04,
                0x03,
                0x01,
                0x01,
                ( byte ) 0xFF // SubEntry visibility
        };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 4, searchRequest.getMessageId() );
        assertEquals( 1, searchRequest.getControls().size() );

        // SubEntry Control
        String subEntryControlOID = "1.3.6.1.4.1.4203.1.10.1";
        Control subEntryControl = searchRequest.getControl( subEntryControlOID );
        assertEquals( subEntryControlOID, subEntryControl.getOid() );
        assertTrue( subEntryControl.isCritical() );
        assertTrue( subEntryControl instanceof SubentriesDecorator );
        assertTrue( ( ( SubentriesDecorator ) subEntryControl ).getDecorated().isVisible() );

        assertEquals( "dc=my-domain,dc=com", searchRequest.getBase().toString() );
        assertEquals( SearchScope.SUBTREE, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( false, searchRequest.getTypesOnly() );

        ExprNode filter = searchRequest.getFilter();

        assertTrue( filter instanceof PresenceNode );
        assertEquals( "objectClass", ( ( PresenceNode ) filter ).getAttribute() );

        // Check the encoding
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x5F, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );
            assertEquals( decodedPdu, encodedPdu );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    // Defensive tests
    /**
     * Test the decoding of a SearchRequest with an empty body
     */
    @Test
    public void testDecodeSearchRequestEmptyBody()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x05, 0x02, 0x01, 0x04, // messageID
                0x63,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty baseDN and nothing more
     */
    @Test
    public void testDecodeSearchRequestBaseDnOnly()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x07, 0x02, 0x01, 0x04, // messageID
                0x63,
                0x02,
                0x04,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with no controls. The search filter
     * is : (&(|(objectclass=top)(ou=contacts))(!(objectclass=ttt)))
     */
    @Test
    public void testDecodeSearchRequestEmptyBaseDnNoControls()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x6F );
        stream.put( new byte[]
            { 0x30, 0x6D, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x68, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x00, // baseObject LDAPDN,
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // sizeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF, // typesOnly  BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x3C, // Filter ::= CHOICE {
                // and [0] SET OF Filter,
                ( byte ) 0xA1,
                0x24, // or [1] SET of Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3]
                // Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                'o',
                'p',
                ( byte ) 0xA3,
                0x0E, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x02,
                'o',
                'u', // attributeDesc AttributeDescription (LDAPString),
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x08,
                'c',
                'o',
                'n',
                't',
                'a',
                'c',
                't',
                's',
                ( byte ) 0xA2,
                0x14, // not [2] Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                't',
                't',
                // attributes AttributeDescriptionList }
                0x30,
                0x15, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '0', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '1', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '2' // AttributeDescription ::= LDAPString
        } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 1000, searchRequest.getSizeLimit() );
        assertEquals( 1000, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (& (...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();

        // (& (| (...
        assertEquals( 2, andNodes.size() );
        OrNode orFilter = ( OrNode ) andNodes.get( 0 );
        assertNotNull( orFilter );

        // (& (| (obectclass=top) (...
        List<ExprNode> orNodes = orFilter.getChildren();
        assertEquals( 2, orNodes.size() );

        EqualityNode<?> equalityNode = ( EqualityNode<?> ) orNodes.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "objectclass", equalityNode.getAttribute() );
        assertEquals( "top", equalityNode.getValue().getString() );

        // (& (| (objectclass=top) (ou=contacts) ) (...
        equalityNode = ( EqualityNode<?> ) orNodes.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "ou", equalityNode.getAttribute() );
        assertEquals( "contacts", equalityNode.getValue().getString() );

        // (& (| (objectclass=top) (ou=contacts) ) (! ...
        NotNode notNode = ( NotNode ) andNodes.get( 1 );
        assertNotNull( notNode );

        // (& (| (objectclass=top) (ou=contacts) ) (! (objectclass=ttt) ) )
        equalityNode = ( EqualityNode<?> ) notNode.getFirstChild();
        assertNotNull( equalityNode );

        assertEquals( "objectclass", equalityNode.getAttribute() );
        assertEquals( "ttt", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();

        for ( String attribute : attributes )
        {
            assertNotNull( attribute );
        }

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x6F, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x6F ), decodedPdu.substring( 0, 0x6F ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest with a bad objectBase
     */
    @Test
    public void testDecodeSearchRequestGlobalBadObjectBase()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x90 );
        stream.put( new byte[]
            { 0x30, ( byte ) 0x81,
                ( byte ) 0x8D, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                ( byte ) 0x81,
                ( byte ) 0x87, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                ':',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // sizeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF, // typesOnly  BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x3C, // Filter ::= CHOICE {
                // and [0] SET OF Filter,
                ( byte ) 0xA1,
                0x24, // or [1] SET of Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3]
                // Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                'o',
                'p',
                ( byte ) 0xA3,
                0x0E, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x02,
                'o',
                'u', // attributeDesc AttributeDescription (LDAPString),
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x08,
                'c',
                'o',
                'n',
                't',
                'a',
                'c',
                't',
                's',
                ( byte ) 0xA2,
                0x14, // not [2] Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                't',
                't',
                // attributes AttributeDescriptionList }
                0x30,
                0x15, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '0', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '1', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '2' // AttributeDescription ::= LDAPString
        } );

        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( de instanceof ResponseCarryingException );
            Message response = ( ( ResponseCarryingException ) de ).getResponse();
            assertTrue( response instanceof SearchResultDoneImpl );
            assertEquals( ResultCodeEnum.INVALID_DN_SYNTAX, ( ( SearchResultDoneImpl ) response ).getLdapResult()
                .getResultCode() );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty scope
     */
    @Test
    public void testDecodeSearchRequestEmptyScope()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x28, 0x02, 0x01,
                0x04, // messageID
                0x63,
                0x23,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with a bad scope
     */
    @Test
    public void testDecodeSearchRequestGlobalBadScope()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x90 );
        stream.put( new byte[]
            { 0x30, ( byte ) 0x81,
                ( byte ) 0x8D, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                ( byte ) 0x81,
                ( byte ) 0x87, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                ':',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x03, // scope ENUMERATED {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // sizeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF, // typesOnly  BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x3C, // Filter ::= CHOICE {
                // and [0] SET OF Filter,
                ( byte ) 0xA1,
                0x24, // or [1] SET of Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3]
                // Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                'o',
                'p',
                ( byte ) 0xA3,
                0x0E, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x02,
                'o',
                'u', // attributeDesc AttributeDescription (LDAPString),
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x08,
                'c',
                'o',
                'n',
                't',
                'a',
                'c',
                't',
                's',
                ( byte ) 0xA2,
                0x14, // not [2] Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                't',
                't',
                // attributes AttributeDescriptionList }
                0x30,
                0x15, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '0', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '1', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '2' // AttributeDescription ::= LDAPString
        } );

        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty derefAlias
     */
    @Test
    public void testDecodeSearchRequestEmptyDerefAlias()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x2B, 0x02, 0x01,
                0x04, // messageID
                0x63,
                0x26,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with a bad derefAlias
     */
    @Test
    public void testDecodeSearchRequestGlobalBadDerefAlias()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x90 );
        stream.put( new byte[]
            { 0x30, ( byte ) 0x81,
                ( byte ) 0x8D, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                ( byte ) 0x81,
                ( byte ) 0x87, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                ':',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x04, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // sizeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF, // typesOnly  BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x3C, // Filter ::= CHOICE {
                // and [0] SET OF Filter,
                ( byte ) 0xA1,
                0x24, // or [1] SET of Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3]
                // Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                'o',
                'p',
                ( byte ) 0xA3,
                0x0E, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x02,
                'o',
                'u', // attributeDesc AttributeDescription (LDAPString),
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x08,
                'c',
                'o',
                'n',
                't',
                'a',
                'c',
                't',
                's',
                ( byte ) 0xA2,
                0x14, // not [2] Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                't',
                't',
                // attributes AttributeDescriptionList }
                0x30,
                0x15, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '0', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '1', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '2' // AttributeDescription ::= LDAPString
        } );

        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty size limit
     */
    @Test
    public void testDecodeSearchRequestEmptySizeLimit()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x2E, 0x02, 0x01,
                0x04, // messageID
                0x63,
                0x29,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x01,
                0x00,
                0x02,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with a bad sizeLimit
     */
    @Test
    public void testDecodeSearchRequestGlobalBadSizeLimit()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x8F );
        stream.put( new byte[]
            { 0x30, ( byte ) 0x81,
                ( byte ) 0x8C, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                ( byte ) 0x81,
                ( byte ) 0x86, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                ':',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                0x02,
                0x01,
                ( byte ) 0xFF, // sizeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF, // typesOnly  BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x3C, // Filter ::= CHOICE {
                // and [0] SET OF Filter,
                ( byte ) 0xA1,
                0x24, // or [1] SET of Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3]
                // Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                'o',
                'p',
                ( byte ) 0xA3,
                0x0E, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x02,
                'o',
                'u', // attributeDesc AttributeDescription (LDAPString),
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x08,
                'c',
                'o',
                'n',
                't',
                'a',
                'c',
                't',
                's',
                ( byte ) 0xA2,
                0x14, // not [2] Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                't',
                't',
                // attributes AttributeDescriptionList }
                0x30,
                0x15, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '0', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '1', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '2' // AttributeDescription ::= LDAPString
        } );

        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty time limit
     */
    @Test
    public void testDecodeSearchRequestEmptyTimeLimit()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x31, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x2C,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x02,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with a bad timeLimit
     */
    @Test
    public void testDecodeSearchRequestGlobalBadTimeLimit()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x8F );
        stream.put( new byte[]
            { 0x30, ( byte ) 0x81,
                ( byte ) 0x8C, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                ( byte ) 0x81,
                ( byte ) 0x86, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                ':',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                // baseObject (0),
                // singleLevel (1),
                // wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                // neverDerefAliases (0),
                // derefInSearching (1),
                // derefFindingBaseObj (2),
                // derefAlways (3) },
                0x02,
                0x02,
                0x03,
                ( byte ) 0xE8, // sizeLimit INTEGER (0 .. maxInt), (1000)
                0x02,
                0x01,
                ( byte ) 0xFF, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF, // typesOnly  BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x3C, // Filter ::= CHOICE {
                // and [0] SET OF Filter,
                ( byte ) 0xA1,
                0x24, // or [1] SET of Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3]
                // Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                'o',
                'p',
                ( byte ) 0xA3,
                0x0E, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x02,
                'o',
                'u', // attributeDesc AttributeDescription (LDAPString),
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x08,
                'c',
                'o',
                'n',
                't',
                'a',
                'c',
                't',
                's',
                ( byte ) 0xA2,
                0x14, // not [2] Filter,
                ( byte ) 0xA3,
                0x12, // equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                // attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x0B,
                'o',
                'b',
                'j',
                'e',
                'c',
                't',
                'c',
                'l',
                'a',
                's',
                's',
                // assertionValue AssertionValue (OCTET STRING) }
                0x04,
                0x03,
                't',
                't',
                't',
                // attributes AttributeDescriptionList }
                0x30,
                0x15, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '0', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '1', // AttributeDescription ::= LDAPString
                0x04,
                0x05,
                'a',
                't',
                't',
                'r',
                '2' // AttributeDescription ::= LDAPString
        } );

        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty filter
     */
    @Test
    public void testDecodeSearchRequestEmptyTypeOnly()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x34, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x2F,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty filter
     */
    @Test
    public void testDecodeSearchRequestEmptyFilter()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x37, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x32,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA0,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty Present filter
     */
    @Test
    public void testDecodeSearchRequestEmptyPresentFilter()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x37, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x32,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0x87,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty equalityMatch filter
     */
    @Test
    public void testDecodeSearchRequestEmptyEqualityMatchFilter()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x37, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x32,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA3,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty greaterOrEqual filter
     */
    @Test
    public void testDecodeSearchRequestEmptyGreaterOrEqualFilter()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x37, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x32,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA5,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty lessOrEqual filter
     */
    @Test
    public void testDecodeSearchRequestEmptyLessOrEqualFilter()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x37, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x32,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA6,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an approxMatch filter
     */
    @Test
    public void testDecodeSearchRequestEmptyApproxMatchFilter()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x37, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x32,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA8,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with a greaterOrEqual filter and an
     * empty attributeDesc
     */
    @Test
    public void testDecodeSearchRequestEmptyGreaterOrEqualEmptyAttrDesc()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x39, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x34,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x00,
                0x0A,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA5,
                0x02,
                0x04,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with a greaterOrEqual filter and an
     * empty attributeValue, and an empty attribute List
     */
    @Test
    public void testDecodeSearchRequestEmptyGreaterOrEqualEmptyAttrValue()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x41,
                0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x3C,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01,
                0x0A,
                0x01,
                0x03,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA5,
                0x08,
                0x04,
                0x04,
                't',
                'e',
                's',
                't',
                0x04,
                0x00,
                0x30,
                0x00 // AttributeDescriptionList ::= SEQUENCE
            // OF AttributeDescription
        };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 4, searchRequest.getMessageId() );
        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // >=
        GreaterEqNode<?> greaterOrEqual = ( GreaterEqNode<?> ) searchRequest.getFilter();

        assertNotNull( greaterOrEqual );

        assertEquals( "test", greaterOrEqual.getAttribute() );
        assertEquals( "", greaterOrEqual.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();

        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x43, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu, decodedPdu );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest with a greaterOrEqual filter and an
     * empty attributeValue, and an '*' attribute List
     */
    @Test
    public void testDecodeSearchRequestEmptyGreaterOrEqualEmptyAttrValueStar()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x44,
                0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x3F,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01,
                0x0A,
                0x01,
                0x03,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA5,
                0x08,
                0x04,
                0x04,
                't',
                'e',
                's',
                't',
                0x04,
                0x00,
                0x30,
                0x03, // AttributeDescriptionList ::= SEQUENCE
                // OF AttributeDescription
                0x04,
                0x01,
                '*' };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 4, searchRequest.getMessageId() );
        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // >=
        GreaterEqNode<?> greaterOrEqual = ( GreaterEqNode<?> ) searchRequest.getFilter();

        assertNotNull( greaterOrEqual );

        assertEquals( "test", greaterOrEqual.getAttribute() );
        assertEquals( "", greaterOrEqual.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();

        assertEquals( 1, attributes.size() );
        assertEquals( "*", attributes.get( 0 ) );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x46, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu, decodedPdu );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest with a greaterOrEqual filter and an
     * empty attributeValue, and an empty attribute List
     */
    @Test
    public void testDecodeSearchRequestEmptyGreaterOrEqualEmptyAttrValueEmpty()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x43,
                0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x3E,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01,
                0x0A,
                0x01,
                0x03,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA5,
                0x08,
                0x04,
                0x04,
                't',
                'e',
                's',
                't',
                0x04,
                0x00,
                0x30,
                0x02, // AttributeDescriptionList ::= SEQUENCE
                // OF AttributeDescription
                0x04,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 4, searchRequest.getMessageId() );
        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // >=
        GreaterEqNode<?> greaterOrEqual = ( GreaterEqNode<?> ) searchRequest.getFilter();

        assertNotNull( greaterOrEqual );

        assertEquals( "test", greaterOrEqual.getAttribute() );
        assertEquals( "", greaterOrEqual.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();

        assertEquals( 0, attributes.size() );
    }


    /**
     * Test the decoding of a SearchRequest with an empty And filter
     */
    @Test
    public void testDecodeSearchRequestEmptyAndFilter()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x3B, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x36,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01,
                0x0A,
                0x01,
                0x03,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA0,
                0x00,
                0x30,
                0x02, // AttributeDescriptionList
                // ::=
                // SEQUENCE
                // OF
                // AttributeDescription
                0x04,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty Or filter
     */
    @Test
    public void testDecodeSearchRequestEmptyOrFilter()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x3B, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x36,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01,
                0x0A,
                0x01,
                0x03,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA1,
                0x00,
                0x30,
                0x02, // AttributeDescriptionList
                // ::=
                // SEQUENCE
                // OF
                // AttributeDescription
                0x04,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with an empty Not filter
     */
    @Test
    public void testDecodeSearchRequestEmptyNotFilter()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x3B, 0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x36,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01,
                0x0A,
                0x01,
                0x03,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA2,
                0x00,
                0x30,
                0x02, // AttributeDescriptionList
                // ::=
                // SEQUENCE
                // OF
                // AttributeDescription
                0x04,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with a Not filter and an empty And
     * filter
     */
    @Test
    public void testDecodeSearchRequestNotFilterEmptyAndFilter()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x3D,
                0x02,
                0x01,
                0x04, // messageID
                0x63,
                0x38,
                0x04,
                0x1F, // baseObject LDAPDN,
                'u',
                'i',
                'd',
                '=',
                'a',
                'k',
                'a',
                'r',
                'a',
                's',
                'u',
                'l',
                'u',
                ',',
                'd',
                'c',
                '=',
                'e',
                'x',
                'a',
                'm',
                'p',
                'l',
                'e',
                ',',
                'd',
                'c',
                '=',
                'c',
                'o',
                'm',
                0x0A,
                0x01,
                0x01,
                0x0A,
                0x01,
                0x03,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x01,
                0x01,
                ( byte ) 0xFF,
                ( byte ) 0xA2,
                0x02,
                ( byte ) 0xA0,
                0x00,
                0x30,
                0x02, // AttributeDescriptionList ::= SEQUENCE OF
                // AttributeDescription
                0x04,
                0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            assertTrue( true );
            return;
        }

        fail( "We should not reach this point" );
    }


    /**
     * Test the decoding of a SearchRequest with a greaterOrEqual filter and an
     * empty attributeValue, and an '*' attribute List
     */
    @Test
    public void testDecodeSearchRequestDIRSERVER_651()
    {
        byte[] asn1BER = new byte[]
            { 0x30, 0x60, 0x02, 0x01, 0x02, 0x63, 0x5b, 0x04, 0x0a, 'd', 'c', '=', 'p', 'g', 'p', 'k', 'e', 'y', 's',
                0x0a, 01, 02, 0x0a, 01, 00, 0x02, 01, 00, 0x02, 01, 00, 0x01, 01, 00, ( byte ) 0xa0, 0x3c,
                ( byte ) 0xa4, 0x28, 0x04, 0x09, 'p', 'g', 'p', 'u', 's', 'e', 'r', 'i', 'd', 0x30, 0x1b,
                ( byte ) 0x80, 0x19, 'v', 'g', 'j', 'o', 'k', 'j', 'e', 'v', '@', 'n', 'e', 't', 'c', 'e', 't', 'e',
                'r', 'a', '.', 'c', 'o', 'm', '.', 'm', 'k', ( byte ) 0xa3, 0x10, 0x04, 0x0b, 'p', 'g', 'p', 'd', 'i',
                's', 'a', 'b', 'l', 'e', 'd', 0x04, 0x01, '0', 0x30, 0x00 };

        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( asn1BER.length );
        stream.put( asn1BER );
        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a LdapMessage Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        // Decode a SearchRequest message
        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 2, searchRequest.getMessageId() );
        assertEquals( "dc=pgpkeys", searchRequest.getBase().toString() );
        assertEquals( SearchScope.SUBTREE, searchRequest.getScope() );
        assertEquals( AliasDerefMode.NEVER_DEREF_ALIASES, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( false, searchRequest.getTypesOnly() );

        // And
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 2, andNodes.size() );

        SubstringNode substringNode = ( SubstringNode ) andNodes.get( 0 );
        assertNotNull( substringNode );

        assertEquals( "pgpuserid", substringNode.getAttribute() );
        assertEquals( "vgjokjev@netcetera.com.mk", substringNode.getInitial() );
        assertEquals( 0, substringNode.getAny().size() );
        assertEquals( null, substringNode.getFinal() );

        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "pgpdisabled", equalityNode.getAttribute() );
        assertEquals( "0", equalityNode.getValue().getString() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x62, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu, decodedPdu );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * (a=b)
     */
    @Test
    public void testDecodeSearchRequestEq()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x25 );
        stream.put( new byte[]
            { 0x30, 0x23, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x1E, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x03, // baseObject LDAPDN,
                'a',
                '=',
                'b',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                //      baseObject (0),
                //      singleLevel (1),
                //      wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                //      neverDerefAliases (0),
                //      derefInSearching (1),
                //      derefFindingBaseObj (2),
                //      derefAlways (3) },
                0x02,
                0x01,
                0x00, // sizeLimit INTEGER (0 .. maxInt), (0)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF,// typesOnly BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA3,
                0x06, // Filter ::= CHOICE {
                //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'a', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'b', //      assertionValue AssertionValue (OCTET STRING) }
                // attributes AttributeDescriptionList }
                0x30,
                0x00, // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
            } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "a=b", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (a=b)
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) searchRequest.getFilter();

        assertNotNull( equalityNode );

        assertEquals( "a", equalityNode.getAttribute() );
        assertEquals( "b", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x25, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x25 ), decodedPdu.substring( 0, 0x25 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * (&(a=b))
     */
    @Test
    public void testDecodeSearchRequestAndEq()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x27 );
        stream.put( new byte[]
            { 0x30, 0x25, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x20, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x03, // baseObject LDAPDN,
                'a',
                '=',
                'b',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                //      baseObject (0),
                //      singleLevel (1),
                //      wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                //      neverDerefAliases (0),
                //      derefInSearching (1),
                //      derefFindingBaseObj (2),
                //      derefAlways (3) },
                0x02,
                0x01,
                0x00, // sizeLimit INTEGER (0 .. maxInt), (0)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF,// typesOnly BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x08, // Filter ::= CHOICE {
                ( byte ) 0xA3,
                0x06,
                //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'a', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'b', //      assertionValue AssertionValue (OCTET STRING) }
                // attributes AttributeDescriptionList }
                0x30,
                0x00, // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
            } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "a=b", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (&(...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 1, andNodes.size() );

        // (&(a=b))
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "a", equalityNode.getAttribute() );
        assertEquals( "b", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x27, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x27 ), decodedPdu.substring( 0, 0x27 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * (&(a=b)(c=d))
     */
    @Test
    public void testDecodeSearchRequestAndEqEq()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x2F );
        stream.put( new byte[]
            { 0x30, 0x2D, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x28, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x03, // baseObject LDAPDN,
                'a',
                '=',
                'b',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                //      baseObject (0),
                //      singleLevel (1),
                //      wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                //      neverDerefAliases (0),
                //      derefInSearching (1),
                //      derefFindingBaseObj (2),
                //      derefAlways (3) },
                0x02,
                0x01,
                0x00, // sizeLimit INTEGER (0 .. maxInt), (0)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF,// typesOnly BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x10, // Filter ::= CHOICE {
                ( byte ) 0xA3,
                0x06,
                //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'a', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'b', //      assertionValue AssertionValue (OCTET STRING) }
                ( byte ) 0xA3,
                0x06,
                //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'c', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'd', //      assertionValue AssertionValue (OCTET STRING) }
                // attributes AttributeDescriptionList }
                0x30,
                0x00, // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
            } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "a=b", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (&(...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 2, andNodes.size() );

        // (&(a=b)...
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "a", equalityNode.getAttribute() );
        assertEquals( "b", equalityNode.getValue().getString() );

        // (&(a=b)(c=d))
        equalityNode = ( EqualityNode<?> ) andNodes.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "c", equalityNode.getAttribute() );
        assertEquals( "d", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x2F, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x2F ), decodedPdu.substring( 0, 0x2F ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * (&(&(a=b))
     */
    @Test
    public void testDecodeSearchRequestAndAndEq()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x29 );
        stream.put( new byte[]
            { 0x30, 0x27, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x22, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x03, // baseObject LDAPDN,
                'a',
                '=',
                'b',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                //      baseObject (0),
                //      singleLevel (1),
                //      wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                //      neverDerefAliases (0),
                //      derefInSearching (1),
                //      derefFindingBaseObj (2),
                //      derefAlways (3) },
                0x02,
                0x01,
                0x00, // sizeLimit INTEGER (0 .. maxInt), (0)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF,// typesOnly BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x0A, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA0,
                0x08, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA3,
                0x06,//      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'a', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'b', //      assertionValue AssertionValue (OCTET STRING) }
                0x30,
                0x00, // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
            } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "a=b", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (&(...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 1, andNodes.size() );

        // (&(&(..
        AndNode andNode2 = ( AndNode ) andNodes.get( 0 );
        assertNotNull( andNode2 );

        List<ExprNode> andNodes2 = andNode2.getChildren();
        assertEquals( 1, andNodes2.size() );

        // (&(&(a=b)))
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes2.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "a", equalityNode.getAttribute() );
        assertEquals( "b", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x29, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x29 ), decodedPdu.substring( 0, 0x29 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * (&(&(a=b)(c=d))
     */
    @Test
    public void testDecodeSearchRequestAndAndEqEq()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x31 );
        stream.put( new byte[]
            { 0x30, 0x2F, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x2A, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x03, // baseObject LDAPDN,
                'a',
                '=',
                'b',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                //      baseObject (0),
                //      singleLevel (1),
                //      wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                //      neverDerefAliases (0),
                //      derefInSearching (1),
                //      derefFindingBaseObj (2),
                //      derefAlways (3) },
                0x02,
                0x01,
                0x00, // sizeLimit INTEGER (0 .. maxInt), (0)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF,// typesOnly BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x12, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA0,
                0x10, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA3,
                0x06,
                //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'a', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'b', //      assertionValue AssertionValue (OCTET STRING) }
                ( byte ) 0xA3,
                0x06,
                //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'c', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'd', //      assertionValue AssertionValue (OCTET STRING) }
                0x30,
                0x00, // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
            } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "a=b", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (&(...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 1, andNodes.size() );

        // (&(&(..
        AndNode andNode2 = ( AndNode ) andNodes.get( 0 );
        assertNotNull( andNode2 );

        List<ExprNode> andNodes2 = andNode2.getChildren();
        assertEquals( 2, andNodes2.size() );

        // (&(&(a=b)...
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes2.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "a", equalityNode.getAttribute() );
        assertEquals( "b", equalityNode.getValue().getString() );

        // (&(&(a=b)(c=d)
        equalityNode = ( EqualityNode<?> ) andNodes2.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "c", equalityNode.getAttribute() );
        assertEquals( "d", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x31, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x31 ), decodedPdu.substring( 0, 0x31 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * (&(&(a=b))(c=d))
     */
    @Test
    public void testDecodeSearchRequestAnd_AndEq_Eq()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x31 );
        stream.put( new byte[]
            { 0x30, 0x2F, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x2A, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x03, // baseObject LDAPDN,
                'a',
                '=',
                'b',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                //      baseObject (0),
                //      singleLevel (1),
                //      wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                //      neverDerefAliases (0),
                //      derefInSearching (1),
                //      derefFindingBaseObj (2),
                //      derefAlways (3) },
                0x02,
                0x01,
                0x00, // sizeLimit INTEGER (0 .. maxInt), (0)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF,// typesOnly BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x12, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA0,
                0x08, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA3,
                0x06,//      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'a', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'b', //      assertionValue AssertionValue (OCTET STRING) }
                ( byte ) 0xA3,
                0x06, //      equalityMatch [3] Assertion,
                //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'c', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'd', //      assertionValue AssertionValue (OCTET STRING) }
                0x30,
                0x00, // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
            } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "a=b", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (&(...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 2, andNodes.size() );

        // (&(&(..
        AndNode andNode2 = ( AndNode ) andNodes.get( 0 );
        assertNotNull( andNode2 );

        List<ExprNode> andNodes2 = andNode2.getChildren();
        assertEquals( 1, andNodes2.size() );

        // (&(&(a=b))...
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes2.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "a", equalityNode.getAttribute() );
        assertEquals( "b", equalityNode.getValue().getString() );

        // (&(&(a=b))(c=d))
        equalityNode = ( EqualityNode<?> ) andNodes.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "c", equalityNode.getAttribute() );
        assertEquals( "d", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x31, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x31 ), decodedPdu.substring( 0, 0x31 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * (&(&(a=b)(c=d))(e=f))
     */
    @Test
    public void testDecodeSearchRequestAnd_AndEqEq_Eq()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x39 );
        stream.put( new byte[]
            { 0x30, 0x37, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x32, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x03, // baseObject LDAPDN,
                'a',
                '=',
                'b',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                //      baseObject (0),
                //      singleLevel (1),
                //      wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                //      neverDerefAliases (0),
                //      derefInSearching (1),
                //      derefFindingBaseObj (2),
                //      derefAlways (3) },
                0x02,
                0x01,
                0x00, // sizeLimit INTEGER (0 .. maxInt), (0)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF,// typesOnly BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x1A, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA0,
                0x10, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA3,
                0x06,//      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'a', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'b', //      assertionValue AssertionValue (OCTET STRING) }
                ( byte ) 0xA3,
                0x06,//      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'c', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'd', //      assertionValue AssertionValue (OCTET STRING) }
                ( byte ) 0xA3,
                0x06, //      equalityMatch [3] Assertion,
                //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'e', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'f', //      assertionValue AssertionValue (OCTET STRING) }
                0x30,
                0x00, // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
            } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "a=b", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (&(...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 2, andNodes.size() );

        // (&(&(..
        AndNode andNode2 = ( AndNode ) andNodes.get( 0 );
        assertNotNull( andNode2 );

        List<ExprNode> andNodes2 = andNode2.getChildren();
        assertEquals( 2, andNodes2.size() );

        // (&(&(a=b)...
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes2.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "a", equalityNode.getAttribute() );
        assertEquals( "b", equalityNode.getValue().getString() );

        // (&(&(a=b)(c=d)...
        equalityNode = ( EqualityNode<?> ) andNodes2.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "c", equalityNode.getAttribute() );
        assertEquals( "d", equalityNode.getValue().getString() );

        // (&(&(a=b)(c=d))(e=f))
        equalityNode = ( EqualityNode<?> ) andNodes.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "e", equalityNode.getAttribute() );
        assertEquals( "f", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x39, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x39 ), decodedPdu.substring( 0, 0x39 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * (&(a=b)(|(a=b)(c=d)))
     */
    @Test
    public void testDecodeSearchRequestAndEq_OrEqEq()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x39 );
        stream.put( new byte[]
            { 0x30, 0x37, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x32, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x03, // baseObject LDAPDN,
                'a',
                '=',
                'b',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                //      baseObject (0),
                //      singleLevel (1),
                //      wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                //      neverDerefAliases (0),
                //      derefInSearching (1),
                //      derefFindingBaseObj (2),
                //      derefAlways (3) },
                0x02,
                0x01,
                0x00, // sizeLimit INTEGER (0 .. maxInt), (0)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF,// typesOnly BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x1A, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA3,
                0x06, //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'a', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'b', //      assertionValue AssertionValue (OCTET STRING) }
                ( byte ) 0xA1,
                0x10, // Filter ::= CHOICE { or             [1] SET OF Filter,
                ( byte ) 0xA3,
                0x06,//      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'c', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'd', //      assertionValue AssertionValue (OCTET STRING) }
                ( byte ) 0xA3,
                0x06,//      equalityMatch [3] Assertion,
                //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'e', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'f', //      assertionValue AssertionValue (OCTET STRING) }
                0x30,
                0x00, // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
            } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "a=b", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (&(...
        ExprNode exprNode = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) exprNode;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 2, andNodes.size() );

        // (&(a=b)..
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "a", equalityNode.getAttribute() );
        assertEquals( "b", equalityNode.getValue().getString() );

        // (&(a=b)(|(...
        OrNode orNode = ( OrNode ) andNodes.get( 1 );
        assertNotNull( orNode );

        List<ExprNode> orNodes = orNode.getChildren();
        assertEquals( 2, orNodes.size() );

        // (&(a=b)(|(c=d)...
        equalityNode = ( EqualityNode<?> ) orNodes.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "c", equalityNode.getAttribute() );
        assertEquals( "d", equalityNode.getValue().getString() );

        // (&(a=b)(|(c=d)(e=f)))
        equalityNode = ( EqualityNode<?> ) orNodes.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "e", equalityNode.getAttribute() );
        assertEquals( "f", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x39, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x39 ), decodedPdu.substring( 0, 0x39 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * (&(&(a=b))(&(c=d)))
     */
    @Test
    public void testDecodeSearchRequestAnd_AndEq_AndEq()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x33 );
        stream.put( new byte[]
            { 0x30, 0x31, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x2C, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x03, // baseObject LDAPDN,
                'a',
                '=',
                'b',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                //      baseObject (0),
                //      singleLevel (1),
                //      wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                //      neverDerefAliases (0),
                //      derefInSearching (1),
                //      derefFindingBaseObj (2),
                //      derefAlways (3) },
                0x02,
                0x01,
                0x00, // sizeLimit INTEGER (0 .. maxInt), (0)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF,// typesOnly BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x14, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA0,
                0x08, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA3,
                0x06,//      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'a', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'b', //      assertionValue AssertionValue (OCTET STRING) }
                ( byte ) 0xA0,
                0x08, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA3,
                0x06,//      equalityMatch [3] Assertion,
                //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'c', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'd', //      assertionValue AssertionValue (OCTET STRING) }
                0x30,
                0x00 // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
        } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "a=b", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (&(...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 2, andNodes.size() );

        // (&(&(..
        AndNode andNode2 = ( AndNode ) andNodes.get( 0 );
        assertNotNull( andNode2 );

        List<ExprNode> andNodes2 = andNode2.getChildren();
        assertEquals( 1, andNodes2.size() );

        // (&(&(a=b)...
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes2.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "a", equalityNode.getAttribute() );
        assertEquals( "b", equalityNode.getValue().getString() );

        // (&(&(a=b))(&...
        andNode2 = ( AndNode ) andNodes.get( 1 );
        assertNotNull( andNode2 );

        andNodes2 = andNode2.getChildren();
        assertEquals( 1, andNodes2.size() );

        // (&(&(a=b))(&(c=d)))
        equalityNode = ( EqualityNode<?> ) andNodes2.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "c", equalityNode.getAttribute() );
        assertEquals( "d", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x33, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x33 ), decodedPdu.substring( 0, 0x33 ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * (&(&(a=b)(c=d))(&(e=f)))
     */
    @Test
    public void testDecodeSearchRequestAnd_AndEqEq_AndEq()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x3B );
        stream.put( new byte[]
            { 0x30, 0x39, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x34, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x03, // baseObject LDAPDN,
                'a',
                '=',
                'b',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                //      baseObject (0),
                //      singleLevel (1),
                //      wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                //      neverDerefAliases (0),
                //      derefInSearching (1),
                //      derefFindingBaseObj (2),
                //      derefAlways (3) },
                0x02,
                0x01,
                0x00, // sizeLimit INTEGER (0 .. maxInt), (0)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF,// typesOnly BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x1C, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA0,
                0x10, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA3,
                0x06,//      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'a', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'b', //      assertionValue AssertionValue (OCTET STRING) }
                ( byte ) 0xA3,
                0x06,//      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'c', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'd', //      assertionValue AssertionValue (OCTET STRING) }
                ( byte ) 0xA0,
                0x08, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA3,
                0x06,//      equalityMatch [3] Assertion,
                //      equalityMatch [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'e', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'f', //      assertionValue AssertionValue (OCTET STRING) }
                0x30,
                0x00 // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
        } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "a=b", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (&(...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 2, andNodes.size() );

        // (&(&(..
        AndNode andNode2 = ( AndNode ) andNodes.get( 0 );
        assertNotNull( andNode2 );

        List<ExprNode> andNodes2 = andNode2.getChildren();
        assertEquals( 2, andNodes2.size() );

        // (&(&(a=b)...
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes2.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "a", equalityNode.getAttribute() );
        assertEquals( "b", equalityNode.getValue().getString() );

        // (&(&(a=b)(c=d))...
        equalityNode = ( EqualityNode<?> ) andNodes2.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "c", equalityNode.getAttribute() );
        assertEquals( "d", equalityNode.getValue().getString() );

        // (&(&(a=b)(c=d))(&...
        andNode2 = ( AndNode ) andNodes.get( 1 );
        assertNotNull( andNode2 );

        andNodes2 = andNode2.getChildren();
        assertEquals( 1, andNodes2.size() );

        // (&(&(a=b)(c=d))(&(e=f)))
        equalityNode = ( EqualityNode<?> ) andNodes2.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "e", equalityNode.getAttribute() );
        assertEquals( "f", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x3B, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x3B ), decodedPdu.substring( 0, 0x3B ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * (&(|(abcdef=*)(ghijkl=*))(!(e>=f)))
     */
    @Test
    public void testDecodeSearchRequestAnd_OrPrPr_NotGEq()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x3B );
        stream.put( new byte[]
            { 0x30, 0x39, // LDAPMessage ::=SEQUENCE {
                0x02,
                0x01,
                0x01, // messageID MessageID
                0x63,
                0x34, // CHOICE { ...,
                // searchRequest SearchRequest, ...
                // SearchRequest ::= APPLICATION[3] SEQUENCE {
                0x04,
                0x03, // baseObject LDAPDN,
                'a',
                '=',
                'b',
                0x0A,
                0x01,
                0x01, // scope ENUMERATED {
                //      baseObject (0),
                //      singleLevel (1),
                //      wholeSubtree (2) },
                0x0A,
                0x01,
                0x03, // derefAliases ENUMERATED {
                //      neverDerefAliases (0),
                //      derefInSearching (1),
                //      derefFindingBaseObj (2),
                //      derefAlways (3) },
                0x02,
                0x01,
                0x00, // sizeLimit INTEGER (0 .. maxInt), (0)
                0x02,
                0x01,
                0x00, // timeLimit INTEGER (0 .. maxInt), (1000)
                0x01,
                0x01,
                ( byte ) 0xFF,// typesOnly BOOLEAN, (TRUE)
                // filter Filter,
                ( byte ) 0xA0,
                0x1C, // Filter ::= CHOICE { and             [0] SET OF Filter,
                ( byte ) 0xA1,
                0x10, // Filter ::= CHOICE { or             [0] SET OF Filter,
                ( byte ) 0x87,
                0x06,// present [7] AttributeDescription,
                'a',
                'b',
                'c', // AttributeDescription ::= LDAPString
                'd',
                'e',
                'f',
                ( byte ) 0x87,
                0x06,// present [7] AttributeDescription,
                'g',
                'h',
                'i', // AttributeDescription ::= LDAPString
                'j',
                'k',
                'l',
                ( byte ) 0xA2,
                0x08, // Filter ::= CHOICE { not             Filter,
                ( byte ) 0xA5,
                0x06,//      greaterOrEqual [3] Assertion,
                // Assertion ::= SEQUENCE {
                0x04,
                0x01,
                'e', //      attributeDesc AttributeDescription (LDAPString),
                0x04,
                0x01,
                'f', //      assertionValue AssertionValue (OCTET STRING) }
                0x30,
                0x00 // AttributeDescriptionList ::= SEQUENCE OF AttributeDescription
        } );

        String decodedPdu = Strings.dumpBytes( stream.array() );
        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "a=b", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        // (&(...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 2, andNodes.size() );

        // (&(|(..
        OrNode orFilter = ( OrNode ) andNodes.get( 0 );
        assertNotNull( orFilter );

        List<ExprNode> orNodes = orFilter.getChildren();
        assertEquals( 2, orNodes.size() );

        // (&(&(abcdef=*)...
        PresenceNode presenceNode = ( PresenceNode ) orNodes.get( 0 );
        assertNotNull( presenceNode );

        assertEquals( "abcdef", presenceNode.getAttribute() );

        // (&(&(abcdef=*)(ghijkl=*))...
        presenceNode = ( PresenceNode ) orNodes.get( 1 );
        assertNotNull( presenceNode );

        assertEquals( "ghijkl", presenceNode.getAttribute() );

        // (&(&(abcdef=*)(ghijkl=*))(&...
        NotNode notNode = ( NotNode ) andNodes.get( 1 );
        assertNotNull( notNode );

        // (&(&(abcdef=*)(ghijkl=*))(&(e>=f)))
        GreaterEqNode<?> greaterEqNode = ( GreaterEqNode<?> ) notNode.getFirstChild();
        assertNotNull( greaterEqNode );

        assertEquals( "e", greaterEqNode.getAttribute() );
        assertEquals( "f", greaterEqNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );

        // Check the encoding
        // We won't check the whole PDU, as it may differs because
        // attributes may have been reordered
        try
        {
            ByteBuffer bb = encoder.encodeMessage( searchRequest );

            // Check the length
            assertEquals( 0x3B, bb.limit() );

            String encodedPdu = Strings.dumpBytes( bb.array() );

            assertEquals( encodedPdu.substring( 0, 0x3B ), decodedPdu.substring( 0, 0x3B ) );
        }
        catch ( EncoderException ee )
        {
            ee.printStackTrace();
            fail( ee.getMessage() );
        }
    }


    /**
     * Test the decoding of a SearchRequest
     * for rootDSE
     */
    @Test
    public void testDecodeSearchRequestRootDse()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x33 );
        stream.put( new byte[]
            { 0x30, ( byte ) 0x84, 0x00, 0x00, 0x00, 0x2D, 0x02, 0x01, 0x01, 0x63, ( byte ) 0x84, 0x00, 0x00, 0x00,
                0x24, 0x04, 0x00, 0x0A, 0x01, 0x00, 0x0A, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01,
                0x00, ( byte ) 0x87, 0x0B, 0x6F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x30,
                ( byte ) 0x84, 0x00, 0x00, 0x00, 0x00 } );

        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 1, searchRequest.getMessageId() );
        assertEquals( "", searchRequest.getBase().toString() );
        assertEquals( SearchScope.OBJECT, searchRequest.getScope() );
        assertEquals( AliasDerefMode.NEVER_DEREF_ALIASES, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( false, searchRequest.getTypesOnly() );

        ExprNode filter = searchRequest.getFilter();

        PresenceNode presenceNode = ( PresenceNode ) filter;
        assertNotNull( presenceNode );
        assertEquals( "objectClass", presenceNode.getAttribute() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );
    }


    /**
     * Test the decoding of a SearchRequest with special length (long form)
     * for rootDSE
     */
    @Test
    public void testDecodeSearchRequestDIRSERVER_810()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x6B );
        stream.put( new byte[]
            { 0x30, ( byte ) 0x84, 0x00, 0x00, 0x00, 0x65, 0x02, 0x01, 0x03, 0x63, ( byte ) 0x84, 0x00, 0x00, 0x00,
                0x5c, 0x04, 0x12, 0x6f, 0x75, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2c, 0x6f, 0x75, 0x3d, 0x73, 0x79,
                0x73,
                0x74,
                0x65,
                0x6d, // 'ou=users,ou=system'
                0x0a,
                0x01,
                0x01,
                0x0a,
                0x01,
                0x00,
                0x02,
                0x01,
                0x00,
                0x02,
                0x01,
                0x1e,
                0x01,
                0x01,
                ( byte ) 0xff,
                ( byte ) 0xa0,
                ( byte ) 0x84,
                0x00,
                0x00,
                0x00,
                0x2d,
                ( byte ) 0xa3,
                ( byte ) 0x84,
                0x00,
                0x00,
                0x00,
                0x0e,
                0x04,
                0x03,
                0x75,
                0x69,
                0x64,
                0x04,
                0x07,
                0x62,
                0x75,
                0x73,
                0x74,
                0x65,
                0x72,
                0x20, // 'buster ' (with a space at the end)
                ( byte ) 0xa3,
                ( byte ) 0x84,
                0x00,
                0x00,
                0x00,
                0x13,
                0x04,
                0x0b,
                0x73,
                0x62,
                0x41,
                0x74,
                0x74,
                0x72,
                0x69,
                0x62,
                0x75,
                0x74,
                0x65, // sbAttribute
                0x04,
                0x04,
                0x42,
                0x75,
                0x79,
                0x20, // 'Buy ' (with a space at the end)
                0x30,
                ( byte ) 0x84,
                0x00,
                0x00,
                0x00,
                0x00 } );

        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 3, searchRequest.getMessageId() );
        assertEquals( "ou=users,ou=system", searchRequest.getBase().toString() );
        assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
        assertEquals( AliasDerefMode.NEVER_DEREF_ALIASES, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 30, searchRequest.getTimeLimit() );
        assertEquals( true, searchRequest.getTypesOnly() );

        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 2, andNodes.size() );

        // (&(uid=buster)...
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "uid", equalityNode.getAttribute() );
        assertEquals( "buster ", equalityNode.getValue().getString() );

        // (&(uid=buster)(sbAttribute=Buy))
        equalityNode = ( EqualityNode<?> ) andNodes.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "sbAttribute", equalityNode.getAttribute() );
        assertEquals( "Buy ", equalityNode.getValue().getString() );

        List<String> attributes = searchRequest.getAttributes();
        assertEquals( 0, attributes.size() );
    }


    /**
     * Test the decoding of a SearchRequest with a complex filter :
     * (&(objectClass=person)(|(cn=Tori*)(sn=Jagger)))
     */
    @Test
    public void testDecodeSearchRequestComplexFilterWithControl()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x77 );
        stream.put( new byte[]
            { 0x30, 0x75, // LdapMessage
                0x02,
                0x01,
                0x06, // message Id = 6
                0x63,
                0x53, // SearchRequest
                0x04,
                0x09, // BaseDN 'ou=system'
                0x6F,
                0x75,
                0x3D,
                0x73,
                0x79,
                0x73,
                0x74,
                0x65,
                0x6D,
                0x0A,
                0x01,
                0x02, // scope = SUBTREE
                0x0A,
                0x01,
                0x03, // derefAlias = 3
                0x02,
                0x01,
                0x00, // sizeLimit = none
                0x02,
                0x01,
                0x00, // timeLimit = none
                0x01,
                0x01,
                0x00, // types only = false
                ( byte ) 0xA0,
                0x35, // AND
                ( byte ) 0xA3,
                0x15, // equals
                0x04,
                0x0B, // 'objectclass'
                0x6F,
                0x62,
                0x6A,
                0x65,
                0x63,
                0x74,
                0x43,
                0x6C,
                0x61,
                0x73,
                0x73,
                0x04,
                0x06, // 'person' 
                0x70,
                0x65,
                0x72,
                0x73,
                0x6F,
                0x6E,
                ( byte ) 0xA1,
                0x1C, // OR
                ( byte ) 0xA4,
                0x0C, // substrings : 'cn=Tori*'
                0x04,
                0x02, // 'cn'
                0x63,
                0x6E,
                0x30,
                0x06, // initial = 'Tori'
                ( byte ) 0x80,
                0x04,
                0x54,
                0x6F,
                0x72,
                0x69,
                ( byte ) 0xA3,
                0x0C, // equals
                0x04,
                0x02, // 'sn'
                0x73,
                0x6E,
                0x04,
                0x06, // 'Jagger'
                0x4A,
                0x61,
                0x67,
                0x67,
                0x65,
                0x72,
                0x30,
                0x00, // Control
                ( byte ) 0xA0,
                0x1B,
                0x30,
                0x19,
                0x04,
                0x17,
                '2',
                '.',
                '1',
                '6',
                '.',
                '8',
                '4',
                '0',
                '.',
                '1',
                '.',
                '1',
                '1',
                '3',
                '7',
                '3',
                '0',
                '.',
                '3',
                '.',
                '4',
                '.',
                '2'
        } );

        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 6, searchRequest.getMessageId() );
        assertEquals( "ou=system", searchRequest.getBase().toString() );
        assertEquals( SearchScope.SUBTREE, searchRequest.getScope() );
        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( false, searchRequest.getTypesOnly() );

        // (&(...
        ExprNode filter = searchRequest.getFilter();

        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 2, andNodes.size() );

        // (&(objectClass=person)..
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "objectClass", equalityNode.getAttribute() );
        assertEquals( "person", equalityNode.getValue().getString() );

        // (&(a=b)(|
        OrNode orNode = ( OrNode ) andNodes.get( 1 );
        assertNotNull( orNode );

        List<ExprNode> orNodes = orNode.getChildren();
        assertEquals( 2, orNodes.size() );

        // (&(a=b)(|(cn=Tori*
        SubstringNode substringNode = ( SubstringNode ) orNodes.get( 0 );
        assertNotNull( substringNode );

        assertEquals( "cn", substringNode.getAttribute() );
        assertEquals( "Tori", substringNode.getInitial() );
        assertEquals( 0, substringNode.getAny().size() );
        assertEquals( null, substringNode.getFinal() );

        // (&(a=b)(|(cn=Tori*)(sn=Jagger)))
        equalityNode = ( EqualityNode<?> ) orNodes.get( 1 );
        assertNotNull( equalityNode );

        assertEquals( "sn", equalityNode.getAttribute() );
        assertEquals( "Jagger", equalityNode.getValue().getString() );
    }


    @Test
    public void decodeComplexFilter()
    {
        Asn1Decoder ldapDecoder = new Asn1Decoder();

        ByteBuffer stream = ByteBuffer.allocate( 0x77 );
        stream.put( new byte[]
            {
                0x30, 0x53,
                0x02, 0x01, 0x02,
                0x63, 0x4E,
                0x04, 0x11,
                'd', 'c', '=', 'e', 'x', 'a', 'm', 'p', 'l', 'e', ',', 'd', 'c', '=', 'c', 'o', 'm',
                0x0A, 0x01, 0x02,
                0x0A, 0x01, 0x00,
                0x02, 0x01, 0x00,
                0x02, 0x01, 0x00,
                0x01, 0x01, 0x00,
                ( byte ) 0xA0, 0x28,
                ( byte ) 0xA1, 0x1F,
                ( byte ) 0xA0, 0x1D,
                ( byte ) 0xA3, 0x1B,
                0x04, 0x0B,
                'o', 'b', 'j', 'e', 'c', 't', 'c', 'l', 'a', 's', 's',
                0x04, 0x0C,
                'g', 'r', 'o', 'u', 'p', 'o', 'f', 'n', 'a', 'm', 'e', 's',
                ( byte ) 0x87, 0x05,
                'o', 'w', 'n', 'e', 'r',
                0x30, 0x00
        } );

        stream.flip();

        // Allocate a BindRequest Container
        LdapMessageContainer<SearchRequestDecorator> ldapMessageContainer =
            new LdapMessageContainer<SearchRequestDecorator>( codec );

        try
        {
            ldapDecoder.decode( stream, ldapMessageContainer );
        }
        catch ( DecoderException de )
        {
            de.printStackTrace();
            fail( de.getMessage() );
        }

        assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );

        SearchRequest searchRequest = ldapMessageContainer.getMessage();

        assertEquals( 2, searchRequest.getMessageId() );
        assertEquals( "dc=example,dc=com", searchRequest.getBase().toString() );
        assertEquals( SearchScope.SUBTREE, searchRequest.getScope() );
        assertEquals( AliasDerefMode.NEVER_DEREF_ALIASES, searchRequest.getDerefAliases() );
        assertEquals( 0, searchRequest.getSizeLimit() );
        assertEquals( 0, searchRequest.getTimeLimit() );
        assertEquals( false, searchRequest.getTypesOnly() );

        ExprNode filter = searchRequest.getFilter();

        // (&(...
        AndNode andNode = ( AndNode ) filter;
        assertNotNull( andNode );

        List<ExprNode> andNodes = andNode.getChildren();
        assertEquals( 2, andNodes.size() );

        // (&(|(...
        filter = searchRequest.getFilter();

        OrNode orNode = ( OrNode ) andNodes.get( 0 );
        assertNotNull( orNode );

        List<ExprNode> orNodes = orNode.getChildren();
        assertEquals( 1, orNodes.size() );

        // (&(|(&...
        AndNode andNode2 = ( AndNode ) orNodes.get( 0 );
        assertNotNull( andNode2 );

        List<ExprNode> andNodes2 = andNode2.getChildren();
        assertEquals( 1, andNodes2.size() );

        // (&(|(&(objectClass=groupOfNames)
        EqualityNode<?> equalityNode = ( EqualityNode<?> ) andNodes2.get( 0 );
        assertNotNull( equalityNode );

        assertEquals( "objectclass", equalityNode.getAttribute() );
        assertEquals( "groupofnames", equalityNode.getValue().getString() );

        // (&(|(&(objectClass=groupOfNames)))(owner=*))
        PresenceNode presenceNode = ( PresenceNode ) andNodes.get( 1 );
        assertNotNull( presenceNode );

        assertEquals( "owner", presenceNode.getAttribute() );
    }
}
