You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2010/08/18 01:31:55 UTC

svn commit: r986523 [6/6] - in /directory: apacheds/branches/apacheds-codec-merge/core-api/src/main/java/org/apache/directory/server/core/ apacheds/branches/apacheds-codec-merge/core-integ/src/test/java/org/apache/directory/server/core/operations/searc...

Modified: directory/shared/branches/shared-codec-merge/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestTest.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-codec-merge/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestTest.java?rev=986523&r1=986522&r2=986523&view=diff
==============================================================================
--- directory/shared/branches/shared-codec-merge/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestTest.java (original)
+++ directory/shared/branches/shared-codec-merge/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestTest.java Tue Aug 17 23:31:53 2010
@@ -40,17 +40,19 @@ import org.apache.directory.shared.asn1.
 import org.apache.directory.shared.asn1.codec.DecoderException;
 import org.apache.directory.shared.asn1.codec.EncoderException;
 import org.apache.directory.shared.ldap.codec.AttributeValueAssertion;
-import org.apache.directory.shared.ldap.codec.LdapConstants;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.ResponseCarryingException;
 import org.apache.directory.shared.ldap.codec.search.controls.subentries.SubentriesControl;
 import org.apache.directory.shared.ldap.constants.SchemaConstants;
-import org.apache.directory.shared.ldap.entry.EntryAttribute;
 import org.apache.directory.shared.ldap.filter.SearchScope;
+import org.apache.directory.shared.ldap.message.AliasDerefMode;
+import org.apache.directory.shared.ldap.message.LdapProtocolEncoder;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.message.SearchRequestImpl;
 import org.apache.directory.shared.ldap.message.SearchResultDoneImpl;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.ldap.message.internal.InternalMessage;
+import org.apache.directory.shared.ldap.message.internal.InternalSearchRequest;
 import org.apache.directory.shared.ldap.schema.normalizers.DeepTrimToLowerNormalizer;
 import org.apache.directory.shared.ldap.schema.normalizers.OidNormalizer;
 import org.apache.directory.shared.ldap.util.StringTools;
@@ -68,32 +70,35 @@ import org.junit.runner.RunWith;
 @Concurrent()
 public class SearchRequestTest
 {
-    static Map<String, OidNormalizer> oids = new HashMap<String, OidNormalizer>(); 
+    /** The encoder instance */
+    LdapProtocolEncoder encoder = new LdapProtocolEncoder();
+
+    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 ) );
-        
+        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 ) );
-        
+        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 ) );
-        
+        OidNormalizer objectClassOidNormalizer = new OidNormalizer( "objectClass", new DeepTrimToLowerNormalizer(
+            SchemaConstants.OBJECT_CLASS_AT_OID ) );
+
         oids.put( "objectclass", objectClassOidNormalizer );
         oids.put( "2.5.4.0", objectClassOidNormalizer );
     }
@@ -110,56 +115,57 @@ public class SearchRequestTest
 
         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]
-                                                        // AttributeValueAssertion,
-                                                        // AttributeValueAssertion ::= 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] AttributeValueAssertion,
-                                                        // AttributeValueAssertion ::= 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] AttributeValueAssertion,
-                                                        // AttributeValueAssertion ::= 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
+            { 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]
+                // AttributeValueAssertion,
+                // AttributeValueAssertion ::= 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] AttributeValueAssertion,
+                // AttributeValueAssertion ::= 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] AttributeValueAssertion,
+                // AttributeValueAssertion ::= 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 = StringTools.dumpBytes( stream.array() );
@@ -179,19 +185,20 @@ public class SearchRequestTest
         }
 
         assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );
-        
-        SearchRequestCodec searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
+
+        InternalSearchRequest searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
 
         assertEquals( 1, searchRequest.getMessageId() );
-        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBaseObject().toString() );
+        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBase().toString() );
         assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
-        assertEquals( LdapConstants.DEREF_ALWAYS, searchRequest.getDerefAliases() );
+        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
         assertEquals( 1000, searchRequest.getSizeLimit() );
         assertEquals( 1000, searchRequest.getTimeLimit() );
-        assertEquals( true, searchRequest.isTypesOnly() );
+        assertEquals( true, searchRequest.getTypesOnly() );
 
         // (& (...
-        AndFilter andFilter = ( AndFilter ) searchRequest.getFilter();
+        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        AndFilter andFilter = ( AndFilter ) filter;
         assertNotNull( andFilter );
 
         List<Filter> andFilters = andFilter.getAndFilter();
@@ -237,9 +244,9 @@ public class SearchRequestTest
         assertEquals( "objectclass", assertion.getAttributeDesc() );
         assertEquals( "ttt", assertion.getAssertionValue().getString() );
 
-        List<EntryAttribute> attributes = searchRequest.getAttributes();
+        List<String> attributes = searchRequest.getAttributes();
 
-        for ( EntryAttribute attribute:attributes )
+        for ( String attribute : attributes )
         {
             assertNotNull( attribute );
         }
@@ -249,7 +256,10 @@ public class SearchRequestTest
         // attributes may have been reordered
         try
         {
-            ByteBuffer bb = searchRequest.encode();
+            ByteBuffer bb = encoder.encodeMessage( searchRequest );
+
+            // Check the length
+            assertEquals( 0x90, bb.limit() );
 
             String encodedPdu = StringTools.dumpBytes( bb.array() );
 
@@ -275,55 +285,54 @@ public class SearchRequestTest
 
         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]
-                                                            // AttributeValueAssertion,
-                                                            // AttributeValueAssertion ::= 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] AttributeValueAssertion,
-                      0x04, 0x02,                           // AttributeValueAssertion ::= 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] AttributeValueAssertion,
-                                                            // AttributeValueAssertion ::= 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
+            { 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]
+                // AttributeValueAssertion,
+                // AttributeValueAssertion ::= 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] AttributeValueAssertion,
+                0x04, 0x02, // AttributeValueAssertion ::= 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] AttributeValueAssertion,
+                // AttributeValueAssertion ::= 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 = StringTools.dumpBytes( stream.array() );
@@ -343,19 +352,20 @@ public class SearchRequestTest
         }
 
         assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );
-        
-        SearchRequestCodec searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
+
+        InternalSearchRequest searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
 
         assertEquals( 1, searchRequest.getMessageId() );
-        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBaseObject().toString() );
+        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBase().toString() );
         assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
-        assertEquals( LdapConstants.DEREF_ALWAYS, searchRequest.getDerefAliases() );
+        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
         assertEquals( 1000, searchRequest.getSizeLimit() );
         assertEquals( 1000, searchRequest.getTimeLimit() );
-        assertEquals( true, searchRequest.isTypesOnly() );
+        assertEquals( true, searchRequest.getTypesOnly() );
 
         // (& (...
-        AndFilter andFilter = ( AndFilter ) searchRequest.getFilter();
+        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        AndFilter andFilter = ( AndFilter ) filter;
         assertNotNull( andFilter );
 
         List<Filter> andFilters = andFilter.getAndFilter();
@@ -402,22 +412,22 @@ public class SearchRequestTest
         assertEquals( "ttt", assertion.getAssertionValue().getString() );
 
         // The attributes
-        List<EntryAttribute> attributes = searchRequest.getAttributes();
+        List<String> attributes = searchRequest.getAttributes();
 
-        for ( EntryAttribute attribute:attributes )
+        for ( String attribute : attributes )
         {
             assertNotNull( attribute );
         }
 
-        // Check the length
-        assertEquals( 0x90, searchRequest.computeLength() );
-
         // Check the encoding
         // We won't check the whole PDU, as it may differs because
         // attributes may have been reordered
         try
         {
-            ByteBuffer bb = searchRequest.encode();
+            ByteBuffer bb = encoder.encodeMessage( searchRequest );
+
+            // Check the length
+            assertEquals( 0x0090, bb.limit() );
 
             String encodedPdu = StringTools.dumpBytes( bb.array() );
 
@@ -443,61 +453,61 @@ public class SearchRequestTest
 
         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]
-                                    // AttributeValueAssertion,
-                                    // AttributeValueAssertion ::= 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,
+                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]
+                // AttributeValueAssertion,
+                // AttributeValueAssertion ::= 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
+                // AttributeDescription
                 0x04, 0x05, 'a', 't', 't', 'r', '0', // AttributeDescription
-                                                        // ::= LDAPString
+                // ::= LDAPString
                 0x04, 0x05, 'a', 't', 't', 'r', '1', // AttributeDescription
-                                                        // ::= LDAPString
+                // ::= LDAPString
                 0x04, 0x05, 'a', 't', 't', 'r', '2' // AttributeDescription ::=
-                                                    // LDAPString
+            // LDAPString
             } );
 
         String decodedPdu = StringTools.dumpBytes( stream.array() );
@@ -517,19 +527,20 @@ public class SearchRequestTest
         }
 
         assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );
-        
-        SearchRequestCodec searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
+
+        InternalSearchRequest searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
 
         assertEquals( 1, searchRequest.getMessageId() );
-        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBaseObject().toString() );
+        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBase().toString() );
         assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
-        assertEquals( LdapConstants.DEREF_ALWAYS, searchRequest.getDerefAliases() );
+        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
         assertEquals( 1000, searchRequest.getSizeLimit() );
         assertEquals( 1000, searchRequest.getTimeLimit() );
-        assertEquals( true, searchRequest.isTypesOnly() );
+        assertEquals( true, searchRequest.getTypesOnly() );
 
         // (& (...
-        AndFilter andFilter = ( AndFilter ) searchRequest.getFilter();
+        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        AndFilter andFilter = ( AndFilter ) filter;
         assertNotNull( andFilter );
 
         List<Filter> andFilters = andFilter.getAndFilter();
@@ -569,22 +580,22 @@ public class SearchRequestTest
         assertEquals( "ttt", assertion.getAssertionValue().getString() );
 
         // The attributes
-        List<EntryAttribute> attributes = searchRequest.getAttributes();
+        List<String> attributes = searchRequest.getAttributes();
 
-        for ( EntryAttribute attribute:attributes )
+        for ( String attribute : attributes )
         {
             assertNotNull( attribute );
         }
 
-        // Check the length
-        assertEquals( 0x7B, searchRequest.computeLength() );
-
         // Check the encoding
         // We won't check the whole PDU, as it may differs because
         // attributes may have been reordered
         try
         {
-            ByteBuffer bb = searchRequest.encode();
+            ByteBuffer bb = encoder.encodeMessage( searchRequest );
+
+            // Check the length
+            assertEquals( 0x7B, bb.limit() );
 
             String encodedPdu = StringTools.dumpBytes( bb.array() );
 
@@ -609,11 +620,15 @@ public class SearchRequestTest
 
         ByteBuffer stream = ByteBuffer.allocate( 0x40 );
         stream.put( new byte[]
-            { 0x30, 0x37, // LDAPMessage ::=SEQUENCE {
-                0x02, 0x01, 0x03, // messageID MessageID
-                0x63, 0x32, // CHOICE { ..., searchRequest SearchRequest, ...
+            { 0x30,
+                0x37, // LDAPMessage ::=SEQUENCE {
+                0x02, 0x01,
+                0x03, // messageID MessageID
+                0x63,
+                0x32, // CHOICE { ..., searchRequest SearchRequest, ...
                 // SearchRequest ::= APPLICATION[3] SEQUENCE {
-                0x04, 0x12, // baseObject LDAPDN,
+                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),
@@ -628,15 +643,15 @@ public class SearchRequestTest
                 0x02, 0x01, 0x00,
                 // timeLimit INTEGER (0 .. maxInt), (infinite)
                 0x02, 0x01, 0x00, 0x01, 0x01, ( byte ) 0x00, // typesOnly
-                                                                // BOOLEAN,
-                                                                // (FALSE)
+                // 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
+                // AttributeDescription
                 0x00, 0x00, // Some trailing 00, useless.
                 0x00, 0x00, 0x00, 0x00 } );
 
@@ -657,34 +672,35 @@ public class SearchRequestTest
         }
 
         assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );
-        
-        SearchRequestCodec searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
+
+        InternalSearchRequest searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
 
         assertEquals( 3, searchRequest.getMessageId() );
-        assertEquals( "ou=users,ou=system", searchRequest.getBaseObject().toString() );
+        assertEquals( "ou=users,ou=system", searchRequest.getBase().toString() );
         assertEquals( SearchScope.OBJECT, searchRequest.getScope() );
-        assertEquals( LdapConstants.DEREF_ALWAYS, searchRequest.getDerefAliases() );
+        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
         assertEquals( 0, searchRequest.getSizeLimit() );
         assertEquals( 0, searchRequest.getTimeLimit() );
-        assertEquals( false, searchRequest.isTypesOnly() );
+        assertEquals( false, searchRequest.getTypesOnly() );
 
         // (objectClass = *)
-        PresentFilter presentFilter = ( PresentFilter ) searchRequest.getFilter();
+        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        PresentFilter presentFilter = ( PresentFilter ) filter;
         assertNotNull( presentFilter );
         assertEquals( "objectClass", presentFilter.getAttributeDescription() );
 
         // The attributes
-        List<EntryAttribute> attributes = searchRequest.getAttributes();
+        List<String> attributes = searchRequest.getAttributes();
 
         assertEquals( 0, attributes.size() );
 
-        // Check the length
-        assertEquals( 0x39, searchRequest.computeLength() );
-
         // Check the encoding
         try
         {
-            ByteBuffer bb = searchRequest.encode();
+            ByteBuffer bb = encoder.encodeMessage( searchRequest );
+
+            // Check the length
+            assertEquals( 0x39, bb.limit() );
 
             String encodedPdu = StringTools.dumpBytes( bb.array() );
 
@@ -697,6 +713,7 @@ public class SearchRequestTest
         }
     }
 
+
     /**
      * Test the decoding of a SearchRequest with an empty attribute. The search
      * filter is : (objectclass=*)
@@ -708,37 +725,39 @@ public class SearchRequestTest
 
         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
+            { 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();
@@ -757,28 +776,30 @@ public class SearchRequestTest
         }
 
         assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );
-        
-        SearchRequestCodec searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
+
+        InternalSearchRequest searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
 
         assertEquals( 3, searchRequest.getMessageId() );
-        assertEquals( "ou=users,ou=system", searchRequest.getBaseObject().toString() );
+        assertEquals( "ou=users,ou=system", searchRequest.getBase().toString() );
         assertEquals( SearchScope.OBJECT, searchRequest.getScope() );
-        assertEquals( LdapConstants.DEREF_ALWAYS, searchRequest.getDerefAliases() );
+        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
         assertEquals( 0, searchRequest.getSizeLimit() );
         assertEquals( 0, searchRequest.getTimeLimit() );
-        assertEquals( false, searchRequest.isTypesOnly() );
+        assertEquals( false, searchRequest.getTypesOnly() );
 
         // (objectClass = *)
-        PresentFilter presentFilter = ( PresentFilter ) searchRequest.getFilter();
+        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        PresentFilter presentFilter = ( PresentFilter ) filter;
         assertNotNull( presentFilter );
         assertEquals( "objectClass", presentFilter.getAttributeDescription() );
 
         // The attributes
-        List<EntryAttribute> attributes = searchRequest.getAttributes();
+        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=*)
@@ -790,37 +811,39 @@ public class SearchRequestTest
 
         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
+            { 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();
@@ -839,38 +862,39 @@ public class SearchRequestTest
         }
 
         assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );
-        
-        SearchRequestCodec searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
+
+        InternalSearchRequest searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
 
         assertEquals( 3, searchRequest.getMessageId() );
-        assertEquals( "ou=users,ou=system", searchRequest.getBaseObject().toString() );
+        assertEquals( "ou=users,ou=system", searchRequest.getBase().toString() );
         assertEquals( SearchScope.OBJECT, searchRequest.getScope() );
-        assertEquals( LdapConstants.DEREF_ALWAYS, searchRequest.getDerefAliases() );
+        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
         assertEquals( 0, searchRequest.getSizeLimit() );
         assertEquals( 0, searchRequest.getTimeLimit() );
-        assertEquals( false, searchRequest.isTypesOnly() );
+        assertEquals( false, searchRequest.getTypesOnly() );
 
         // (objectClass = *)
-        PresentFilter presentFilter = ( PresentFilter ) searchRequest.getFilter();
+        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        PresentFilter presentFilter = ( PresentFilter ) filter;
         assertNotNull( presentFilter );
         assertEquals( "objectClass", presentFilter.getAttributeDescription() );
 
         // The attributes
-        List<EntryAttribute> attributes = searchRequest.getAttributes();
+        List<String> attributes = searchRequest.getAttributes();
 
         assertEquals( 2, attributes.size() );
         Set<String> expectedAttrs = new HashSet<String>();
         expectedAttrs.add( "sn" );
         expectedAttrs.add( "*" );
-        
-        for ( EntryAttribute attribute:attributes )
+
+        for ( String attribute : attributes )
         {
-            assertTrue( expectedAttrs.contains( attribute.getId() ) );
-            expectedAttrs.remove( attribute.getId() );
+            assertTrue( expectedAttrs.contains( attribute ) );
+            expectedAttrs.remove( attribute );
         }
-        
+
         assertEquals( 0, expectedAttrs.size() );
-    }        
+    }
 
 
     /**
@@ -883,52 +907,30 @@ public class SearchRequestTest
 
         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
+            { 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 = StringTools.dumpBytes( stream.array() );
@@ -948,19 +950,19 @@ public class SearchRequestTest
         }
 
         assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );
-        
-        SearchRequestCodec searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
+
+        InternalSearchRequest searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
 
         assertEquals( 33, searchRequest.getMessageId() );
-        assertEquals( "dc=example,dc=com", searchRequest.getBaseObject().toString() );
+        assertEquals( "dc=example,dc=com", searchRequest.getBase().toString() );
         assertEquals( SearchScope.OBJECT, searchRequest.getScope() );
-        assertEquals( LdapConstants.DEREF_FINDING_BASE_OBJ, searchRequest.getDerefAliases() );
+        assertEquals( AliasDerefMode.DEREF_FINDING_BASE_OBJ, searchRequest.getDerefAliases() );
         assertEquals( 2, searchRequest.getSizeLimit() );
         assertEquals( 3, searchRequest.getTimeLimit() );
-        assertEquals( true, searchRequest.isTypesOnly() );
+        assertEquals( true, searchRequest.getTypesOnly() );
 
         // (objectclass=t*)
-        OrFilter orFilter = ( OrFilter ) searchRequest.getFilter();
+        OrFilter orFilter = ( OrFilter ) ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
         assertNotNull( orFilter );
         assertEquals( 5, orFilter.getFilterSet().size() );
 
@@ -996,22 +998,22 @@ public class SearchRequestTest
         assertEquals( "abok", assertion.getAssertionValue().getString() );
 
         // The attributes
-        List<EntryAttribute> attributes = searchRequest.getAttributes();
+        List<String> attributes = searchRequest.getAttributes();
 
-        for ( EntryAttribute attribute:attributes )
+        for ( String attribute : attributes )
         {
             assertNotNull( attribute );
         }
 
-        // Check the length
-        assertEquals( 0x96, searchRequest.computeLength() );
-
         // Check the encoding
         // We won't check the whole PDU, as it may differs because
         // attributes may have been reordered
         try
         {
-            ByteBuffer bb = searchRequest.encode();
+            ByteBuffer bb = encoder.encodeMessage( searchRequest );
+
+            // Check the length
+            assertEquals( 0x0096, bb.limit() );
 
             String encodedPdu = StringTools.dumpBytes( bb.array() );
 
@@ -1032,37 +1034,49 @@ public class SearchRequestTest
     public void testDecodeSearchRequestWithControls()
     {
         byte[] asn1BER = 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',
-            };
+            { 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', };
 
         Asn1Decoder ldapDecoder = new Asn1Decoder();
 
@@ -1084,36 +1098,41 @@ public class SearchRequestTest
         }
 
         assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );
-        SearchRequestCodec searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
-        
+        InternalSearchRequest searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
+
         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.getControls( 0 );
+        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.getControls( 1 );
+        Control manageReferralControl = searchRequest.getControl( manageReferralControlOID );
         assertEquals( manageReferralControlOID, manageReferralControl.getOid() );
 
-        assertEquals( "dc=my-domain,dc=com", searchRequest.getBaseObject().toString() );
+        assertEquals( "dc=my-domain,dc=com", searchRequest.getBase().toString() );
         assertEquals( SearchScope.SUBTREE, searchRequest.getScope() );
-        assertEquals( LdapConstants.DEREF_ALWAYS, searchRequest.getDerefAliases() );
+        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
         assertEquals( 0, searchRequest.getSizeLimit() );
         assertEquals( 0, searchRequest.getTimeLimit() );
-        assertEquals( false, searchRequest.isTypesOnly() );
+        assertEquals( false, searchRequest.getTypesOnly() );
 
-        assertTrue( searchRequest.getFilter() instanceof PresentFilter );
-        assertEquals( "objectClass", ( ( PresentFilter ) searchRequest.getFilter() ).getAttributeDescription() );
+        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        assertTrue( filter instanceof PresentFilter );
+        assertEquals( "objectClass", ( ( PresentFilter ) filter ).getAttributeDescription() );
 
         // Check the encoding
         try
         {
-            ByteBuffer bb = searchRequest.encode();
+            ByteBuffer bb = encoder.encodeMessage( searchRequest );
+
+            // Check the length
+            assertEquals( 0x81, bb.limit() );
+
             String encodedPdu = StringTools.dumpBytes( bb.array() );
             assertEquals( decodedPdu, encodedPdu );
         }
@@ -1137,21 +1156,39 @@ public class SearchRequestTest
 
         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, ...
+            {
+                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,
+                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
-                                                                                            // {
+                '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 {
+                0x0A,
+                0x01,
+                0x03, // derefAliases ENUMERATED {
                 // neverDerefAliases (0),
                 // derefInSearching (1),
                 // derefFindingBaseObj (2),
@@ -1159,33 +1196,50 @@ public class SearchRequestTest
                 // 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)
+                0x02, 0x02, 0x03,
+                ( byte ) 0xE8,
+                0x01,
+                0x01,
+                ( byte ) 0xFF, // typesOnly
+                // BOOLEAN,
+                // (TRUE)
                 // filter Filter,
-                ( byte ) 0xA0, 0x4D, // Filter ::= CHOICE {
+                ( byte ) 0xA0,
+                0x4D, // Filter ::= CHOICE {
                 // and [0] SET OF Filter,
-                  ( byte ) 0xA1, 0x2A, // or [1] SET of Filter,
-                    ( byte ) 0xA3, 0x12, // equalityMatch [3]
-                                        // AttributeValueAssertion,
+                ( byte ) 0xA1,
+                0x2A, // or [1] SET of Filter,
+                ( byte ) 0xA3,
+                0x12, // equalityMatch [3]
+                // AttributeValueAssertion,
                 // AttributeValueAssertion ::= SEQUENCE {
                 // attributeDesc AttributeDescription (LDAPString),
-                      0x04, 0x0B, 'o', 'b', 'j', 'e', 'c', 't', 'c', 'l', 'a', 's', 's',
+                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]
-                                                                // AttributeValueAssertion,
-                // AttributeValueAssertion ::= SEQUENCE {
-                0x04, 0x08, '2', '.', '5', '.', '4', '.', '1', '1', // attributeDesc
-                                                                    // AttributeDescription
-                                                                    // (LDAPString),
+                0x04, 0x03, 't', 'o',
+                'p',
+                ( byte ) 0xA3,
+                0x14, // equalityMatch
+                // [3]
+                // AttributeValueAssertion,
+                // AttributeValueAssertion ::= 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]
-                                        // AttributeValueAssertion,
+                0x04, 0x08, 'c', 'o', 'n', 't', 'a', 'c',
+                't',
+                's',
+                ( byte ) 0xA2,
+                0x1F, // not
+                // [2]
+                // Filter,
+                ( byte ) 0xA3,
+                0x1D, // equalityMatch [3]
+                // AttributeValueAssertion,
                 // AttributeValueAssertion ::= SEQUENCE {
                 // attributeDesc AttributeDescription (LDAPString),
                 0x04, 0x16, 'o', 'r', 'g', 'a', 'n', 'i', 'z', 'a', 't', 'i', 'o', 'n', 'a', 'l', 'U', 'n', 'i', 't',
@@ -1194,13 +1248,13 @@ public class SearchRequestTest
                 0x04, 0x03, 't', 't', 't',
                 // attributes AttributeDescriptionList }
                 0x30, 0x15, // AttributeDescriptionList ::= SEQUENCE OF
-                            // AttributeDescription
+                // AttributeDescription
                 0x04, 0x05, 'a', 't', 't', 'r', '0', // AttributeDescription
-                                                        // ::= LDAPString
+                // ::= LDAPString
                 0x04, 0x05, 'a', 't', 't', 'r', '1', // AttributeDescription
-                                                        // ::= LDAPString
+                // ::= LDAPString
                 0x04, 0x05, 'a', 't', 't', 'r', '2' // AttributeDescription ::=
-                                                    // LDAPString
+            // LDAPString
             } );
 
         stream.flip();
@@ -1219,19 +1273,20 @@ public class SearchRequestTest
         }
 
         assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );
-        
-        SearchRequestCodec searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
+
+        InternalSearchRequest searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
 
         assertEquals( 1, searchRequest.getMessageId() );
-        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBaseObject().toString() );
+        assertEquals( "uid=akarasulu,dc=example,dc=com", searchRequest.getBase().toString() );
         assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
-        assertEquals( LdapConstants.DEREF_ALWAYS, searchRequest.getDerefAliases() );
+        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
         assertEquals( 1000, searchRequest.getSizeLimit() );
         assertEquals( 1000, searchRequest.getTimeLimit() );
-        assertEquals( true, searchRequest.isTypesOnly() );
+        assertEquals( true, searchRequest.getTypesOnly() );
 
         // (& (...
-        AndFilter andFilter = ( AndFilter ) searchRequest.getFilter();
+        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        AndFilter andFilter = ( AndFilter ) filter;
         assertNotNull( andFilter );
 
         List<Filter> andFilters = andFilter.getAndFilter();
@@ -1277,9 +1332,9 @@ public class SearchRequestTest
         assertEquals( "organizationalUnitName", assertion.getAttributeDesc() );
         assertEquals( "ttt", assertion.getAssertionValue().getString() );
 
-        List<EntryAttribute> attributes = searchRequest.getAttributes();
+        List<String> attributes = searchRequest.getAttributes();
 
-        for ( EntryAttribute attribute:attributes )
+        for ( String attribute : attributes )
         {
             assertNotNull( attribute );
         }
@@ -1296,29 +1351,31 @@ public class SearchRequestTest
     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
+            { 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();
@@ -1341,33 +1398,38 @@ public class SearchRequestTest
         }
 
         assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );
-        SearchRequestCodec searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
-        
+        InternalSearchRequest searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
+
         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.getControls( 0 );
+        Control subEntryControl = searchRequest.getControl( subEntryControlOID );
         assertEquals( subEntryControlOID, subEntryControl.getOid() );
         assertTrue( subEntryControl.isCritical() );
         assertTrue( subEntryControl instanceof SubentriesControl );
-        assertTrue( ((SubentriesControl)subEntryControl).isVisible() );
+        assertTrue( ( ( SubentriesControl ) subEntryControl ).isVisible() );
 
-        assertEquals( "dc=my-domain,dc=com", searchRequest.getBaseObject().toString() );
+        assertEquals( "dc=my-domain,dc=com", searchRequest.getBase().toString() );
         assertEquals( SearchScope.SUBTREE, searchRequest.getScope() );
-        assertEquals( LdapConstants.DEREF_ALWAYS, searchRequest.getDerefAliases() );
+        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
         assertEquals( 0, searchRequest.getSizeLimit() );
         assertEquals( 0, searchRequest.getTimeLimit() );
-        assertEquals( false, searchRequest.isTypesOnly() );
+        assertEquals( false, searchRequest.getTypesOnly() );
 
-        assertTrue( searchRequest.getFilter() instanceof PresentFilter );
-        assertEquals( "objectClass", ( ( PresentFilter ) searchRequest.getFilter() ).getAttributeDescription() );
+        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        assertTrue( filter instanceof PresentFilter );
+        assertEquals( "objectClass", ( ( PresentFilter ) filter ).getAttributeDescription() );
 
         // Check the encoding
         try
         {
-            ByteBuffer bb = searchRequest.encode();
+            ByteBuffer bb = encoder.encodeMessage( searchRequest );
+
+            // Check the length
+            assertEquals( 0x5F, bb.limit() );
+
             String encodedPdu = StringTools.dumpBytes( bb.array() );
             assertEquals( decodedPdu, encodedPdu );
         }
@@ -1421,12 +1483,8 @@ public class SearchRequestTest
     public void testDecodeSearchRequestBaseDnOnly()
     {
         byte[] asn1BER = new byte[]
-            { 
-            0x30, 0x07, 
-              0x02, 0x01, 0x04, // messageID
-              0x63, 0x02, 
-                0x04, 0x00 
-            };
+            { 0x30, 0x07, 0x02, 0x01, 0x04, // messageID
+                0x63, 0x02, 0x04, 0x00 };
 
         Asn1Decoder ldapDecoder = new Asn1Decoder();
 
@@ -1451,6 +1509,7 @@ public class SearchRequestTest
         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)))
@@ -1462,54 +1521,51 @@ public class SearchRequestTest
 
         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]
-                                                        // AttributeValueAssertion,
-                                                        // AttributeValueAssertion ::= 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] AttributeValueAssertion,
-                                                        // AttributeValueAssertion ::= 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] AttributeValueAssertion,
-                                                        // AttributeValueAssertion ::= 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
+            { 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]
+                // AttributeValueAssertion,
+                // AttributeValueAssertion ::= 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] AttributeValueAssertion,
+                // AttributeValueAssertion ::= 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] AttributeValueAssertion,
+                // AttributeValueAssertion ::= 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 = StringTools.dumpBytes( stream.array() );
@@ -1529,19 +1585,20 @@ public class SearchRequestTest
         }
 
         assertEquals( TLVStateEnum.PDU_DECODED, ldapMessageContainer.getState() );
-        
-        SearchRequestCodec searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
+
+        InternalSearchRequest searchRequest = ( ( LdapMessageContainer ) ldapMessageContainer ).getSearchRequest();
 
         assertEquals( 1, searchRequest.getMessageId() );
-        assertEquals( "", searchRequest.getBaseObject().toString() );
+        assertEquals( "", searchRequest.getBase().toString() );
         assertEquals( SearchScope.ONELEVEL, searchRequest.getScope() );
-        assertEquals( LdapConstants.DEREF_ALWAYS, searchRequest.getDerefAliases() );
+        assertEquals( AliasDerefMode.DEREF_ALWAYS, searchRequest.getDerefAliases() );
         assertEquals( 1000, searchRequest.getSizeLimit() );
         assertEquals( 1000, searchRequest.getTimeLimit() );
-        assertEquals( true, searchRequest.isTypesOnly() );
+        assertEquals( true, searchRequest.getTypesOnly() );
 
         // (& (...
-        AndFilter andFilter = ( AndFilter ) searchRequest.getFilter();
+        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        AndFilter andFilter = ( AndFilter ) filter;
         assertNotNull( andFilter );
 
         List<Filter> andFilters = andFilter.getAndFilter();
@@ -1587,9 +1644,9 @@ public class SearchRequestTest
         assertEquals( "objectclass", assertion.getAttributeDesc() );
         assertEquals( "ttt", assertion.getAssertionValue().getString() );
 
-        List<EntryAttribute> attributes = searchRequest.getAttributes();
+        List<String> attributes = searchRequest.getAttributes();
 
-        for ( EntryAttribute attribute:attributes )
+        for ( String attribute : attributes )
         {
             assertNotNull( attribute );
         }
@@ -1599,7 +1656,10 @@ public class SearchRequestTest
         // attributes may have been reordered
         try
         {
-            ByteBuffer bb = searchRequest.encode();
+            ByteBuffer bb = encoder.encodeMessage( searchRequest );
+
+            // Check the length
+            assertEquals( 0x6F, bb.limit() );
 
             String encodedPdu = StringTools.dumpBytes( bb.array() );
 
@@ -1612,6 +1672,7 @@ public class SearchRequestTest
         }
     }
 
+
     /**
      * Test the decoding of a SearchRequest with a bad objectBase
      */
@@ -1622,58 +1683,59 @@ public class SearchRequestTest
 
         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 {

[... 3079 lines stripped ...]