hiding message implementations

git-svn-id: https://svn.apache.org/repos/asf/directory/shared/branches/alex_refactoring@1056056 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dsml-engine/src/main/java/org/apache/directory/shared/dsmlv2/engine/Dsmlv2Engine.java b/dsml-engine/src/main/java/org/apache/directory/shared/dsmlv2/engine/Dsmlv2Engine.java
index b20c535..db62db6 100644
--- a/dsml-engine/src/main/java/org/apache/directory/shared/dsmlv2/engine/Dsmlv2Engine.java
+++ b/dsml-engine/src/main/java/org/apache/directory/shared/dsmlv2/engine/Dsmlv2Engine.java
@@ -452,7 +452,7 @@
      */
     private void bind( int messageId ) throws LdapException, EncoderException, DecoderException, IOException
     {
-        BindRequest bindRequest = new BindRequestImpl();
+        BindRequest bindRequest = new org.apache.directory.shared.ldap.codec.message.BindRequestImpl();
         bindRequest.setSimple( true );
         bindRequest.setCredentials( Strings.getBytesUtf8(password) );
         bindRequest.setName( new DN( user ) );
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/AddResponseDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/AddResponseDsml.java
index 391c451..fda501c 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/AddResponseDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/AddResponseDsml.java
@@ -23,7 +23,6 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.AddResponse;
-import org.apache.directory.shared.ldap.message.AddResponseImpl;
 import org.dom4j.Element;
 
 
@@ -39,7 +38,7 @@
      */
     public AddResponseDsml()
     {
-        super( new AddResponseImpl() );
+        super( new org.apache.directory.shared.ldap.codec.message.AddResponseImpl() );
     }
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/AuthResponseDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/AuthResponseDsml.java
index 63c2fab..4a7edfc 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/AuthResponseDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/AuthResponseDsml.java
@@ -23,7 +23,7 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.BindResponse;
-import org.apache.directory.shared.ldap.message.BindResponseImpl;
+import org.apache.directory.shared.ldap.codec.message.BindResponseImpl;
 import org.dom4j.Element;
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/CompareResponseDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/CompareResponseDsml.java
index be530df..7333a71 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/CompareResponseDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/CompareResponseDsml.java
@@ -23,7 +23,7 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.CompareResponse;
-import org.apache.directory.shared.ldap.message.CompareResponseImpl;
+import org.apache.directory.shared.ldap.codec.message.CompareResponseImpl;
 import org.dom4j.Element;
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/DelResponseDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/DelResponseDsml.java
index 6f90cf9..db70063 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/DelResponseDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/DelResponseDsml.java
@@ -23,7 +23,6 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.DeleteResponse;
-import org.apache.directory.shared.ldap.message.DeleteResponseImpl;
 import org.dom4j.Element;
 
 
@@ -39,7 +38,7 @@
      */
     public DelResponseDsml()
     {
-        super( new DeleteResponseImpl() );
+        super( new org.apache.directory.shared.ldap.codec.message.DeleteResponseImpl() );
     }
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/Dsmlv2ResponseGrammar.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/Dsmlv2ResponseGrammar.java
index 48f33d2..1f5c0c4 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/Dsmlv2ResponseGrammar.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/Dsmlv2ResponseGrammar.java
@@ -44,31 +44,24 @@
 import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
 import org.apache.directory.shared.ldap.message.AddResponse;
-import org.apache.directory.shared.ldap.message.AddResponseImpl;
+import org.apache.directory.shared.ldap.codec.message.AddResponseImpl;
 import org.apache.directory.shared.ldap.message.BindResponse;
-import org.apache.directory.shared.ldap.message.BindResponseImpl;
 import org.apache.directory.shared.ldap.message.CompareResponse;
-import org.apache.directory.shared.ldap.message.CompareResponseImpl;
 import org.apache.directory.shared.ldap.message.DeleteResponse;
-import org.apache.directory.shared.ldap.message.DeleteResponseImpl;
 import org.apache.directory.shared.ldap.message.ExtendedResponse;
-import org.apache.directory.shared.ldap.message.ExtendedResponseImpl;
 import org.apache.directory.shared.ldap.message.LdapResult;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.ModifyDnResponse;
-import org.apache.directory.shared.ldap.message.ModifyDnResponseImpl;
+import org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl;
 import org.apache.directory.shared.ldap.message.ModifyResponse;
-import org.apache.directory.shared.ldap.message.ModifyResponseImpl;
-import org.apache.directory.shared.ldap.message.ReferralImpl;
+import org.apache.directory.shared.ldap.codec.message.ReferralImpl;
 import org.apache.directory.shared.ldap.message.Response;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.ResultResponse;
 import org.apache.directory.shared.ldap.message.SearchResultDone;
-import org.apache.directory.shared.ldap.message.SearchResultDoneImpl;
 import org.apache.directory.shared.ldap.message.SearchResultEntry;
-import org.apache.directory.shared.ldap.message.SearchResultEntryImpl;
 import org.apache.directory.shared.ldap.message.SearchResultReference;
-import org.apache.directory.shared.ldap.message.SearchResultReferenceImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchResultReferenceImpl;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.ldap.name.DN;
 import org.apache.directory.shared.util.Base64;
@@ -833,7 +826,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            BindResponse bindResponse = new BindResponseImpl();
+            BindResponse bindResponse = new org.apache.directory.shared.ldap.codec.message.BindResponseImpl();
 
             container.getBatchResponse().addResponse( bindResponse );
 
@@ -876,7 +869,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            CompareResponse compareResponse = new CompareResponseImpl();
+            CompareResponse compareResponse = new org.apache.directory.shared.ldap.codec.message.CompareResponseImpl();
 
             container.getBatchResponse().addResponse( compareResponse );
 
@@ -918,7 +911,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            DeleteResponse delResponse = new DeleteResponseImpl();
+            DeleteResponse delResponse = new org.apache.directory.shared.ldap.codec.message.DeleteResponseImpl();
 
             container.getBatchResponse().addResponse( delResponse );
 
@@ -960,7 +953,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            ModifyResponse modifyResponse = new ModifyResponseImpl();
+            ModifyResponse modifyResponse = new org.apache.directory.shared.ldap.codec.message.ModifyResponseImpl();
 
             container.getBatchResponse().addResponse( modifyResponse );
 
@@ -1056,11 +1049,11 @@
 
             if ( attributeValue != null )
             {
-                extendedResponse = new ExtendedResponseImpl( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
+                extendedResponse = new org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
             }
             else
             {
-                extendedResponse = new ExtendedResponseImpl( -1 );
+                extendedResponse = new org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl( -1 );
             }
 
             container.getBatchResponse().addResponse( extendedResponse );
@@ -1554,7 +1547,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchResultEntry searchResultEntry = new SearchResultEntryImpl();
+            SearchResultEntry searchResultEntry = new org.apache.directory.shared.ldap.codec.message.SearchResultEntryImpl();
 
             SearchResponse searchResponse = ( SearchResponse ) container.getBatchResponse().getCurrentResponse();
 
@@ -1629,7 +1622,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchResultDone searchResultDone = new SearchResultDoneImpl();
+            SearchResultDone searchResultDone = new org.apache.directory.shared.ldap.codec.message.SearchResultDoneImpl();
 
             searchResultDone.getLdapResult();
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ExtendedResponseDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ExtendedResponseDsml.java
index 3dea004..32e0276 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ExtendedResponseDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ExtendedResponseDsml.java
@@ -25,7 +25,7 @@
 import org.apache.directory.shared.dsmlv2.ParserUtils;
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.ExtendedResponse;
-import org.apache.directory.shared.ldap.message.ExtendedResponseImpl;
+import org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl;
 import org.apache.directory.shared.util.Strings;
 import org.dom4j.Element;
 import org.dom4j.Namespace;
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ModDNResponseDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ModDNResponseDsml.java
index 4934349..badab35 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ModDNResponseDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ModDNResponseDsml.java
@@ -23,7 +23,7 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.ModifyDnResponse;
-import org.apache.directory.shared.ldap.message.ModifyDnResponseImpl;
+import org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl;
 import org.dom4j.Element;
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ModifyResponseDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ModifyResponseDsml.java
index 0ac9a39..a375f85 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ModifyResponseDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/ModifyResponseDsml.java
@@ -23,7 +23,6 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.ModifyResponse;
-import org.apache.directory.shared.ldap.message.ModifyResponseImpl;
 import org.dom4j.Element;
 
 
@@ -39,7 +38,7 @@
      */
     public ModifyResponseDsml()
     {
-        super( new ModifyResponseImpl() );
+        super( new org.apache.directory.shared.ldap.codec.message.ModifyResponseImpl() );
     }
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultDoneDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultDoneDsml.java
index 93ea3a4..4684258 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultDoneDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultDoneDsml.java
@@ -23,7 +23,6 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.SearchResultDone;
-import org.apache.directory.shared.ldap.message.SearchResultDoneImpl;
 import org.dom4j.Element;
 
 
@@ -39,7 +38,7 @@
      */
     public SearchResultDoneDsml()
     {
-        super( new SearchResultDoneImpl() );
+        super( new org.apache.directory.shared.ldap.codec.message.SearchResultDoneImpl() );
     }
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultEntryDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultEntryDsml.java
index 3a56fad..0c2f41c 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultEntryDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultEntryDsml.java
@@ -28,7 +28,6 @@
 import org.apache.directory.shared.ldap.entry.Value;
 import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.message.SearchResultEntry;
-import org.apache.directory.shared.ldap.message.SearchResultEntryImpl;
 import org.apache.directory.shared.ldap.name.DN;
 import org.dom4j.Element;
 import org.dom4j.Namespace;
@@ -47,7 +46,7 @@
      */
     public SearchResultEntryDsml()
     {
-        super( new SearchResultEntryImpl() );
+        super( new org.apache.directory.shared.ldap.codec.message.SearchResultEntryImpl() );
     }
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultReferenceDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultReferenceDsml.java
index a6709ae..9fe2aee 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultReferenceDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/reponse/SearchResultReferenceDsml.java
@@ -26,7 +26,7 @@
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.SearchResultReference;
-import org.apache.directory.shared.ldap.message.SearchResultReferenceImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchResultReferenceImpl;
 import org.apache.directory.shared.ldap.util.LdapURL;
 import org.dom4j.Element;
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AbandonRequestDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AbandonRequestDsml.java
index 63c1000..f9505d7 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AbandonRequestDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AbandonRequestDsml.java
@@ -22,7 +22,7 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.AbandonRequest;
-import org.apache.directory.shared.ldap.message.AbandonRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.AbandonRequestImpl;
 import org.dom4j.Element;
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AddRequestDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AddRequestDsml.java
index 647ff08..f1195ed 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AddRequestDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AddRequestDsml.java
@@ -27,7 +27,6 @@
 import org.apache.directory.shared.ldap.entry.Value;
 import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.message.AddRequest;
-import org.apache.directory.shared.ldap.message.AddRequestImpl;
 import org.apache.directory.shared.ldap.name.DN;
 import org.dom4j.Element;
 import org.dom4j.Namespace;
@@ -46,7 +45,7 @@
      */
     public AddRequestDsml()
     {
-        super( new AddRequestImpl() );
+        super( new org.apache.directory.shared.ldap.codec.message.AddRequestImpl() );
     }
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AuthRequestDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AuthRequestDsml.java
index fcd3023..c26e380 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AuthRequestDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/AuthRequestDsml.java
@@ -22,7 +22,7 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.BindRequest;
-import org.apache.directory.shared.ldap.message.BindRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.BindRequestImpl;
 import org.dom4j.Element;
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/CompareRequestDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/CompareRequestDsml.java
index 87dea57..84c4e83 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/CompareRequestDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/CompareRequestDsml.java
@@ -22,7 +22,7 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.CompareRequest;
-import org.apache.directory.shared.ldap.message.CompareRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.CompareRequestImpl;
 import org.apache.directory.shared.ldap.name.DN;
 import org.dom4j.Element;
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/DelRequestDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/DelRequestDsml.java
index 7a491fa..617dae0 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/DelRequestDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/DelRequestDsml.java
@@ -22,7 +22,6 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.DeleteRequest;
-import org.apache.directory.shared.ldap.message.DeleteRequestImpl;
 import org.apache.directory.shared.ldap.name.DN;
 import org.dom4j.Element;
 
@@ -39,7 +38,7 @@
      */
     public DelRequestDsml()
     {
-        super( new DeleteRequestImpl() );
+        super( new org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl() );
     }
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/Dsmlv2Grammar.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/Dsmlv2Grammar.java
index 286d368..ac6ed31 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/Dsmlv2Grammar.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/Dsmlv2Grammar.java
@@ -57,24 +57,21 @@
 import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
 import org.apache.directory.shared.ldap.filter.SearchScope;
 import org.apache.directory.shared.ldap.message.AbandonRequest;
-import org.apache.directory.shared.ldap.message.AbandonRequestImpl;
 import org.apache.directory.shared.ldap.message.AddRequest;
-import org.apache.directory.shared.ldap.message.AddRequestImpl;
 import org.apache.directory.shared.ldap.message.AliasDerefMode;
 import org.apache.directory.shared.ldap.message.BindRequest;
-import org.apache.directory.shared.ldap.message.BindRequestImpl;
 import org.apache.directory.shared.ldap.message.CompareRequest;
-import org.apache.directory.shared.ldap.message.CompareRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.CompareRequestImpl;
 import org.apache.directory.shared.ldap.message.DeleteRequest;
-import org.apache.directory.shared.ldap.message.DeleteRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl;
 import org.apache.directory.shared.ldap.message.ExtendedRequest;
-import org.apache.directory.shared.ldap.message.ExtendedRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.ExtendedRequestImpl;
 import org.apache.directory.shared.ldap.message.ModifyDnRequest;
-import org.apache.directory.shared.ldap.message.ModifyDnRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.ModifyDnRequestImpl;
 import org.apache.directory.shared.ldap.message.ModifyRequest;
-import org.apache.directory.shared.ldap.message.ModifyRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.ldap.name.DN;
 import org.apache.directory.shared.ldap.name.RDN;
@@ -1137,7 +1134,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            AbandonRequest abandonRequest = new AbandonRequestImpl();
+            AbandonRequest abandonRequest = new org.apache.directory.shared.ldap.codec.message.AbandonRequestImpl();
             container.getBatchRequest().addRequest( abandonRequest );
 
             XmlPullParser xpp = container.getParser();
@@ -1184,7 +1181,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            AddRequest addRequest = new AddRequestImpl();
+            AddRequest addRequest = new org.apache.directory.shared.ldap.codec.message.AddRequestImpl();
             container.getBatchRequest().addRequest( addRequest );
 
             XmlPullParser xpp = container.getParser();
@@ -1300,7 +1297,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            BindRequest authRequest = new BindRequestImpl();
+            BindRequest authRequest = new org.apache.directory.shared.ldap.codec.message.BindRequestImpl();
             container.getBatchRequest().addRequest( authRequest );
 
             authRequest.setSimple( true );
@@ -1734,7 +1731,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            ModifyRequest modifyRequest = new ModifyRequestImpl();
+            ModifyRequest modifyRequest = new org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl();
             container.getBatchRequest().addRequest( modifyRequest );
 
             XmlPullParser xpp = container.getParser();
@@ -1876,7 +1873,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequest searchRequest = new SearchRequestImpl();
+            SearchRequest searchRequest = new org.apache.directory.shared.ldap.codec.message.SearchRequestImpl();
             container.getBatchRequest().addRequest( searchRequest );
 
             XmlPullParser xpp = container.getParser();
@@ -2071,7 +2068,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
 
             XmlPullParser xpp = container.getParser();
 
@@ -2111,7 +2108,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
             SubstringFilter substringFilter = ( SubstringFilter ) searchRequest.getTerminalFilter();
 
             XmlPullParser xpp = container.getParser();
@@ -2151,7 +2148,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
             SubstringFilter substringFilter = ( SubstringFilter ) searchRequest.getTerminalFilter();
 
             XmlPullParser xpp = container.getParser();
@@ -2230,7 +2227,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
 
             searchRequest.setTerminalFilter( null );
         }
@@ -2243,7 +2240,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
 
             XmlPullParser xpp = container.getParser();
 
@@ -2268,7 +2265,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
 
             Filter filter = searchRequest.getCurrentFilter().getParent();
 
@@ -2283,7 +2280,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
 
             XmlPullParser xpp = container.getParser();
 
@@ -2308,7 +2305,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
 
             XmlPullParser xpp = container.getParser();
 
@@ -2333,7 +2330,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
 
             XmlPullParser xpp = container.getParser();
 
@@ -2377,7 +2374,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
 
             XmlPullParser xpp = container.getParser();
 
@@ -2421,7 +2418,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
 
             XmlPullParser xpp = container.getParser();
 
@@ -2467,7 +2464,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
 
             XmlPullParser xpp = container.getParser();
 
@@ -2510,7 +2507,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
             AttributeValueAssertionFilter filter = ( AttributeValueAssertionFilter ) searchRequest.getTerminalFilter();
             AttributeValueAssertion assertion = filter.getAssertion();
 
@@ -2557,7 +2554,7 @@
             XmlPullParser xpp = container.getParser();
 
             // Adding the filter to the Search Filter
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
 
             try
             {
@@ -2596,7 +2593,7 @@
             XmlPullParser xpp = container.getParser();
 
             // Adding the filter to the Search Filter
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
 
             try
             {
@@ -2659,7 +2656,7 @@
     {
         public void action( Dsmlv2Container container ) throws XmlPullParserException
         {
-            SearchRequestImpl searchRequest = ( SearchRequestImpl ) container.getBatchRequest().getCurrentRequest();
+            org.apache.directory.shared.ldap.codec.message.SearchRequestImpl searchRequest = (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) container.getBatchRequest().getCurrentRequest();
             ExtensibleMatchFilter filter = ( ExtensibleMatchFilter ) searchRequest.getTerminalFilter();
 
             XmlPullParser xpp = container.getParser();
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ExtendedRequestDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ExtendedRequestDsml.java
index bfca469..8d1280a 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ExtendedRequestDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ExtendedRequestDsml.java
@@ -24,7 +24,6 @@
 import org.apache.directory.shared.dsmlv2.ParserUtils;
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.ExtendedRequest;
-import org.apache.directory.shared.ldap.message.ExtendedRequestImpl;
 import org.dom4j.Element;
 import org.dom4j.Namespace;
 import org.dom4j.QName;
@@ -42,7 +41,7 @@
      */
     public ExtendedRequestDsml()
     {
-        super( new ExtendedRequestImpl() );
+        super( new org.apache.directory.shared.ldap.codec.message.ExtendedRequestImpl() );
     }
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ModifyDNRequestDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ModifyDNRequestDsml.java
index 443c9a5..a61ffee 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ModifyDNRequestDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ModifyDNRequestDsml.java
@@ -22,7 +22,7 @@
 
 import org.apache.directory.shared.ldap.message.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.ModifyDnRequest;
-import org.apache.directory.shared.ldap.message.ModifyDnRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.ModifyDnRequestImpl;
 import org.apache.directory.shared.ldap.name.DN;
 import org.apache.directory.shared.ldap.name.RDN;
 import org.dom4j.Element;
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ModifyRequestDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ModifyRequestDsml.java
index 7f2caed..3bde6ad 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ModifyRequestDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/ModifyRequestDsml.java
@@ -29,7 +29,6 @@
 import org.apache.directory.shared.ldap.entry.ModificationOperation;
 import org.apache.directory.shared.ldap.entry.Value;
 import org.apache.directory.shared.ldap.message.ModifyRequest;
-import org.apache.directory.shared.ldap.message.ModifyRequestImpl;
 import org.dom4j.Element;
 import org.dom4j.Namespace;
 import org.dom4j.QName;
@@ -47,7 +46,7 @@
      */
     public ModifyRequestDsml()
     {
-        super( new ModifyRequestImpl() );
+        super( new org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl() );
     }
 
 
diff --git a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/SearchRequestDsml.java b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/SearchRequestDsml.java
index 0f7a586..fa0d0e3 100644
--- a/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/SearchRequestDsml.java
+++ b/dsml-parser/src/main/java/org/apache/directory/shared/dsmlv2/request/SearchRequestDsml.java
@@ -38,7 +38,6 @@
 import org.apache.directory.shared.ldap.filter.SubstringNode;
 import org.apache.directory.shared.ldap.message.AliasDerefMode;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
 import org.dom4j.Element;
 import org.dom4j.Namespace;
 import org.dom4j.QName;
@@ -56,7 +55,7 @@
      */
     public SearchRequestDsml()
     {
-        super( new SearchRequestImpl() );
+        super( new org.apache.directory.shared.ldap.codec.message.SearchRequestImpl() );
     }
 
 
diff --git a/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapNetworkConnection.java b/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapNetworkConnection.java
index 5990a80..2de3397 100644
--- a/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapNetworkConnection.java
+++ b/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapNetworkConnection.java
@@ -78,42 +78,37 @@
 import org.apache.directory.shared.ldap.exception.LdapOperationException;
 import org.apache.directory.shared.ldap.filter.SearchScope;
 import org.apache.directory.shared.ldap.message.AbandonRequest;
-import org.apache.directory.shared.ldap.message.AbandonRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.AbandonRequestImpl;
 import org.apache.directory.shared.ldap.message.AddRequest;
-import org.apache.directory.shared.ldap.message.AddRequestImpl;
 import org.apache.directory.shared.ldap.message.AddResponse;
 import org.apache.directory.shared.ldap.message.AliasDerefMode;
 import org.apache.directory.shared.ldap.message.BindRequest;
-import org.apache.directory.shared.ldap.message.BindRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.BindRequestImpl;
 import org.apache.directory.shared.ldap.message.BindResponse;
 import org.apache.directory.shared.ldap.message.CompareRequest;
-import org.apache.directory.shared.ldap.message.CompareRequestImpl;
 import org.apache.directory.shared.ldap.message.CompareResponse;
 import org.apache.directory.shared.ldap.message.DeleteRequest;
-import org.apache.directory.shared.ldap.message.DeleteRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl;
 import org.apache.directory.shared.ldap.message.DeleteResponse;
 import org.apache.directory.shared.ldap.message.ExtendedRequest;
-import org.apache.directory.shared.ldap.message.ExtendedRequestImpl;
 import org.apache.directory.shared.ldap.message.ExtendedResponse;
 import org.apache.directory.shared.ldap.message.IntermediateResponse;
-import org.apache.directory.shared.ldap.message.IntermediateResponseImpl;
 import org.apache.directory.shared.ldap.message.LdapResult;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.ModifyDnRequest;
-import org.apache.directory.shared.ldap.message.ModifyDnRequestImpl;
 import org.apache.directory.shared.ldap.message.ModifyDnResponse;
 import org.apache.directory.shared.ldap.message.ModifyRequest;
-import org.apache.directory.shared.ldap.message.ModifyRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl;
 import org.apache.directory.shared.ldap.message.ModifyResponse;
 import org.apache.directory.shared.ldap.message.Response;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.apache.directory.shared.ldap.message.SearchResultDone;
 import org.apache.directory.shared.ldap.message.SearchResultEntry;
 import org.apache.directory.shared.ldap.message.SearchResultReference;
 import org.apache.directory.shared.ldap.message.UnbindRequest;
-import org.apache.directory.shared.ldap.message.UnbindRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.UnbindRequestImpl;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.ldap.message.extended.NoticeOfDisconnect;
 import org.apache.directory.shared.ldap.message.extended.nod.AddNoDResponse;
@@ -655,7 +650,7 @@
             throw new IllegalArgumentException( msg );
         }
 
-        AddRequest addRequest = new AddRequestImpl();
+        AddRequest addRequest = new org.apache.directory.shared.ldap.codec.message.AddRequestImpl();
         addRequest.setEntry( entry );
 
         return add( addRequest );
@@ -674,7 +669,7 @@
             throw new IllegalArgumentException( msg );
         }
 
-        AddRequest addRequest = new AddRequestImpl();
+        AddRequest addRequest = new org.apache.directory.shared.ldap.codec.message.AddRequestImpl();
         addRequest.setEntry( entry );
 
         return addAsync( addRequest );
@@ -1819,13 +1814,13 @@
 
                 if ( responseFuture instanceof SearchFuture )
                 {
-                    intermediateResponse = new IntermediateResponseImpl( messageId );
+                    intermediateResponse = new org.apache.directory.shared.ldap.codec.message.IntermediateResponseImpl( messageId );
                     addControls( intermediateResponse, ( IntermediateResponse ) response );
                     ( ( SearchFuture ) responseFuture ).set( intermediateResponse );
                 }
                 else if ( responseFuture instanceof ExtendedFuture )
                 {
-                    intermediateResponse = new IntermediateResponseImpl( messageId );
+                    intermediateResponse = new org.apache.directory.shared.ldap.codec.message.IntermediateResponseImpl( messageId );
                     addControls( intermediateResponse, ( IntermediateResponse ) response );
                     ( ( ExtendedFuture ) responseFuture ).set( intermediateResponse );
                 }
@@ -2213,7 +2208,7 @@
             throw new IllegalArgumentException( msg );
         }
 
-        ModifyDnRequest modDnRequest = new ModifyDnRequestImpl();
+        ModifyDnRequest modDnRequest = new org.apache.directory.shared.ldap.codec.message.ModifyDnRequestImpl();
         modDnRequest.setName( entryDn );
         modDnRequest.setNewRdn( newRdn );
         modDnRequest.setDeleteOldRdn( deleteOldRdn );
@@ -2272,7 +2267,7 @@
             throw new IllegalArgumentException( msg );
         }
 
-        ModifyDnRequest modDnRequest = new ModifyDnRequestImpl();
+        ModifyDnRequest modDnRequest = new org.apache.directory.shared.ldap.codec.message.ModifyDnRequestImpl();
         modDnRequest.setName( entryDn );
         modDnRequest.setNewSuperior( newSuperiorDn );
 
@@ -2328,7 +2323,7 @@
         }
 
         // Create the request
-        ModifyDnRequest modDnRequest = new ModifyDnRequestImpl();
+        ModifyDnRequest modDnRequest = new org.apache.directory.shared.ldap.codec.message.ModifyDnRequestImpl();
         modDnRequest.setName( entryDn );
         modDnRequest.setNewRdn( newDn.getRdn() );
         modDnRequest.setNewSuperior( newDn.getParent() );
@@ -2489,7 +2484,7 @@
 
         if ( isControlSupported( treeDeleteOid ) )
         {
-            DeleteRequest deleteRequest = new DeleteRequestImpl();
+            DeleteRequest deleteRequest = new org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl();
             deleteRequest.setName( dn );
             deleteRequest.addControl( new ControlImpl( treeDeleteOid ) );
             return delete( deleteRequest );
@@ -2682,7 +2677,7 @@
      */
     public CompareResponse compare( DN dn, String attributeName, String value ) throws LdapException
     {
-        CompareRequest compareRequest = new CompareRequestImpl();
+        CompareRequest compareRequest = new org.apache.directory.shared.ldap.codec.message.CompareRequestImpl();
         compareRequest.setName( dn );
         compareRequest.setAttributeId( attributeName );
         compareRequest.setAssertionValue( value );
@@ -2696,7 +2691,7 @@
      */
     public CompareResponse compare( DN dn, String attributeName, byte[] value ) throws LdapException
     {
-        CompareRequest compareRequest = new CompareRequestImpl();
+        CompareRequest compareRequest = new org.apache.directory.shared.ldap.codec.message.CompareRequestImpl();
         compareRequest.setName( dn );
         compareRequest.setAttributeId( attributeName );
         compareRequest.setAssertionValue( value );
@@ -2710,7 +2705,7 @@
      */
     public CompareResponse compare( DN dn, String attributeName, Value<?> value ) throws LdapException
     {
-        CompareRequest compareRequest = new CompareRequestImpl();
+        CompareRequest compareRequest = new org.apache.directory.shared.ldap.codec.message.CompareRequestImpl();
         compareRequest.setName( dn );
         compareRequest.setAttributeId( attributeName );
 
@@ -2877,7 +2872,7 @@
      */
     public ExtendedResponse extended( OID oid, byte[] value ) throws LdapException
     {
-        ExtendedRequest extendedRequest = new ExtendedRequestImpl();
+        ExtendedRequest extendedRequest = new org.apache.directory.shared.ldap.codec.message.ExtendedRequestImpl();
         extendedRequest.setRequestName( oid.toString() );
         extendedRequest.setRequestValue( value );
 
@@ -3575,7 +3570,7 @@
             else
             {
                 // Copy the bindRequest without setting the credentials
-                BindRequest bindRequestCopy = new BindRequestImpl( newId );
+                BindRequest bindRequestCopy = new org.apache.directory.shared.ldap.codec.message.BindRequestImpl( newId );
                 bindRequestCopy.setName( bindRequest.getName() );
                 bindRequestCopy.setSaslMechanism( bindRequest.getSaslMechanism() );
                 bindRequestCopy.setSimple( bindRequest.isSimple() );
diff --git a/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/protocol/LdapProtocolEncoder.java b/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/protocol/LdapProtocolEncoder.java
index 966f963..e33c5b0 100644
--- a/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/protocol/LdapProtocolEncoder.java
+++ b/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/protocol/LdapProtocolEncoder.java
@@ -22,7 +22,7 @@
 
 import java.nio.ByteBuffer;
 
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.mina.core.buffer.IoBuffer;
 import org.apache.mina.core.session.IoSession;
@@ -38,7 +38,7 @@
 public class LdapProtocolEncoder implements ProtocolEncoder
 {
     /** The stateful encoder */
-    private static final LdapEncoder ENCODER = new LdapEncoder();
+    private static final org.apache.directory.shared.ldap.codec.message.LdapEncoder ENCODER = new LdapEncoder();
 
 
     /**
diff --git a/ldap-model/src/main/java/org/apache/directory/shared/ldap/message/MessageFactory.java b/ldap-model/src/main/java/org/apache/directory/shared/ldap/message/MessageFactory.java
new file mode 100644
index 0000000..a994acf
--- /dev/null
+++ b/ldap-model/src/main/java/org/apache/directory/shared/ldap/message/MessageFactory.java
@@ -0,0 +1,61 @@
+/*
+ *  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.shared.ldap.message;
+
+
+/**
+ * Interface for a factory that creates LDAP request response message instances.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface MessageFactory
+{
+    Response newResponse( SingleReplyRequest request );
+
+    AbandonRequest newAbandonRequest( int id );
+
+    AddRequest newAddRequest( int id );
+
+    BindRequest newBindRequest( int id );
+
+    BindResponse newBindResponse( int id );
+
+    CompareRequest newCompareRequest( int id );
+
+    DeleteRequest newDeleteRequest( int id );
+
+    ExtendedRequest newExtendedRequest( int id );
+
+    ModifyDnRequest newModifyDnRequest( int id );
+
+    ModifyRequest newModifyRequest( int id );
+
+    SearchRequest newSearchRequest( int id );
+
+    UnbindRequest newUnbindRequest( int id );
+
+    SearchResultDone newSearchResultDone( int id );
+
+    SearchResultEntry newSearchResultEntry( int id );
+
+    SearchResultReference newSearchResultReference( int id );
+
+    Referral newReferral();
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java
index 1bd0f0c..6400b14 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java
@@ -63,60 +63,39 @@
 import org.apache.directory.shared.ldap.codec.actions.StoreTypeMatchingRuleAction;
 import org.apache.directory.shared.ldap.codec.actions.ValueAction;
 import org.apache.directory.shared.ldap.codec.controls.ControlFactory;
+import org.apache.directory.shared.ldap.codec.message.*;
 import org.apache.directory.shared.ldap.codec.search.ExtensibleMatchFilter;
 import org.apache.directory.shared.ldap.codec.search.SubstringFilter;
 import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
 import org.apache.directory.shared.ldap.filter.SearchScope;
 import org.apache.directory.shared.ldap.message.AbandonRequest;
-import org.apache.directory.shared.ldap.message.AbandonRequestImpl;
 import org.apache.directory.shared.ldap.message.AddRequest;
-import org.apache.directory.shared.ldap.message.AddRequestImpl;
 import org.apache.directory.shared.ldap.message.AddResponse;
-import org.apache.directory.shared.ldap.message.AddResponseImpl;
 import org.apache.directory.shared.ldap.message.AliasDerefMode;
 import org.apache.directory.shared.ldap.message.BindRequest;
-import org.apache.directory.shared.ldap.message.BindRequestImpl;
 import org.apache.directory.shared.ldap.message.BindResponse;
-import org.apache.directory.shared.ldap.message.BindResponseImpl;
 import org.apache.directory.shared.ldap.message.CompareRequest;
-import org.apache.directory.shared.ldap.message.CompareRequestImpl;
 import org.apache.directory.shared.ldap.message.CompareResponse;
-import org.apache.directory.shared.ldap.message.CompareResponseImpl;
 import org.apache.directory.shared.ldap.message.DeleteRequest;
-import org.apache.directory.shared.ldap.message.DeleteRequestImpl;
 import org.apache.directory.shared.ldap.message.DeleteResponse;
-import org.apache.directory.shared.ldap.message.DeleteResponseImpl;
 import org.apache.directory.shared.ldap.message.ExtendedRequest;
-import org.apache.directory.shared.ldap.message.ExtendedRequestImpl;
 import org.apache.directory.shared.ldap.message.ExtendedResponse;
-import org.apache.directory.shared.ldap.message.ExtendedResponseImpl;
 import org.apache.directory.shared.ldap.message.IntermediateResponse;
-import org.apache.directory.shared.ldap.message.IntermediateResponseImpl;
 import org.apache.directory.shared.ldap.message.LdapResult;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.ModifyDnRequest;
-import org.apache.directory.shared.ldap.message.ModifyDnRequestImpl;
 import org.apache.directory.shared.ldap.message.ModifyDnResponse;
-import org.apache.directory.shared.ldap.message.ModifyDnResponseImpl;
 import org.apache.directory.shared.ldap.message.ModifyRequest;
-import org.apache.directory.shared.ldap.message.ModifyRequestImpl;
 import org.apache.directory.shared.ldap.message.ModifyResponse;
-import org.apache.directory.shared.ldap.message.ModifyResponseImpl;
 import org.apache.directory.shared.ldap.message.Referral;
-import org.apache.directory.shared.ldap.message.ReferralImpl;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.ResultResponse;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
 import org.apache.directory.shared.ldap.message.SearchResultDone;
-import org.apache.directory.shared.ldap.message.SearchResultDoneImpl;
 import org.apache.directory.shared.ldap.message.SearchResultEntry;
-import org.apache.directory.shared.ldap.message.SearchResultEntryImpl;
 import org.apache.directory.shared.ldap.message.SearchResultReference;
-import org.apache.directory.shared.ldap.message.SearchResultReferenceImpl;
 import org.apache.directory.shared.ldap.message.UnbindRequest;
-import org.apache.directory.shared.ldap.message.UnbindRequestImpl;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.ldap.name.DN;
 import org.apache.directory.shared.ldap.name.RDN;
@@ -148,6 +127,8 @@
     /** The instance of grammar. LdapMessageGrammar is a singleton */
     private static Grammar instance = new LdapMessageGrammar();
 
+    private static CodecMessageFactory messageFactory = new CodecMessageFactory();
+
 
     // ~ Constructors
     // -------------------------------------------------------------------------------
@@ -295,7 +276,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Create the UnbindRequest LdapMessage instance and store it in the container
-                    UnbindRequest unbindRequest = new UnbindRequestImpl( ldapMessageContainer.getMessageId() );
+                    UnbindRequest unbindRequest = messageFactory.newUnbindRequest( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( unbindRequest );
 
                     TLV tlv = ldapMessageContainer.getCurrentTLV();
@@ -342,7 +323,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Create the DeleteRequest LdapMessage instance and store it in the container
-                    DeleteRequest delRequest = new DeleteRequestImpl( ldapMessageContainer.getMessageId() );
+                    DeleteRequest delRequest = messageFactory.newDeleteRequest( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( delRequest );
 
                     // And store the DN into it
@@ -373,7 +354,7 @@
                                 .getLocalizedMessage() );
                             LOG.error( msg );
 
-                            DeleteResponseImpl response = new DeleteResponseImpl( delRequest.getMessageId() );
+                            DeleteResponse response = ( DeleteResponse ) messageFactory.newResponse( delRequest );
                             throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
                                 DN.EMPTY_DN, ine );
                         }
@@ -418,7 +399,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Create the AbandonRequest LdapMessage instance and store it in the container
-                    AbandonRequest abandonRequest = new AbandonRequestImpl( ldapMessageContainer.getMessageId() );
+                    AbandonRequest abandonRequest = messageFactory.newAbandonRequest( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( abandonRequest );
 
                     // The current TLV should be a integer
@@ -491,7 +472,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Create the BindRequest LdapMessage instance and store it in the container
-                    BindRequest bindRequest = new BindRequestImpl( ldapMessageContainer.getMessageId() );
+                    BindRequest bindRequest = messageFactory.newBindRequest( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( bindRequest );
 
                     // We will check that the request is not null
@@ -595,7 +576,7 @@
                                 + ") is invalid";
                             LOG.error( "{} : {}", msg, ine.getMessage() );
 
-                            BindResponseImpl response = new BindResponseImpl( bindRequestMessage.getMessageId() );
+                            BindResponse response = ( BindResponse ) messageFactory.newResponse( bindRequestMessage );
 
                             throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
                                 DN.EMPTY_DN, ine );
@@ -696,7 +677,7 @@
                         String msg = I18n.err( I18n.ERR_04079 );
                         LOG.error( msg );
 
-                        BindResponseImpl response = new BindResponseImpl( bindRequestMessage.getMessageId() );
+                        BindResponse response = ( BindResponse ) messageFactory.newResponse( bindRequestMessage );
 
                         throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_CREDENTIALS,
                             bindRequestMessage.getName(), null );
@@ -830,7 +811,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Now, we can allocate the BindResponse Object
-                    BindResponse bindResponse = new BindResponseImpl( ldapMessageContainer.getMessageId() );
+                    BindResponse bindResponse = messageFactory.newBindResponse( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( bindResponse );
                 }
             } );
@@ -1026,10 +1007,7 @@
 
                     Message response = ldapMessageContainer.getMessage();
                     LdapResult ldapResult = ( ( ResultResponse ) response ).getLdapResult();
-
-                    Referral referral = new ReferralImpl();
-
-                    ldapResult.setReferral( referral );
+                    ldapResult.setReferral( messageFactory.newReferral() );
                 }
             } );
 
@@ -1095,7 +1073,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Now, we can allocate the SearchResultEntry Object
-                    SearchResultEntry searchResultEntry = new SearchResultEntryImpl( ldapMessageContainer
+                    SearchResultEntry searchResultEntry = messageFactory.newSearchResultEntry( ldapMessageContainer
                         .getMessageId() );
                     ldapMessageContainer.setMessage( searchResultEntry );
                 }
@@ -1373,7 +1351,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Now, we can allocate the SearchResultDone Object
-                    SearchResultDone searchResultDone = new SearchResultDoneImpl( ldapMessageContainer.getMessageId() );
+                    SearchResultDone searchResultDone = messageFactory.newSearchResultDone( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( searchResultDone );
 
                     LOG.debug( "Search Result Done found" );
@@ -1411,7 +1389,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Now, we can allocate the ModifyRequest Object
-                    ModifyRequest modifyRequest = new ModifyRequestImpl( ldapMessageContainer.getMessageId() );
+                    ModifyRequest modifyRequest = new org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( modifyRequest );
                 }
             } );
@@ -1458,7 +1436,7 @@
                                 + ") is invalid";
                             LOG.error( "{} : {}", msg, ine.getMessage() );
 
-                            ModifyResponseImpl response = new ModifyResponseImpl( modifyRequest.getMessageId() );
+                            org.apache.directory.shared.ldap.codec.message.ModifyResponseImpl response = new org.apache.directory.shared.ldap.codec.message.ModifyResponseImpl( modifyRequest.getMessageId() );
                             throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
                                 DN.EMPTY_DN, ine );
                         }
@@ -1536,7 +1514,7 @@
                     }
 
                     // Store the current operation.
-                    ( ( ModifyRequestImpl ) modifyRequest ).setCurrentOperation( operation );
+                    ( (org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl) modifyRequest ).setCurrentOperation( operation );
 
                     if ( IS_DEBUG )
                     {
@@ -1616,7 +1594,7 @@
                     else
                     {
                         type = StringTools.getType( tlv.getValue().getData() );
-                        ( ( ModifyRequestImpl ) modifyRequest ).addAttributeTypeAndValues( type );
+                        ( (org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl) modifyRequest ).addAttributeTypeAndValues( type );
                     }
 
                     if ( IS_DEBUG )
@@ -1822,7 +1800,7 @@
 
                     // Now, we can allocate the AddRequest Object
                     int messageId = ldapMessageContainer.getMessageId();
-                    AddRequest addRequest = new AddRequestImpl( messageId );
+                    AddRequest addRequest = new org.apache.directory.shared.ldap.codec.message.AddRequestImpl( messageId );
                     ldapMessageContainer.setMessage( addRequest );
 
                     // We will check that the request is not null
@@ -1865,7 +1843,7 @@
                         String msg = I18n.err( I18n.ERR_04085 );
                         LOG.error( msg );
 
-                        AddResponseImpl response = new AddResponseImpl( addRequest.getMessageId() );
+                        org.apache.directory.shared.ldap.codec.message.AddResponseImpl response = new org.apache.directory.shared.ldap.codec.message.AddResponseImpl( addRequest.getMessageId() );
 
                         // I guess that trying to add an entry which DN is empty is a naming violation...
                         // Not 100% sure though ...
@@ -1888,7 +1866,7 @@
                                 + ") is invalid";
                             LOG.error( "{} : {}", msg, ine.getMessage() );
 
-                            AddResponseImpl response = new AddResponseImpl( addRequest.getMessageId() );
+                            org.apache.directory.shared.ldap.codec.message.AddResponseImpl response = new org.apache.directory.shared.ldap.codec.message.AddResponseImpl( addRequest.getMessageId() );
                             throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
                                 DN.EMPTY_DN, ine );
                         }
@@ -1950,7 +1928,7 @@
                         String msg = I18n.err( I18n.ERR_04086 );
                         LOG.error( msg );
 
-                        AddResponseImpl response = new AddResponseImpl( addRequest.getMessageId() );
+                        org.apache.directory.shared.ldap.codec.message.AddResponseImpl response = new org.apache.directory.shared.ldap.codec.message.AddResponseImpl( addRequest.getMessageId() );
 
                         throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
                             addRequest.getEntry().getDn(), null );
@@ -1967,7 +1945,7 @@
                         String msg = I18n.err( I18n.ERR_04087 );
                         LOG.error( msg );
 
-                        AddResponseImpl response = new AddResponseImpl( addRequest.getMessageId() );
+                        org.apache.directory.shared.ldap.codec.message.AddResponseImpl response = new org.apache.directory.shared.ldap.codec.message.AddResponseImpl( addRequest.getMessageId() );
                         throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
                             addRequest.getEntry().getDn(), ne );
                     }
@@ -2050,7 +2028,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Now, we can allocate the AddResponse Object
-                    AddResponse addResponse = new AddResponseImpl( ldapMessageContainer.getMessageId() );
+                    AddResponse addResponse = new org.apache.directory.shared.ldap.codec.message.AddResponseImpl( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( addResponse );
 
                     // We will check that the request is not null
@@ -2137,7 +2115,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Now, we can allocate the ModifyDNRequest Object
-                    ModifyDnRequest modifyDnRequest = new ModifyDnRequestImpl( ldapMessageContainer
+                    ModifyDnRequest modifyDnRequest = new org.apache.directory.shared.ldap.codec.message.ModifyDnRequestImpl( ldapMessageContainer
                         .getMessageId() );
                     ldapMessageContainer.setMessage( modifyDnRequest );
 
@@ -2190,7 +2168,7 @@
                                 + ") is invalid";
                             LOG.error( "{} : {}", msg, ine.getMessage() );
 
-                            ModifyDnResponseImpl response = new ModifyDnResponseImpl( modifyDNRequest.getMessageId() );
+                            org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl response = new org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl( modifyDNRequest.getMessageId() );
                             throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
                                 DN.EMPTY_DN, ine );
                         }
@@ -2238,7 +2216,7 @@
                         String msg = I18n.err( I18n.ERR_04090 );
                         LOG.error( msg );
 
-                        ModifyDnResponseImpl response = new ModifyDnResponseImpl( modifyDnRequest.getMessageId() );
+                        org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl response = new org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl( modifyDnRequest.getMessageId() );
                         throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
                             modifyDnRequest.getName(), null );
                     }
@@ -2258,7 +2236,7 @@
                                 + ") is invalid";
                             LOG.error( "{} : {}", msg, ine.getMessage() );
 
-                            ModifyDnResponseImpl response = new ModifyDnResponseImpl( modifyDnRequest.getMessageId() );
+                            org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl response = new org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl( modifyDnRequest.getMessageId() );
                             throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
                                 modifyDnRequest.getName(), ine );
                         }
@@ -2385,7 +2363,7 @@
                                 + Strings.dumpBytes(dnBytes) + ") is invalid";
                             LOG.error( "{} : {}", msg, ine.getMessage() );
 
-                            ModifyDnResponseImpl response = new ModifyDnResponseImpl( modifyDnRequest.getMessageId() );
+                            org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl response = new org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl( modifyDnRequest.getMessageId() );
                             throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
                                 modifyDnRequest.getName(), ine );
                         }
@@ -2444,7 +2422,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Now, we can allocate the ModifyDnResponse Object
-                    ModifyDnResponse modifyDnResponse = new ModifyDnResponseImpl( ldapMessageContainer.getMessageId() );
+                    ModifyDnResponse modifyDnResponse = new org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( modifyDnResponse );
 
                     LOG.debug( "Modify DN response " );
@@ -2486,7 +2464,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Now, we can allocate the CompareRequest Object
-                    CompareRequest compareRequest = new CompareRequestImpl( ldapMessageContainer.getMessageId() );
+                    CompareRequest compareRequest = new org.apache.directory.shared.ldap.codec.message.CompareRequestImpl( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( compareRequest );
 
                     LOG.debug( "Compare Request" );
@@ -2537,7 +2515,7 @@
                                 + ") is invalid";
                             LOG.error( "{} : {}", msg, ine.getMessage() );
 
-                            CompareResponseImpl response = new CompareResponseImpl( compareRequest.getMessageId() );
+                            CompareResponseImpl response = new org.apache.directory.shared.ldap.codec.message.CompareResponseImpl( compareRequest.getMessageId() );
                             throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
                                 DN.EMPTY_DN, ine );
                         }
@@ -2596,7 +2574,7 @@
                     {
                         String msg = I18n.err( I18n.ERR_04093 );
                         LOG.error( msg );
-                        CompareResponseImpl response = new CompareResponseImpl( compareRequest.getMessageId() );
+                        org.apache.directory.shared.ldap.codec.message.CompareResponseImpl response = new CompareResponseImpl( compareRequest.getMessageId() );
 
                         throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
                             compareRequest.getName(), null );
@@ -2700,7 +2678,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Now, we can allocate the CompareResponse Object
-                    CompareResponse compareResponse = new CompareResponseImpl( ldapMessageContainer.getMessageId() );
+                    CompareResponse compareResponse = new org.apache.directory.shared.ldap.codec.message.CompareResponseImpl( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( compareResponse );
 
                     // We will check that the request is not null
@@ -2972,7 +2950,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Now, we can allocate the ExtendedResponse Object
-                    ExtendedResponse extendedResponse = new ExtendedResponseImpl( ldapMessageContainer.getMessageId() );
+                    ExtendedResponse extendedResponse = new org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl( ldapMessageContainer.getMessageId() );
                     ldapMessageContainer.setMessage( extendedResponse );
 
                     LOG.debug( "Extended Response" );
@@ -3182,7 +3160,7 @@
                     LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
 
                     // Now, we can allocate the IntermediateResponse Object
-                    IntermediateResponse intermediateResponse = new IntermediateResponseImpl( ldapMessageContainer
+                    IntermediateResponse intermediateResponse = new org.apache.directory.shared.ldap.codec.message.IntermediateResponseImpl( ldapMessageContainer
                         .getMessageId() );
                     ldapMessageContainer.setMessage( intermediateResponse );
 
@@ -3590,7 +3568,7 @@
                     TLV tlv = ldapMessageContainer.getCurrentTLV();
 
                     SearchRequest searchRequest = new SearchRequestImpl( ldapMessageContainer.getMessageId() );
-                    ( ( SearchRequestImpl ) searchRequest ).setTlvId( tlv.getId() );
+                    ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).setTlvId( tlv.getId() );
                     ldapMessageContainer.setMessage( searchRequest );
 
                     LOG.debug( "Search Request" );
@@ -5055,7 +5033,7 @@
 
                         // We now have to get back to the nearest filter which
                         // is not terminal.
-                        ( ( SearchRequestImpl ) searchRequest ).setTerminalFilter( substringFilter );
+                        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).setTerminalFilter( substringFilter );
                     }
                 }
             } );
@@ -5128,7 +5106,7 @@
 
                     // We now have to get back to the nearest filter which is
                     // not terminal.
-                    ( ( SearchRequestImpl ) searchRequest ).unstackFilters( container );
+                    ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).unstackFilters( container );
                 }
             } );
 
@@ -6163,7 +6141,7 @@
                     TLV tlv = ldapMessageContainer.getCurrentTLV();
 
                     // Store the value.
-                    ExtensibleMatchFilter extensibleMatchFilter = ( ExtensibleMatchFilter ) ( ( SearchRequestImpl ) searchRequest )
+                    ExtensibleMatchFilter extensibleMatchFilter = ( ExtensibleMatchFilter ) ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest )
                         .getTerminalFilter();
 
                     // We get the value. If it's a 0, it's a FALSE. If it's
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAndFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAndFilterAction.java
index 164b211..b8bc4cf 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAndFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAndFilterAction.java
@@ -29,7 +29,7 @@
 import org.apache.directory.shared.ldap.codec.search.AndFilter;
 import org.apache.directory.shared.ldap.codec.search.Filter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitApproxMatchFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitApproxMatchFilterAction.java
index aaa2657..4677fcc 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitApproxMatchFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitApproxMatchFilterAction.java
@@ -28,7 +28,7 @@
 import org.apache.directory.shared.ldap.codec.search.AttributeValueAssertionFilter;
 import org.apache.directory.shared.ldap.codec.search.Filter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -72,7 +72,7 @@
 
         // Store the filter structure that still has to be
         // fulfilled
-        ( ( SearchRequestImpl ) searchRequest ).setTerminalFilter( filter );
+        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).setTerminalFilter( filter );
 
         if ( IS_DEBUG )
         {
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAssertionValueFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAssertionValueFilterAction.java
index a93812b..8d4eade 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAssertionValueFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAssertionValueFilterAction.java
@@ -31,7 +31,6 @@
 import org.apache.directory.shared.ldap.entry.StringValue;
 import org.apache.directory.shared.ldap.entry.Value;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
 import org.apache.directory.shared.util.CharConstants;
 import org.apache.directory.shared.util.Strings;
 import org.slf4j.Logger;
@@ -83,7 +82,7 @@
             assertionValue = new BinaryValue( CharConstants.EMPTY_BYTES );
         }
 
-        AttributeValueAssertionFilter terminalFilter = ( AttributeValueAssertionFilter ) ( ( SearchRequestImpl ) searchRequest )
+        AttributeValueAssertionFilter terminalFilter = ( AttributeValueAssertionFilter ) ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest )
             .getTerminalFilter();
         AttributeValueAssertion assertion = terminalFilter.getAssertion();
 
@@ -116,7 +115,7 @@
 
         // We now have to get back to the nearest filter which is
         // not terminal.
-        ( ( SearchRequestImpl ) searchRequest ).unstackFilters( container );
+        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).unstackFilters( container );
 
         if ( IS_DEBUG )
         {
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAttributeDescFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAttributeDescFilterAction.java
index 3d7573b..99a7485 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAttributeDescFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitAttributeDescFilterAction.java
@@ -29,7 +29,7 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.search.AttributeValueAssertionFilter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.apache.directory.shared.util.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitEqualityMatchFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitEqualityMatchFilterAction.java
index 5def9d5..37c9c15 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitEqualityMatchFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitEqualityMatchFilterAction.java
@@ -28,7 +28,6 @@
 import org.apache.directory.shared.ldap.codec.search.AttributeValueAssertionFilter;
 import org.apache.directory.shared.ldap.codec.search.Filter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -68,11 +67,11 @@
         Filter filter = new AttributeValueAssertionFilter( ldapMessageContainer.getTlvId(),
             LdapConstants.EQUALITY_MATCH_FILTER );
 
-        ( ( SearchRequestImpl ) searchRequest ).addCurrentFilter( filter );
+        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).addCurrentFilter( filter );
 
         // Store the filter structure that still has to be
         // fulfilled
-        ( ( SearchRequestImpl ) searchRequest ).setTerminalFilter( filter );
+        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).setTerminalFilter( filter );
 
         if ( IS_DEBUG )
         {
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitExtensibleMatchFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitExtensibleMatchFilterAction.java
index 1d6bbbf..6b87cab 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitExtensibleMatchFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitExtensibleMatchFilterAction.java
@@ -27,7 +27,6 @@
 import org.apache.directory.shared.ldap.codec.search.ExtensibleMatchFilter;
 import org.apache.directory.shared.ldap.codec.search.Filter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -66,8 +65,8 @@
         // We can allocate the ExtensibleMatch Filter
         Filter extensibleMatchFilter = new ExtensibleMatchFilter( ldapMessageContainer.getTlvId() );
 
-        ( ( SearchRequestImpl ) searchRequest ).addCurrentFilter( extensibleMatchFilter );
-        ( ( SearchRequestImpl ) searchRequest ).setTerminalFilter( extensibleMatchFilter );
+        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).addCurrentFilter( extensibleMatchFilter );
+        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).setTerminalFilter( extensibleMatchFilter );
 
         if ( IS_DEBUG )
         {
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitGreaterOrEqualFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitGreaterOrEqualFilterAction.java
index 19c24bd..d795d2c 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitGreaterOrEqualFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitGreaterOrEqualFilterAction.java
@@ -28,7 +28,6 @@
 import org.apache.directory.shared.ldap.codec.search.AttributeValueAssertionFilter;
 import org.apache.directory.shared.ldap.codec.search.Filter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -68,11 +67,11 @@
         Filter filter = new AttributeValueAssertionFilter( ldapMessageContainer.getTlvId(),
             LdapConstants.GREATER_OR_EQUAL_FILTER );
 
-        ( ( SearchRequestImpl ) searchRequest ).addCurrentFilter( filter );
+        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).addCurrentFilter( filter );
 
         // Store the filter structure that still has to be
         // fullfiled
-        ( ( SearchRequestImpl ) searchRequest ).setTerminalFilter( filter );
+        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).setTerminalFilter( filter );
 
         if ( IS_DEBUG )
         {
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitLessOrEqualFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitLessOrEqualFilterAction.java
index a2a4111..7a672fd 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitLessOrEqualFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitLessOrEqualFilterAction.java
@@ -28,7 +28,7 @@
 import org.apache.directory.shared.ldap.codec.search.AttributeValueAssertionFilter;
 import org.apache.directory.shared.ldap.codec.search.Filter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -72,7 +72,7 @@
 
         // Store the filter structure that still has to be
         // fullfiled
-        ( ( SearchRequestImpl ) searchRequest ).setTerminalFilter( filter );
+        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).setTerminalFilter( filter );
 
         if ( IS_DEBUG )
         {
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitNotFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitNotFilterAction.java
index 6f7c978..f6901dd 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitNotFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitNotFilterAction.java
@@ -29,7 +29,7 @@
 import org.apache.directory.shared.ldap.codec.search.Filter;
 import org.apache.directory.shared.ldap.codec.search.NotFilter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitOrFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitOrFilterAction.java
index c006e22..c6b1b49 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitOrFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitOrFilterAction.java
@@ -29,7 +29,6 @@
 import org.apache.directory.shared.ldap.codec.search.Filter;
 import org.apache.directory.shared.ldap.codec.search.OrFilter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -79,7 +78,7 @@
         Filter orFilter = new OrFilter( ldapMessageContainer.getTlvId() );
 
         // Set the filter
-        ( ( SearchRequestImpl ) searchRequest ).addCurrentFilter( orFilter );
+        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).addCurrentFilter( orFilter );
 
         if ( IS_DEBUG )
         {
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitPresentFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitPresentFilterAction.java
index 374d76e..9dc7335 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitPresentFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitPresentFilterAction.java
@@ -27,7 +27,7 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.search.PresentFilter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.apache.directory.shared.util.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitReferralsAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitReferralsAction.java
index 4acdc6f..95ea336 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitReferralsAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitReferralsAction.java
@@ -28,7 +28,6 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.message.LdapResult;
 import org.apache.directory.shared.ldap.message.Referral;
-import org.apache.directory.shared.ldap.message.ReferralImpl;
 import org.apache.directory.shared.ldap.message.ResultResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -79,7 +78,7 @@
         ResultResponse response = ( ResultResponse ) ldapMessageContainer.getMessage();
         LdapResult ldapResult = response.getLdapResult();
 
-        Referral referral = new ReferralImpl();
+        Referral referral = new org.apache.directory.shared.ldap.codec.message.ReferralImpl();
         ldapResult.setReferral( referral );
 
         if ( IS_DEBUG )
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitSubstringsFilterAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitSubstringsFilterAction.java
index 06b77a9..e61646d 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitSubstringsFilterAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/InitSubstringsFilterAction.java
@@ -29,7 +29,7 @@
 import org.apache.directory.shared.ldap.codec.search.Filter;
 import org.apache.directory.shared.ldap.codec.search.SubstringFilter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/ModifyAttributeValueAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/ModifyAttributeValueAction.java
index d349601..13bac3c 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/ModifyAttributeValueAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/ModifyAttributeValueAction.java
@@ -25,7 +25,7 @@
 import org.apache.directory.shared.asn1.ber.tlv.TLV;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.message.ModifyRequest;
-import org.apache.directory.shared.ldap.message.ModifyRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl;
 import org.apache.directory.shared.util.CharConstants;
 import org.apache.directory.shared.util.Strings;
 import org.slf4j.Logger;
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreAnyAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreAnyAction.java
index 504f9ea..b634193 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreAnyAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreAnyAction.java
@@ -28,7 +28,7 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.search.SubstringFilter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.apache.directory.shared.util.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -68,7 +68,7 @@
         TLV tlv = ldapMessageContainer.getCurrentTLV();
 
         // Store the value.
-        SubstringFilter substringFilter = ( SubstringFilter ) ( ( SearchRequestImpl ) searchRequest )
+        SubstringFilter substringFilter = ( SubstringFilter ) ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest )
             .getTerminalFilter();
 
         if ( tlv.getLength() == 0 )
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreFinalAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreFinalAction.java
index a42fb22..14fd292 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreFinalAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreFinalAction.java
@@ -28,7 +28,7 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.search.SubstringFilter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.apache.directory.shared.util.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -83,7 +83,7 @@
 
         // We now have to get back to the nearest filter which is
         // not terminal.
-        ( ( SearchRequestImpl ) searchRequest ).unstackFilters( container );
+        ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).unstackFilters( container );
 
         if ( IS_DEBUG )
         {
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreMatchValueAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreMatchValueAction.java
index 9aa1dc2..37d59bc 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreMatchValueAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreMatchValueAction.java
@@ -28,7 +28,7 @@
 import org.apache.directory.shared.ldap.codec.search.ExtensibleMatchFilter;
 import org.apache.directory.shared.ldap.entry.BinaryValue;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -67,7 +67,7 @@
         TLV tlv = ldapMessageContainer.getCurrentTLV();
 
         // Store the value.
-        ExtensibleMatchFilter extensibleMatchFilter = ( ExtensibleMatchFilter ) ( ( SearchRequestImpl ) searchRequest )
+        ExtensibleMatchFilter extensibleMatchFilter = ( ExtensibleMatchFilter ) ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest )
             .getTerminalFilter();
 
         byte[] value = tlv.getValue().getData();
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreReferenceAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreReferenceAction.java
index 7647721..30703af 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreReferenceAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreReferenceAction.java
@@ -28,7 +28,6 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.util.LdapURLEncodingException;
 import org.apache.directory.shared.ldap.message.Referral;
-import org.apache.directory.shared.ldap.message.ReferralImpl;
 import org.apache.directory.shared.ldap.message.SearchResultReference;
 import org.apache.directory.shared.ldap.util.LdapURL;
 import org.apache.directory.shared.util.Strings;
@@ -77,7 +76,7 @@
 
         if ( referral == null )
         {
-            referral = new ReferralImpl();
+            referral = new org.apache.directory.shared.ldap.codec.message.ReferralImpl();
             searchResultReference.setReferral( referral );
         }
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreTypeMatchingRuleAction.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreTypeMatchingRuleAction.java
index eaad062..dfd24d0 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreTypeMatchingRuleAction.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/actions/StoreTypeMatchingRuleAction.java
@@ -28,7 +28,7 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.search.ExtensibleMatchFilter;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.apache.directory.shared.util.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/AbandonRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/AbandonRequestImpl.java
new file mode 100644
index 0000000..084b6ce
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/AbandonRequestImpl.java
@@ -0,0 +1,162 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.i18n.I18n;
+import org.apache.directory.shared.ldap.message.AbandonRequest;
+import org.apache.directory.shared.ldap.message.AbstractRequest;
+
+
+/**
+ * Implementation of an AbandonRequest.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class AbandonRequestImpl extends AbstractRequest implements AbandonRequest
+{
+    static final long serialVersionUID = -4688193359792740969L;
+
+    /** Sequence identifier of the outstanding request message to abandon */
+    private int abandonId;
+
+
+    /**
+     * Creates an AbandonRequest implementation for an outstanding request.
+     */
+    public AbandonRequestImpl()
+    {
+        super( -1, TYPE, false );
+    }
+
+
+    /**
+     * Creates an AbandonRequest implementation for an outstanding request.
+     * 
+     * @param id the sequence identifier of the AbandonRequest message.
+     */
+    public AbandonRequestImpl( final int id )
+    {
+        super( id, TYPE, false );
+    }
+
+
+    /**
+     * Gets the id of the request operation to terminate.
+     * 
+     * @return the id of the request message to abandon
+     */
+    public int getAbandoned()
+    {
+        return abandonId;
+    }
+
+
+    /**
+     * Sets the id of the request operation to terminate.
+     * 
+     * @param abandonId
+     *            the sequence id of the request message to abandon
+     */
+    public void setAbandoned( int abandonId )
+    {
+        this.abandonId = abandonId;
+    }
+
+
+    /**
+     * Checks for equality first by asking the super method which should compare
+     * all but the Abandoned request's Id. It then compares this to determine
+     * equality.
+     * 
+     * @param obj
+     *            the object to test for equality to this AbandonRequest
+     * @return true if the obj equals this request false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+
+        if ( ( obj == null ) || !( obj instanceof AbandonRequest ) )
+        {
+            return false;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        AbandonRequest req = ( AbandonRequest ) obj;
+
+        if ( req.getAbandoned() != abandonId )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * @see Object#hashCode()
+     * @return the instance's hash code 
+     */
+    public int hashCode()
+    {
+        int hash = 37;
+        hash = hash * 17 + abandonId;
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * RFC 2251 [Section 4.11]: Abandon, Bind, Unbind, and StartTLS operations
+     * cannot be abandoned.
+     */
+    public void abandon()
+    {
+        throw new UnsupportedOperationException( I18n.err( I18n.ERR_04185 ) );
+    }
+
+
+    /**
+     * Return a String representing an AbandonRequest
+     * 
+     * @return A String representing the AbandonRequest
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Abandon Request :\n" );
+        sb.append( "        Message Id : " ).append( abandonId );
+
+        // The controls
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/AddRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/AddRequestImpl.java
new file mode 100644
index 0000000..7f12992
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/AddRequestImpl.java
@@ -0,0 +1,388 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import java.util.List;
+
+import org.apache.directory.shared.ldap.entry.DefaultEntry;
+import org.apache.directory.shared.ldap.entry.DefaultEntryAttribute;
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.exception.LdapException;
+import org.apache.directory.shared.ldap.message.*;
+import org.apache.directory.shared.ldap.name.DN;
+
+
+/**
+ * Lockable add request implemenation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class AddRequestImpl extends AbstractAbandonableRequest implements AddRequest
+{
+    static final long serialVersionUID = 7534132448349520346L;
+
+    /** A MultiMap of the new entry's attributes and their values */
+    private Entry entry;
+
+    private AddResponse response;
+
+    /** The current attribute being decoded */
+    private EntryAttribute currentAttribute;
+
+    /** The add request length */
+    private int addRequestLength;
+
+    /** The Entry length */
+    private int entryLength;
+
+    /** The list of all attributes length */
+    private List<Integer> attributesLength;
+
+    /** The list of all vals length */
+    private List<Integer> valuesLength;
+
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Creates an AddRequest implementation to create a new entry.
+     */
+    public AddRequestImpl()
+    {
+        super( -1, TYPE );
+        entry = new DefaultEntry();
+    }
+
+
+    /**
+     * Creates an AddRequest implementation to create a new entry.
+     * 
+     * @param id the sequence identifier of the AddRequest message.
+     */
+    public AddRequestImpl( final int id )
+    {
+        super( id, TYPE );
+        entry = new DefaultEntry();
+    }
+
+
+    // ------------------------------------------------------------------------
+    // AddRequest Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the distinguished name of the entry to add.
+     * 
+     * @return the Dn of the added entry.
+     */
+    public DN getEntryDn()
+    {
+        return entry.getDn();
+    }
+
+
+    /**
+     * Sets the distinguished name of the entry to add.
+     * 
+     * @param dn the Dn of the added entry.
+     */
+    public void setEntryDn( DN dn )
+    {
+        entry.setDn( dn );
+    }
+
+
+    /**
+     * Gets the entry to add.
+     * 
+     * @return the added Entry
+     */
+    public Entry getEntry()
+    {
+        return entry;
+    }
+
+
+    /**
+     * Sets the Entry to add.
+     * 
+     * @param entry the added Entry
+     */
+    public void setEntry( Entry entry )
+    {
+        this.entry = entry;
+    }
+
+
+    /**
+     * Create a new attributeValue
+     * 
+     * @param type The attribute's name (called 'type' in the grammar)
+     */
+    public void addAttributeType( String type ) throws LdapException
+    {
+        // do not create a new attribute if we have seen this attributeType before
+        if ( entry.get( type ) != null )
+        {
+            currentAttribute = entry.get( type );
+            return;
+        }
+
+        // fix this to use AttributeImpl(type.getString().toLowerCase())
+        currentAttribute = new DefaultEntryAttribute( type );
+        entry.put( currentAttribute );
+    }
+
+
+    /**
+     * @return Returns the currentAttribute type.
+     */
+    public String getCurrentAttributeType()
+    {
+        return currentAttribute.getId();
+    }
+
+
+    /**
+     * Add a new value to the current attribute
+     * 
+     * @param value The value to add
+     */
+    public void addAttributeValue( String value )
+    {
+        currentAttribute.add( value );
+    }
+
+
+    /**
+     * Add a new value to the current attribute
+     * 
+     * @param value The value to add
+     */
+    public void addAttributeValue( org.apache.directory.shared.ldap.entry.Value<?> value )
+    {
+        currentAttribute.add( value );
+    }
+
+
+    /**
+     * Add a new value to the current attribute
+     * 
+     * @param value The value to add
+     */
+    public void addAttributeValue( byte[] value )
+    {
+        currentAttribute.add( value );
+    }
+
+
+    // ------------------------------------------------------------------------
+    // SingleReplyRequest Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the protocol response message type for this request which produces
+     * at least one response.
+     * 
+     * @return the message type of the response.
+     */
+    public MessageTypeEnum getResponseType()
+    {
+        return RESP_TYPE;
+    }
+
+
+    /**
+     * The result containing response for this request.
+     * 
+     * @return the result containing response for this request
+     */
+    public ResultResponse getResultResponse()
+    {
+        if ( response == null )
+        {
+            response = new AddResponseImpl( getMessageId() );
+        }
+
+        return response;
+    }
+
+
+    /**
+     * Stores the encoded length for the AddRequest
+     * @param addRequestLength The encoded length
+     */
+    /* No qualifier*/void setAddRequestLength( int addRequestLength )
+    {
+        this.addRequestLength = addRequestLength;
+    }
+
+
+    /**
+     * @return The encoded AddRequest's length
+     */
+    /* No qualifier */int getAddRequestLength()
+    {
+        return addRequestLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the Entry
+     * @param entryLength The encoded length
+     */
+    /* No qualifier*/void setEntryLength( int entryLength )
+    {
+        this.entryLength = entryLength;
+    }
+
+
+    /**
+     * @return The encoded Entry's length
+     */
+    /* No qualifier */int getEntryLength()
+    {
+        return entryLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the attributes
+     * @param atributesLength The encoded length
+     */
+    /* No qualifier*/void setAttributesLength( List<Integer> attributesLength )
+    {
+        this.attributesLength = attributesLength;
+    }
+
+
+    /**
+     * @return The encoded values length
+     */
+    /* No qualifier */List<Integer> getAttributesLength()
+    {
+        return attributesLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the values
+     * @param valuesLength The encoded length
+     */
+    /* No qualifier*/void setValuesLength( List<Integer> valuesLength )
+    {
+        this.valuesLength = valuesLength;
+    }
+
+
+    /**
+     * @return The encoded values length
+     */
+    /* No qualifier */List<Integer> getValuesLength()
+    {
+        return valuesLength;
+    }
+
+
+    /**
+     * Checks to see if an object is equivalent to this AddRequest. First
+     * there's a quick test to see if the obj is the same object as this one -
+     * if so true is returned. Next if the super method fails false is returned.
+     * Then the name of the entry is compared - if not the same false is
+     * returned. Lastly the attributes of the entry are compared. If they are
+     * not the same false is returned otherwise the method exists returning
+     * true.
+     * 
+     * @param obj the object to test for equality to this
+     * @return true if the obj is equal to this AddRequest, false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        // Short circuit
+        if ( this == obj )
+        {
+            return true;
+        }
+
+        // Check the object class. If null, it will exit.
+        if ( !( obj instanceof AddRequest ) )
+        {
+            return false;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        AddRequest req = ( AddRequest ) obj;
+
+        // Check the entry
+        if ( entry == null )
+        {
+            return ( req.getEntry() == null );
+        }
+        else
+        {
+            return ( entry.equals( req.getEntry() ) );
+        }
+    }
+
+
+    /**
+     * @see Object#hashCode()
+     * @return the instance's hash code 
+     */
+    public int hashCode()
+    {
+        int hash = 37;
+        hash = hash * 17 + ( entry == null ? 0 : entry.hashCode() );
+        hash = hash * 17 + ( response == null ? 0 : response.hashCode() );
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Add Request :\n" );
+
+        if ( entry == null )
+        {
+            sb.append( "            No entry\n" );
+        }
+        else
+        {
+            sb.append( entry.toString() );
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/AddResponseImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/AddResponseImpl.java
new file mode 100644
index 0000000..f3ea2db
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/AddResponseImpl.java
@@ -0,0 +1,96 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.AbstractResultResponse;
+import org.apache.directory.shared.ldap.message.AddResponse;
+
+/**
+ * AddResponse implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class AddResponseImpl extends AbstractResultResponse implements AddResponse
+{
+    /** The encoded addResponse length */
+    private int addResponseLength;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    static final long serialVersionUID = 4027132942339551383L;
+
+
+    /**
+     * Creates an AddResponse as a reply to an AddRequest.
+     */
+    public AddResponseImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates an AddResponse as a reply to an AddRequest.
+     * 
+     * @param id the session unique message id
+     */
+    public AddResponseImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    /**
+     * Stores the encoded length for the AddResponse
+     * @param addResponseLength The encoded length
+     */
+    /* No qualifier*/void setAddResponseLength( int addResponseLength )
+    {
+        this.addResponseLength = addResponseLength;
+    }
+
+
+    /**
+     * @return The encoded AddResponse's length
+     */
+    /* No qualifier */int getAddResponseLength()
+    {
+        return addResponseLength;
+    }
+
+
+    /**
+     * Get a String representation of an AddResponse
+     * 
+     * @return An AddResponse String
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Add Response\n" );
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/BindRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/BindRequestImpl.java
new file mode 100644
index 0000000..155756e
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/BindRequestImpl.java
@@ -0,0 +1,530 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import java.util.Arrays;
+
+import org.apache.directory.shared.i18n.I18n;
+import org.apache.directory.shared.ldap.message.*;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.util.Strings;
+
+
+/**
+ * Bind protocol operation request which authenticates and begins a client
+ * session. Does not yet contain interfaces for SASL authentication mechanisms.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ */
+class BindRequestImpl extends AbstractAbandonableRequest implements BindRequest
+{
+    static final long serialVersionUID = 7945504184130380071L;
+
+    /**
+     * Distinguished name identifying the name of the authenticating subject -
+     * defaults to the empty string
+     */
+    private DN name;
+
+    /** The passwords, keys or tickets used to verify user identity */
+    private byte[] credentials;
+
+    /** A storage for credentials hashCode */
+    private int hCredentials;
+
+    /** The mechanism used to decode user identity */
+    private String mechanism;
+
+    /** Simple vs. SASL authentication mode flag */
+    private boolean isSimple = true;
+
+    /** Bind behavior exhibited by protocol version */
+    private boolean isVersion3 = true;
+
+    /** The associated response */
+    public BindResponse response;
+
+    /** The bind request length */
+    private int bindRequestLength;
+
+    /** The SASL Mechanism length */
+    private int saslMechanismLength;
+
+    /** The SASL credentials length */
+    private int saslCredentialsLength;
+
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Creates an BindRequest implementation to bind to an LDAP server.
+     * 
+     * @param id the sequence identifier of the BindRequest message.
+     */
+    public BindRequestImpl( final int id )
+    {
+        super( id, TYPE );
+        hCredentials = 0;
+    }
+
+
+    /**
+     * Creates an BindRequest implementation to bind to an LDAP server.
+     */
+    public BindRequestImpl()
+    {
+        super( -1, TYPE );
+        hCredentials = 0;
+    }
+
+
+    // -----------------------------------------------------------------------
+    // BindRequest Interface Method Implementations
+    // -----------------------------------------------------------------------
+
+    /**
+     * Checks to see if the authentication mechanism is simple and not SASL
+     * based.
+     * 
+     * @return true if the mechanism is simple false if it is SASL based.
+     */
+    public boolean isSimple()
+    {
+        return isSimple;
+    }
+
+
+    /**
+     * Checks to see if the authentication mechanism is simple and not SASL
+     * based.
+     * 
+     * @return true if the mechanism is simple false if it is SASL based.
+     */
+    public boolean getSimple()
+    {
+        return isSimple;
+    }
+
+
+    /**
+     * Sets the authentication mechanism to simple or to SASL based
+     * authentication.
+     * 
+     * @param simple
+     *            true if authentication is simple, false otherwise.
+     */
+    public void setSimple( boolean simple )
+    {
+        this.isSimple = simple;
+    }
+
+
+    /**
+     * Gets the simple credentials associated with a simple authentication
+     * attempt or null if this request uses SASL authentication mechanisms.
+     * 
+     * @return null if the mechanism is SASL or the credentials if it is simple.
+     */
+    public byte[] getCredentials()
+    {
+        return credentials;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setCredentials( String credentials )
+    {
+        setCredentials( Strings.getBytesUtf8(credentials) );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setCredentials( byte[] credentials )
+    {
+        if ( credentials != null )
+        {
+            this.credentials = new byte[credentials.length];
+            System.arraycopy( credentials, 0, this.credentials, 0, credentials.length );
+        }
+        else
+        {
+            this.credentials = null;
+        }
+
+        // Compute the hashcode
+        if ( credentials != null )
+        {
+            hCredentials = 0;
+
+            for ( byte b : credentials )
+            {
+                hCredentials = hCredentials * 31 + b;
+            }
+        }
+        else
+        {
+            hCredentials = 0;
+        }
+    }
+
+
+    /**
+     * Gets the mechanism if this request uses SASL authentication mechanisms.
+     * 
+     * @return The mechanism if SASL.
+     */
+    public String getSaslMechanism()
+    {
+        return mechanism;
+    }
+
+
+    /**
+     * Sets the mechanism associated with a SASL authentication
+     * 
+     * @param saslMechanism
+     *            the SASL mechanism
+     */
+    public void setSaslMechanism( String saslMechanism )
+    {
+        this.mechanism = saslMechanism;
+    }
+
+
+    /**
+     * Gets the distinguished name of the subject in this authentication
+     * request. This field may take on a null value (a zero length string) for
+     * the purposes of anonymous binds, when authentication has been performed
+     * at a lower layer, or when using SASL credentials with a mechanism that
+     * includes the DN in the credentials.
+     * 
+     * @return the DN of the authenticating user.
+     */
+    public DN getName()
+    {
+        return name;
+    }
+
+
+    /**
+     * Sets the distinguished name of the subject in this authentication
+     * request. This field may take on a null value (or a zero length string)
+     * for the purposes of anonymous binds, when authentication has been
+     * performed at a lower layer, or when using SASL credentials with a
+     * mechanism that includes the DN in the credentials.
+     * 
+     * @param name
+     *            the DN of the authenticating user - leave null for annonymous
+     *            user.
+     */
+    public void setName( DN name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * Checks to see if the Ldap v3 protocol is used. Normally this would
+     * extract a version number from the bind request sent by the client
+     * indicating the version of the protocol to be used in this protocol
+     * session. The integer is either a 2 or a 3 at the moment. We thought it
+     * was better to just check if the protocol used is 3 or not rather than use
+     * an type-safe enumeration type for a binary value. If an LDAPv4 comes out
+     * then we shall convert the return type to a type safe enumeration.
+     * 
+     * @return true if client using version 3 false if it is version 2.
+     */
+    public boolean isVersion3()
+    {
+        return isVersion3;
+    }
+
+
+    /**
+     * Gets whether or not the Ldap v3 protocol is used. Normally this would
+     * extract a version number from the bind request sent by the client
+     * indicating the version of the protocol to be used in this protocol
+     * session. The integer is either a 2 or a 3 at the moment. We thought it
+     * was better to just check if the protocol used is 3 or not rather than use
+     * an type-safe enumeration type for a binary value. If an LDAPv4 comes out
+     * then we shall convert the return type to a type safe enumeration.
+     * 
+     * @return true if client using version 3 false if it is version 2.
+     */
+    public boolean getVersion3()
+    {
+        return isVersion3;
+    }
+
+
+    /**
+     * Sets whether or not the LDAP v3 or v2 protocol is used. Normally this
+     * would extract a version number from the bind request sent by the client
+     * indicating the version of the protocol to be used in this protocol
+     * session. The integer is either a 2 or a 3 at the moment. We thought it
+     * was better to just check if the protocol used is 3 or not rather than use
+     * an type-safe enumeration type for a binary value. If an LDAPv4 comes out
+     * then we shall convert the return type to a type safe enumeration.
+     * 
+     * @param version3
+     *            if true the client will be exhibiting version 3 bind behavoir,
+     *            if false is used version 2 behavoir will be exhibited.
+     */
+    public void setVersion3( boolean version3 )
+    {
+        this.isVersion3 = version3;
+    }
+
+
+    // -----------------------------------------------------------------------
+    // BindRequest Interface Method Implementations
+    // -----------------------------------------------------------------------
+    /**
+     * Gets the protocol response message type for this request which produces
+     * at least one response.
+     * 
+     * @return the message type of the response.
+     */
+    public MessageTypeEnum getResponseType()
+    {
+        return RESP_TYPE;
+    }
+
+
+    /**
+     * The result containing response for this request.
+     * 
+     * @return the result containing response for this request
+     */
+    public ResultResponse getResultResponse()
+    {
+        if ( response == null )
+        {
+            response = new BindResponseImpl( getMessageId() );
+        }
+
+        return response;
+    }
+
+
+    /**
+     * RFC 2251/4511 [Section 4.11]: Abandon, Bind, Unbind, and StartTLS operations
+     * cannot be abandoned.
+     */
+    public void abandon()
+    {
+        throw new UnsupportedOperationException( I18n.err( I18n.ERR_04185 ) );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( ( obj == null ) || !( obj instanceof BindRequest ) )
+        {
+            return false;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        BindRequest req = ( BindRequest ) obj;
+
+        if ( req.isSimple() != isSimple() )
+        {
+            return false;
+        }
+
+        if ( req.isVersion3() != isVersion3() )
+        {
+            return false;
+        }
+
+        DN dn1 = req.getName();
+        DN dn2 = getName();
+
+        if ( dn1 == null )
+        {
+            if ( dn2 != null )
+            {
+                return false;
+            }
+        }
+        else
+        {
+            if ( dn2 == null )
+            {
+                return false;
+            }
+            else if ( !dn1.equals( dn2 ) )
+            {
+                return false;
+            }
+
+        }
+
+        if ( !Arrays.equals( req.getCredentials(), getCredentials() ) )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        hash = hash * 17 + ( credentials == null ? 0 : hCredentials );
+        hash = hash * 17 + ( isSimple ? 0 : 1 );
+        hash = hash * 17 + ( isVersion3 ? 0 : 1 );
+        hash = hash * 17 + ( mechanism == null ? 0 : mechanism.hashCode() );
+        hash = hash * 17 + ( name == null ? 0 : name.hashCode() );
+        hash = hash * 17 + ( response == null ? 0 : response.hashCode() );
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Stores the encoded length for the BindRequest
+     * @param bindRequestLength The encoded length
+     */
+    /* No qualifier*/void setBindRequestLength( int bindRequestLength )
+    {
+        this.bindRequestLength = bindRequestLength;
+    }
+
+
+    /**
+     * @return The encoded BindRequest's length
+     */
+    /* No qualifier */int getBindRequestLength()
+    {
+        return bindRequestLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the SaslCredentials
+     * @param saslCredentialsLength The encoded length
+     */
+    /* No qualifier*/void setSaslCredentialsLength( int saslCredentialsLength )
+    {
+        this.saslCredentialsLength = saslCredentialsLength;
+    }
+
+
+    /**
+     * @return The encoded SaslCredentials's length
+     */
+    /* No qualifier */int getSaslCredentialsLength()
+    {
+        return saslCredentialsLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the Mechanism
+     * @param saslMechanismLength The encoded length
+     */
+    /* No qualifier*/void setSaslMechanismLength( int saslMechanismLength )
+    {
+        this.saslMechanismLength = saslMechanismLength;
+    }
+
+
+    /**
+     * @return The encoded SaslMechanism's length
+     */
+    /* No qualifier */int getSaslMechanismLength()
+    {
+        return saslMechanismLength;
+    }
+
+
+    /**
+     * Get a String representation of a BindRequest
+     * 
+     * @return A BindRequest String
+     */
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer();
+        sb.append( "    BindRequest\n" );
+        sb.append( "        Version : '" ).append( isVersion3 ? "3" : "2" ).append( "'\n" );
+
+        if ( Strings.isEmpty(name.getNormName()) && isSimple )
+        {
+            sb.append( "        Name : anonymous\n" );
+        }
+        else
+        {
+            sb.append( "        Name : '" ).append( name.toString() ).append( "'\n" );
+
+            if ( isSimple )
+            {
+                sb.append( "        Simple authentication : '" ).append( Strings.utf8ToString(credentials) )
+                    .append( '/' ).append( Strings.dumpBytes(credentials) ).append( "'\n" );
+            }
+            else
+            {
+                sb.append( "        Sasl credentials\n" );
+                sb.append( "            Mechanism :'" ).append( mechanism ).append( "'\n" );
+
+                if ( credentials == null )
+                {
+                    sb.append( "            Credentials : null" );
+                }
+                else
+                {
+                    sb.append( "            Credentials : (omitted-for-safety)" );
+                }
+            }
+        }
+
+        // The controls if any
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/BindResponseImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/BindResponseImpl.java
new file mode 100644
index 0000000..29821a3
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/BindResponseImpl.java
@@ -0,0 +1,216 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import java.util.Arrays;
+
+import org.apache.directory.shared.ldap.message.AbstractResultResponse;
+import org.apache.directory.shared.ldap.message.BindResponse;
+import org.apache.directory.shared.util.Strings;
+
+
+/**
+ * BindResponse implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ */
+class BindResponseImpl extends AbstractResultResponse implements BindResponse
+{
+    static final long serialVersionUID = -5146809476518669755L;
+
+    /** optional property holding SASL authentication response parameters */
+    private byte[] serverSaslCreds;
+
+    /** The encoded bindResponse length */
+    private int bindResponseLength;
+
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+    /**
+     * Creates a BindResponse as a reply to an BindRequest.
+     */
+    public BindResponseImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates a BindResponse as a reply to an BindRequest.
+     * 
+     * @param id the session unique message id
+     */
+    public BindResponseImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    // ------------------------------------------------------------------------
+    // BindResponse Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the optional property holding SASL authentication response paramters
+     * that are SASL mechanism specific. Will return null if the authentication
+     * is simple.
+     * 
+     * @return the sasl mech. specific credentials or null of auth. is simple
+     */
+    public byte[] getServerSaslCreds()
+    {
+        if ( serverSaslCreds == null )
+        {
+            return null;
+        }
+
+        final byte[] copy = new byte[serverSaslCreds.length];
+        System.arraycopy( serverSaslCreds, 0, copy, 0, serverSaslCreds.length );
+        return copy;
+    }
+
+
+    /**
+     * Sets the optional property holding SASL authentication response paramters
+     * that are SASL mechanism specific. Leave null if authentication mode is
+     * simple.
+     * 
+     * @param serverSaslCreds
+     *            the sasl auth. mech. specific credentials
+     */
+    public void setServerSaslCreds( byte[] serverSaslCreds )
+    {
+        if ( serverSaslCreds != null )
+        {
+            this.serverSaslCreds = new byte[serverSaslCreds.length];
+            System.arraycopy( serverSaslCreds, 0, this.serverSaslCreds, 0, serverSaslCreds.length );
+        }
+        else
+        {
+            this.serverSaslCreds = null;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        hash = hash * 17 + Arrays.hashCode( serverSaslCreds );
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks to see if this BindResponse is equal to another BindResponse. The
+     * implementation and lockable properties are not factored into the
+     * evaluation of equality. Only the messageId, saslCredentials and the
+     * LdapResults of this BindResponse PDU and the compared object are taken
+     * into account if that object also implements the BindResponse interface.
+     * 
+     * @param obj
+     *            the object to test for equality with this BindResponse
+     * @return true if obj equals this BindResponse false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        // quickly return true if obj is this one
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( ( obj == null ) || !( obj instanceof BindResponse ) )
+        {
+            return false;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        BindResponse response = ( BindResponse ) obj;
+        byte[] creds = response.getServerSaslCreds();
+
+        if ( serverSaslCreds == null )
+        {
+            if ( creds != null )
+            {
+                return false;
+            }
+        }
+        else if ( creds == null )
+        {
+            return false;
+        }
+
+        return Arrays.equals( serverSaslCreds, creds );
+    }
+
+
+    /**
+     * Stores the encoded length for the BindResponse
+     * @param bindResponseLength The encoded length
+     */
+    /* No qualifier*/void setBindResponseLength( int bindResponseLength )
+    {
+        this.bindResponseLength = bindResponseLength;
+    }
+
+
+    /**
+     * @return The encoded BindResponse's length
+     */
+    /* No qualifier */int getBindResponseLength()
+    {
+        return bindResponseLength;
+    }
+
+
+    /**
+     * Get a String representation of a BindResponse
+     * 
+     * @return A BindResponse String
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    BindResponse\n" );
+        sb.append( super.toString() );
+
+        if ( serverSaslCreds != null )
+        {
+            sb.append( "        Server sasl credentials : '" ).append( Strings.dumpBytes(serverSaslCreds) )
+                .append( "'\n" );
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/CodecMessageFactory.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/CodecMessageFactory.java
new file mode 100644
index 0000000..b8f726a
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/CodecMessageFactory.java
@@ -0,0 +1,157 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.*;
+
+
+/**
+ * A MessageFactory implemented by the Codec to hide implementation details.
+ *
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ *         $Rev: 946353 $
+ */
+public class CodecMessageFactory implements MessageFactory
+{
+    public Response newResponse( SingleReplyRequest request )
+    {
+        Response response = null;
+
+        switch ( request.getResponseType() )
+        {
+            case ADD_REQUEST:
+                response = new AddResponseImpl( request.getMessageId() );
+                break;
+            case BIND_REQUEST:
+                response = new BindResponseImpl( request.getMessageId() );
+                break;
+            case COMPARE_REQUEST:
+                response = new CompareResponseImpl( request.getMessageId() );
+                break;
+            case DEL_REQUEST:
+                response = new DeleteResponseImpl( request.getMessageId() );
+                break;
+            case EXTENDED_REQUEST:
+                response = new ExtendedResponseImpl( request.getMessageId() );
+                break;
+            case MODIFYDN_RESPONSE:
+                response = new ModifyDnResponseImpl( request.getMessageId() );
+                break;
+            case MODIFY_REQUEST:
+                response = new ModifyResponseImpl( request.getMessageId() );
+                break;
+            default:
+                throw new IllegalArgumentException( "Not a SingleReplyRequest instance: " + request.getResponseType() );
+        }
+
+        return response;
+    }
+
+
+    public AbandonRequest newAbandonRequest( int id )
+    {
+        return new AbandonRequestImpl( id );
+    }
+
+
+    public AddRequest newAddRequest( int id )
+    {
+        return new AddRequestImpl( id );
+    }
+
+
+    public BindRequest newBindRequest( int id )
+    {
+        return new BindRequestImpl( id );
+    }
+
+
+    public BindResponse newBindResponse( int id )
+    {
+        return new BindResponseImpl( id );
+    }
+
+
+    public CompareRequest newCompareRequest( int id )
+    {
+        return new CompareRequestImpl( id );
+    }
+
+
+    public DeleteRequest newDeleteRequest( int id )
+    {
+        return new DeleteRequestImpl( id );
+    }
+
+
+    public ExtendedRequest newExtendedRequest( int id )
+    {
+        return new ExtendedRequestImpl( id );
+    }
+
+
+    public ModifyDnRequest newModifyDnRequest( int id )
+    {
+        return new ModifyDnRequestImpl( id );
+    }
+
+
+    public ModifyRequest newModifyRequest( int id )
+    {
+        return new ModifyRequestImpl( id );
+    }
+
+
+    public SearchRequest newSearchRequest( int id )
+    {
+        return new SearchRequestImpl( id );
+    }
+
+
+    public UnbindRequest newUnbindRequest( int id )
+    {
+        return new UnbindRequestImpl( id );
+    }
+
+
+    public SearchResultDone newSearchResultDone( int id )
+    {
+        return new SearchResultDoneImpl( id );
+    }
+
+
+    public SearchResultEntry newSearchResultEntry( int id )
+    {
+        return new SearchResultEntryImpl( id );
+    }
+
+
+    public SearchResultReference newSearchResultReference( int id )
+    {
+        return new SearchResultReferenceImpl( id );
+    }
+
+
+    public Referral newReferral()
+    {
+        return new ReferralImpl();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/CompareRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/CompareRequestImpl.java
new file mode 100644
index 0000000..962ce20
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/CompareRequestImpl.java
@@ -0,0 +1,427 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.entry.BinaryValue;
+import org.apache.directory.shared.ldap.entry.StringValue;
+import org.apache.directory.shared.ldap.entry.Value;
+import org.apache.directory.shared.ldap.message.*;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.util.Strings;
+
+
+/**
+ * Comparison request implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class CompareRequestImpl extends AbstractAbandonableRequest implements CompareRequest
+{
+    static final long serialVersionUID = 1699731530016468977L;
+
+    /** Distinguished name identifying the compared entry */
+    private DN name;
+
+    /** The id of the attribute used in the comparison */
+    private String attrId;
+
+    /** The bytes of the attribute id used in the comparison */
+    private byte[] attrIdBytes;
+
+    /** The value of the attribute used in the comparison */
+    private Value<?> attrVal;
+
+    /** The bytes of the attribute value used in the comparison */
+    private byte[] attrValBytes;
+
+    /** The associated response */
+    private CompareResponse response;
+
+    /** The compare request length */
+    private int compareRequestLength;
+
+    /** The attribute value assertion length */
+    private int avaLength;
+
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+    /**
+     * Creates an CompareRequest implementation to compare a named entry with an
+     * attribute value assertion pair.
+     */
+    public CompareRequestImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates an CompareRequest implementation to compare a named entry with an
+     * attribute value assertion pair.
+     * 
+     * @param id the sequence identifier of the CompareRequest message.
+     */
+    public CompareRequestImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    // ------------------------------------------------------------------------
+    // ComparisonRequest Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the distinguished name of the entry to be compared using the
+     * attribute value assertion.
+     * 
+     * @return the DN of the compared entry.
+     */
+    public DN getName()
+    {
+        return name;
+    }
+
+
+    /**
+     * Sets the distinguished name of the entry to be compared using the
+     * attribute value assertion.
+     * 
+     * @param name the DN of the compared entry.
+     */
+    public void setName( DN name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * Gets the attribute value to use in making the comparison.
+     * 
+     * @return the attribute value to used in comparison.
+     */
+    public Value<?> getAssertionValue()
+    {
+        return attrVal;
+    }
+
+
+    /**
+     * Sets the attribute value to use in the comparison.
+     * 
+     * @param value the attribute value used in comparison.
+     */
+    public void setAssertionValue( String value )
+    {
+        this.attrVal = new StringValue( value );
+    }
+
+
+    /**
+     * Sets the attribute value to use in the comparison.
+     * 
+     * @param value the attribute value used in comparison.
+     */
+    public void setAssertionValue( byte[] value )
+    {
+        if ( value != null )
+        {
+            this.attrVal = new BinaryValue( value );
+        }
+        else
+        {
+            this.attrVal = null;
+        }
+    }
+
+
+    /**
+     * Gets the attribute id use in making the comparison.
+     * 
+     * @return the attribute id used in comparison.
+     */
+    public String getAttributeId()
+    {
+        return attrId;
+    }
+
+
+    /**
+     * Sets the attribute id used in the comparison.
+     * 
+     * @param attributeId the attribute id used in comparison.
+     */
+    public void setAttributeId( String attributeId )
+    {
+        this.attrId = attributeId;
+    }
+
+
+    /**
+     * Gets the attribute id bytes use in making the comparison.
+     * 
+     * @return the attribute id bytes used in comparison.
+     */
+    /*No qualifier*/byte[] getAttrIdBytes()
+    {
+        return attrIdBytes;
+    }
+
+
+    /**
+     * Sets the attribute id bytes used in the comparison.
+     * 
+     * @param attrIdBytes the attribute id bytes used in comparison.
+     */
+    /*No qualifier*/void setAttrIdBytes( byte[] attrIdBytes )
+    {
+        this.attrIdBytes = attrIdBytes;
+    }
+
+
+    /**
+     * Gets the attribute value bytes use in making the comparison.
+     * 
+     * @return the attribute value bytes used in comparison.
+     */
+    /*No qualifier*/byte[] getAttrValBytes()
+    {
+        return attrValBytes;
+    }
+
+
+    /**
+     * Sets the attribute value bytes used in the comparison.
+     * 
+     * @param attrValBytes the attribute value bytes used in comparison.
+     */
+    /*No qualifier*/void setAttrValBytes( byte[] attrValBytes )
+    {
+        this.attrValBytes = attrValBytes;
+    }
+
+
+    // ------------------------------------------------------------------------
+    // SingleReplyRequest Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the protocol response message type for this request which produces
+     * at least one response.
+     * 
+     * @return the message type of the response.
+     */
+    public MessageTypeEnum getResponseType()
+    {
+        return RESP_TYPE;
+    }
+
+
+    /**
+     * The result containing response for this request.
+     * 
+     * @return the result containing response for this request
+     */
+    public ResultResponse getResultResponse()
+    {
+        if ( response == null )
+        {
+            response = new CompareResponseImpl( getMessageId() );
+        }
+
+        return response;
+    }
+
+
+    /**
+     * Stores the encoded length for the CompareRequest
+     * @param compareRequestLength The encoded length
+     */
+    /* No qualifier*/void setCompareRequestLength( int compareRequestLength )
+    {
+        this.compareRequestLength = compareRequestLength;
+    }
+
+
+    /**
+     * @return The encoded CompareRequest length
+     */
+    /* No qualifier */int getCompareRequestLength()
+    {
+        return compareRequestLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the ava
+     * @param avaLength The encoded length
+     */
+    /* No qualifier*/void setAvaLength( int avaLength )
+    {
+        this.avaLength = avaLength;
+    }
+
+
+    /**
+     * @return The encoded ava length
+     */
+    /* No qualifier */int getAvaLength()
+    {
+        return avaLength;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( name != null )
+        {
+            hash = hash * 17 + name.hashCode();
+        }
+        if ( attrId != null )
+        {
+            hash = hash * 17 + attrId.hashCode();
+        }
+        if ( attrVal != null )
+        {
+            hash = hash * 17 + attrVal.hashCode();
+        }
+        Value<?> reqVal = getAssertionValue();
+        if ( reqVal != null )
+        {
+            hash = hash * 17 + reqVal.hashCode();
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks to see if an object is equivalent to this CompareRequest.
+     * 
+     * @param obj the obj to compare with this CompareRequest
+     * @return true if the obj is equal to this request, false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        CompareRequest req = ( CompareRequest ) obj;
+        DN reqName = req.getName();
+
+        if ( ( name != null ) && ( reqName == null ) )
+        {
+            return false;
+        }
+
+        if ( ( name == null ) && ( reqName != null ) )
+        {
+            return false;
+        }
+
+        if ( ( name != null ) && ( reqName != null ) && !name.equals( req.getName() ) )
+        {
+            return false;
+        }
+
+        String reqId = req.getAttributeId();
+
+        if ( ( attrId != null ) && ( reqId == null ) )
+        {
+            return false;
+        }
+
+        if ( ( attrId == null ) && ( reqId != null ) )
+        {
+            return false;
+        }
+
+        if ( ( attrId != null ) && ( reqId != null ) && !attrId.equals( reqId ) )
+        {
+            return false;
+        }
+
+        Value<?> reqVal = req.getAssertionValue();
+
+        if ( attrVal != null )
+        {
+            if ( reqVal != null )
+            {
+                return attrVal.equals( reqVal );
+            }
+            else
+            {
+                return false;
+            }
+        }
+        else
+        {
+            return reqVal == null;
+        }
+    }
+
+
+    /**
+     * Get a String representation of a Compare Request
+     * 
+     * @return A Compare Request String
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Compare request\n" );
+        sb.append( "        Entry : '" ).append( name.toString() ).append( "'\n" );
+        sb.append( "        Attribute description : '" ).append( attrId ).append( "'\n" );
+        sb.append( "        Attribute value : '" );
+
+        if ( !attrVal.isBinary() )
+        {
+            sb.append( attrVal.get() );
+        }
+        else
+        {
+            byte[] binVal = attrVal.getBytes();
+            sb.append( Strings.utf8ToString(binVal) ).append( '/' ).append( Strings.dumpBytes(binVal) )
+                .append( "'\n" );
+        }
+
+        // The controls
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/CompareResponseImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/CompareResponseImpl.java
new file mode 100644
index 0000000..a2c297e
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/CompareResponseImpl.java
@@ -0,0 +1,107 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.AbstractResultResponse;
+import org.apache.directory.shared.ldap.message.CompareResponse;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+
+/**
+ * CompareResponse implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ */
+class CompareResponseImpl extends AbstractResultResponse implements CompareResponse
+{
+    /** The encoded compareResponse length */
+    private int compareResponseLength;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    static final long serialVersionUID = 6452521899386487731L;
+
+
+    /**
+     * Creates a CompareResponse as a reply to an CompareRequest.
+     */
+    public CompareResponseImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates a CompareResponse as a reply to an CompareRequest.
+     * 
+     * @param id the session unique message id
+     */
+    public CompareResponseImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    /**
+     * Stores the encoded length for the CompareResponse
+     * @param compareResponseLength The encoded length
+     */
+    /* No qualifier*/void setCompareResponseLength( int compareResponseLength )
+    {
+        this.compareResponseLength = compareResponseLength;
+    }
+
+
+    /**
+     * @return The encoded CompareResponse's length
+     */
+    /* No qualifier*/int getCompareResponseLength()
+    {
+        return compareResponseLength;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isTrue()
+    {
+        return ldapResult.getResultCode() == ResultCodeEnum.COMPARE_TRUE;
+    }
+
+
+    /**
+     * Get a String representation of an CompareResponse
+     * 
+     * @return An CompareResponse String
+     */
+    public String toString()
+    {
+
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Compare Response\n" );
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/DeleteRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/DeleteRequestImpl.java
new file mode 100644
index 0000000..373d2e2
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/DeleteRequestImpl.java
@@ -0,0 +1,207 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.*;
+import org.apache.directory.shared.ldap.name.DN;
+
+
+/**
+ * Delete request implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class DeleteRequestImpl extends AbstractAbandonableRequest implements DeleteRequest
+{
+    static final long serialVersionUID = 3187847454305567542L;
+
+    /** The distinguished name of the entry to delete */
+    private DN name;
+
+    /** The deleteResponse associated with this request */
+    private DeleteResponse response;
+
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Creates a DeleteRequest implementing object used to delete a
+     * leaf entry from the DIT.
+     */
+    public DeleteRequestImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates a DeleteRequest implementing object used to delete a
+     * leaf entry from the DIT.
+     * 
+     * @param id the sequential message identifier
+     */
+    public DeleteRequestImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    // ------------------------------------------------------------------------
+    // DeleteRequest Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the distinguished name of the leaf entry to be deleted by this
+     * request.
+     * 
+     * @return the DN of the leaf entry to delete.
+     */
+    public DN getName()
+    {
+        return name;
+    }
+
+
+    /**
+     * Sets the distinguished name of the leaf entry to be deleted by this
+     * request.
+     * 
+     * @param name the DN of the leaf entry to delete.
+     */
+    public void setName( DN name )
+    {
+        this.name = name;
+    }
+
+
+    // ------------------------------------------------------------------------
+    // SingleReplyRequest Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the protocol response message type for this request which produces
+     * at least one response.
+     * 
+     * @return the message type of the response.
+     */
+    public MessageTypeEnum getResponseType()
+    {
+        return RESP_TYPE;
+    }
+
+
+    /**
+     * The result containing response for this request.
+     * 
+     * @return the result containing response for this request
+     */
+    public ResultResponse getResultResponse()
+    {
+        if ( response == null )
+        {
+            response = new DeleteResponseImpl( getMessageId() );
+        }
+
+        return response;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+
+        if ( name != null )
+        {
+            hash = hash * 17 + name.hashCode();
+        }
+
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks to see if an object is equivalent to this DeleteRequest. First
+     * there's a quick test to see if the obj is the same object as this one -
+     * if so true is returned. Next if the super method fails false is returned.
+     * Then the name of the entry is compared - if not the same false is
+     * returned. Finally the method exists returning true.
+     * 
+     * @param obj the object to test for equality to this
+     * @return true if the obj is equal to this DeleteRequest, false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        DeleteRequest req = ( DeleteRequest ) obj;
+
+        if ( name != null && req.getName() == null )
+        {
+            return false;
+        }
+
+        if ( name == null && req.getName() != null )
+        {
+            return false;
+        }
+
+        if ( ( name != null ) && ( req.getName() != null ) && !name.equals( req.getName() ) )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Return a String representing a DelRequest
+     * 
+     * @return A DelRequest String
+     */
+    public String toString()
+    {
+
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Del request\n" );
+        sb.append( "        Entry : '" ).append( name.toString() ).append( "'\n" );
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/DeleteResponseImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/DeleteResponseImpl.java
new file mode 100644
index 0000000..6053a88
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/DeleteResponseImpl.java
@@ -0,0 +1,96 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.AbstractResultResponse;
+import org.apache.directory.shared.ldap.message.DeleteResponse;
+
+/**
+ * DeleteResponse implementation
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ */
+class DeleteResponseImpl extends AbstractResultResponse implements DeleteResponse
+{
+    /** The encoded deleteResponse length */
+    private int deleteResponseLength;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    static final long serialVersionUID = -6830004960050713586L;
+
+
+    /**
+     * Creates a DeleteResponse as a reply to an DeleteRequest.
+     */
+    public DeleteResponseImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates a DeleteResponse as a reply to an DeleteRequest.
+     * 
+     * @param id the session unique message id
+     */
+    public DeleteResponseImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    /**
+     * Stores the encoded length for the DeleteResponse
+     * @param deleteResponseLength The encoded length
+     */
+    /* No qualifier*/void setDeleteResponseLength( int deleteResponseLength )
+    {
+        this.deleteResponseLength = deleteResponseLength;
+    }
+
+
+    /**
+     * @return The encoded DeleteResponse's length
+     */
+    /* No qualifier*/int getDeleteResponseLength()
+    {
+        return deleteResponseLength;
+    }
+
+
+    /**
+     * Get a String representation of a DelResponse
+     * 
+     * @return A DelResponse String
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Compare Response\n" );
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ExtendedRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ExtendedRequestImpl.java
new file mode 100644
index 0000000..8953593
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ExtendedRequestImpl.java
@@ -0,0 +1,349 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import java.util.Arrays;
+
+import javax.naming.NamingException;
+import javax.naming.ldap.ExtendedResponse;
+
+import org.apache.directory.shared.ldap.message.AbstractRequest;
+import org.apache.directory.shared.ldap.message.ExtendedRequest;
+import org.apache.directory.shared.ldap.message.MessageTypeEnum;
+import org.apache.directory.shared.ldap.message.ResultResponse;
+import org.apache.directory.shared.util.Strings;
+
+
+/**
+ * ExtendedRequest implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class ExtendedRequestImpl extends AbstractRequest implements ExtendedRequest
+{
+    static final long serialVersionUID = 7916990159044177480L;
+
+    /** Extended request's Object Identifier or <b>requestName</b> */
+    private String oid;
+
+    /** Extended request's value */
+    protected byte[] requestValue;
+
+    /** The associated response */
+    protected ResultResponse response;
+
+    /** The extended request length */
+    private int extendedRequestLength;
+
+    /** The OID length */
+    private byte[] requestNameBytes;
+
+
+    // -----------------------------------------------------------------------
+    // Constructors
+    // -----------------------------------------------------------------------
+
+    /**
+     * Creates an ExtendedRequest implementing object used to perform
+     * extended protocol operation on the server.
+     */
+    public ExtendedRequestImpl()
+    {
+        super( -1, TYPE, true );
+    }
+
+
+    /**
+     * Creates an ExtendedRequest implementing object used to perform
+     * extended protocol operation on the server.
+     * 
+     * @param id the sequential message identifier
+     */
+    public ExtendedRequestImpl( final int id )
+    {
+        super( id, TYPE, true );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // ExtendedRequest Interface Method Implementations
+    // -----------------------------------------------------------------------
+
+    /**
+     * Sets the Object Identifier corresponding to the extended request type.
+     * 
+     * @param newOid the dotted-decimal representation as a String of the OID
+     */
+    public void setRequestName( String newOid )
+    {
+        this.oid = newOid;
+    }
+
+
+    /**
+     * Gets the extended request's <b>requestValue</b> portion of the PDU. The
+     * form of the data is request specific and is determined by the extended
+     * request OID.
+     * 
+     * @return byte array of data
+     */
+    public byte[] getRequestValue()
+    {
+        if ( requestValue == null )
+        {
+            return null;
+        }
+
+        final byte[] copy = new byte[requestValue.length];
+        System.arraycopy( requestValue, 0, copy, 0, requestValue.length );
+        return copy;
+    }
+
+
+    /**
+     * Sets the extended request's <b>requestValue</b> portion of the PDU.
+     * 
+     * @param payload byte array of data encapsulating ext. req. parameters
+     */
+    public void setRequestValue( byte[] payload )
+    {
+        if ( payload != null )
+        {
+            this.requestValue = new byte[payload.length];
+            System.arraycopy( payload, 0, this.requestValue, 0, payload.length );
+        }
+        else
+        {
+            this.requestValue = null;
+        }
+    }
+
+
+    // ------------------------------------------------------------------------
+    // SingleReplyRequest Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the protocol response message type for this request which produces
+     * at least one response.
+     * 
+     * @return the message type of the response.
+     */
+    public MessageTypeEnum getResponseType()
+    {
+        return RESP_TYPE;
+    }
+
+
+    /**
+     * The result containing response for this request.
+     * 
+     * @return the result containing response for this request
+     */
+    public ResultResponse getResultResponse()
+    {
+        if ( response == null )
+        {
+            response = new ExtendedResponseImpl( getMessageId() );
+        }
+
+        return response;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( oid != null )
+        {
+            hash = hash * 17 + oid.hashCode();
+        }
+        if ( requestValue != null )
+        {
+            hash = hash * 17 + Arrays.hashCode( requestValue );
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks to see if an object equals this ExtendedRequest.
+     * 
+     * @param obj the object to be checked for equality
+     * @return true if the obj equals this ExtendedRequest, false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        if ( !( obj instanceof ExtendedRequest ) )
+        {
+            return false;
+        }
+
+        ExtendedRequest req = ( ExtendedRequest ) obj;
+
+        if ( ( oid != null ) && ( req.getRequestName() == null ) )
+        {
+            return false;
+        }
+
+        if ( ( oid == null ) && ( req.getRequestName() != null ) )
+        {
+            return false;
+        }
+
+        if ( ( oid != null ) && ( req.getRequestName() != null ) && !oid.equals( req.getRequestName() ) )
+        {
+            return false;
+        }
+
+        if ( ( requestValue != null ) && ( req.getRequestValue() == null ) )
+        {
+            return false;
+        }
+
+        if ( ( requestValue == null ) && ( req.getRequestValue() != null ) )
+        {
+            return false;
+        }
+
+        if ( ( requestValue != null ) && ( req.getRequestValue() != null )
+            && !Arrays.equals( requestValue, req.getRequestValue() ) )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Gets the Object Idendifier corresponding to the extended request type.
+     * This is the <b>requestName</b> portion of the ext. req. PDU.
+     * 
+     * @return the dotted-decimal representation as a String of the OID
+     */
+    public String getRequestName()
+    {
+        return oid;
+    }
+
+
+    /**
+     * Creates the extended response.
+     * 
+     * This implement always returns null.
+     *
+     * @param id the OID
+     * @param berValue the value
+     * @param offset the offset
+     * @param length the length
+     * @return the extended response
+     * @throws NamingException the naming exception
+     */
+    public ExtendedResponse createExtendedResponse( String id, byte[] berValue, int offset, int length )
+        throws NamingException
+    {
+        return null;
+    }
+
+
+    /**
+     * Stores the encoded length for the ExtendedRequest
+     * 
+     * @param extendedRequestLength The encoded length
+     */
+    /* No qualifier*/void setExtendedRequestLength( int extendedRequestLength )
+    {
+        this.extendedRequestLength = extendedRequestLength;
+    }
+
+
+    /**
+     * @return The encoded ExtendedRequest's length
+     */
+    /* No qualifier*/int getExtendedRequestLength()
+    {
+        return extendedRequestLength;
+    }
+
+
+    /**
+     * Gets the requestName bytes.
+     * 
+     * @return the requestName bytes of the extended request type.
+     */
+    /* No qualifier*/byte[] getRequestNameBytes()
+    {
+        return requestNameBytes;
+    }
+
+
+    /**
+     * Sets the requestName bytes.
+     * 
+     * @param requestNameBytes the OID bytes of the extended request type.
+     */
+    /* No qualifier*/void setRequestNameBytes( byte[] requestNameBytes )
+    {
+        this.requestNameBytes = requestNameBytes;
+    }
+
+
+    /**
+     * Get a String representation of an Extended Request
+     * 
+     * @return an Extended Request String
+     */
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append( "    Extended request\n" );
+        sb.append( "        Request name : '" ).append( oid ).append( "'\n" );
+
+        if ( oid != null )
+        {
+            sb.append( "        Request value : '" ).append( Strings.utf8ToString(requestValue) ).append( '/' )
+                .append( Strings.dumpBytes(requestValue) ).append( "'\n" );
+        }
+
+        // The controls
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ExtendedResponseImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ExtendedResponseImpl.java
new file mode 100644
index 0000000..0a55c2d
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ExtendedResponseImpl.java
@@ -0,0 +1,329 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import java.util.Arrays;
+
+import org.apache.directory.shared.ldap.message.AbstractResultResponse;
+import org.apache.directory.shared.ldap.message.ExtendedResponse;
+import org.apache.directory.shared.util.Strings;
+
+
+/**
+ * ExtendedResponse implementation
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ */
+class ExtendedResponseImpl extends AbstractResultResponse implements ExtendedResponse
+{
+    static final long serialVersionUID = -6646752766410531060L;
+
+    /** Object identifier for the extended response */
+    protected String responseName;
+
+    /** The response name as a byte[] */
+    private byte[] responseNameBytes;
+
+    /** Value encoded in the extended response payload */
+    protected byte[] responseValue;
+
+    /** The encoded extendedResponse length */
+    private int extendedResponseLength;
+
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Creates an ExtendedResponse as a reply to an ExtendedRequest.
+     * 
+     * @param responseName the ExtendedResponse's name
+     */
+    public ExtendedResponseImpl( String responseName )
+    {
+        super( -1, TYPE );
+        this.responseName = responseName;
+    }
+
+
+    /**
+     * Creates an ExtendedResponse as a reply to an ExtendedRequest.
+     * 
+     * @param id the session unique message id
+     * @param responseName the ExtendedResponse's name
+     */
+    public ExtendedResponseImpl( final int id, String responseName )
+    {
+        super( id, TYPE );
+        this.responseName = responseName;
+    }
+
+
+    /**
+     * Creates an ExtendedResponse as a reply to an ExtendedRequest.
+     * 
+     * @param id the session unique message id
+     */
+    public ExtendedResponseImpl( int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    // ------------------------------------------------------------------------
+    // ExtendedResponse Interface Method Implementations
+    // ------------------------------------------------------------------------
+    /**
+     * Sets the response OID specific encoded response value.
+     * 
+     * @param responseValue the response specific encoded response values.
+     */
+    public void setResponseValue( byte[] responseValue )
+    {
+        if ( responseValue != null )
+        {
+            this.responseValue = new byte[responseValue.length];
+            System.arraycopy( responseValue, 0, this.responseValue, 0, responseValue.length );
+        }
+        else
+        {
+            this.responseValue = null;
+        }
+    }
+
+
+    /**
+     * Sets the OID uniquely identifying this extended response (a.k.a. its
+     * name).
+     * 
+     * @param responseName the OID of the extended response type.
+     */
+    public void setResponseName( String responseName )
+    {
+        this.responseName = responseName;
+    }
+
+
+    /**
+     * Gets the responseName bytes.
+     * 
+     * @return the responseName bytes of the extended response type.
+     */
+    /* No qualifier*/byte[] getResponseNameBytes()
+    {
+        return responseNameBytes;
+    }
+
+
+    /**
+     * Sets the OID bytes.
+     * 
+     * @param oidBytes the OID bytes of the extended response type.
+     */
+    /* No qualifier*/void setResponseNameBytes( byte[] responseNameBytes )
+    {
+        this.responseNameBytes = responseNameBytes;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+
+        if ( responseName != null )
+        {
+            hash = hash * 17 + responseName.hashCode();
+        }
+
+        if ( responseValue != null )
+        {
+            hash = hash * 17 + Arrays.hashCode( responseValue );
+        }
+
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks to see if an object equals this ExtendedRequest.
+     * 
+     * @param obj
+     *            the object to be checked for equality
+     * @return true if the obj equals this ExtendedRequest, false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        if ( !( obj instanceof ExtendedResponse ) )
+        {
+            return false;
+        }
+
+        ExtendedResponse resp = ( ExtendedResponse ) obj;
+
+        if ( ( responseName != null ) && ( resp.getResponseName() == null ) )
+        {
+            return false;
+        }
+
+        if ( ( responseName == null ) && ( resp.getResponseName() != null ) )
+        {
+            return false;
+        }
+
+        if ( ( responseName != null ) && ( resp.getResponseName() != null )
+            && !responseName.equals( resp.getResponseName() ) )
+        {
+            return false;
+        }
+
+        if ( ( responseValue != null ) && ( resp.getResponseValue() == null ) )
+        {
+            return false;
+        }
+
+        if ( ( responseValue == null ) && ( resp.getResponseValue() != null ) )
+        {
+            return false;
+        }
+
+        if ( ( responseValue != null ) && ( resp.getResponseValue() != null )
+            && !Arrays.equals( responseValue, resp.getResponseValue() ) )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Gets the OID uniquely identifying this extended response (a.k.a. its
+     * name).
+     * 
+     * @return the responseName of the extended response
+     */
+    public String getResponseName()
+    {
+        return ( ( responseName == null ) ? "" : responseName.toString() );
+    }
+
+
+    /**
+     * Gets the response OID specific encoded response values.
+     * 
+     * @return the response specific encoded response value
+     */
+    public byte[] getResponseValue()
+    {
+        if ( responseValue == null )
+        {
+            return null;
+        }
+
+        final byte[] copy = new byte[responseValue.length];
+        System.arraycopy( responseValue, 0, copy, 0, responseValue.length );
+        return copy;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * @deprecated Use the {@link #getResponseValue()} method
+     */
+    public byte[] getEncodedValue()
+    {
+        return getResponseValue();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * @deprecated Use the {@link #getResponseName()} method
+     */
+    public String getID()
+    {
+        return getResponseName();
+    }
+
+
+    /**
+     * Stores the encoded length for the ExtendedResponse
+     * 
+     * @param extendedResponseLength The encoded length
+     */
+    /* No qualifier*/void setExtendedResponseLength( int extendedResponseLength )
+    {
+        this.extendedResponseLength = extendedResponseLength;
+    }
+
+
+    /**
+     * @return The encoded ExtendedResponse's length
+     */
+    /* No qualifier*/int getExtendedResponseLength()
+    {
+        return extendedResponseLength;
+    }
+
+
+    /**
+     * Get a String representation of an ExtendedResponse
+     * 
+     * @return An ExtendedResponse String
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Extended Response\n" );
+
+        if ( responseName != null )
+        {
+            sb.append( "        ResponseName :'" ).append( responseName ).append( "'\n" );
+        }
+
+        if ( responseValue != null )
+        {
+            sb.append( "        ResponseValue :'" ).append( Strings.dumpBytes(responseValue) ).append( "'\n" );
+        }
+
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/IntermediateResponseImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/IntermediateResponseImpl.java
new file mode 100644
index 0000000..e239923
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/IntermediateResponseImpl.java
@@ -0,0 +1,277 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import java.util.Arrays;
+
+import org.apache.directory.shared.ldap.message.AbstractResultResponse;
+import org.apache.directory.shared.ldap.message.IntermediateResponse;
+import org.apache.directory.shared.util.Strings;
+
+
+/**
+ * IntermediateResponse implementation
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ */
+class IntermediateResponseImpl extends AbstractResultResponse implements IntermediateResponse
+{
+    static final long serialVersionUID = -6646752766410531060L;
+
+    /** ResponseName for the intermediate response */
+    protected String responseName;
+
+    /** The response name as a byte[] */
+    private byte[] responseNameBytes;
+
+    /** Response Value for the intermediate response */
+    protected byte[] responseValue;
+
+    /** The encoded intermediateResponse length */
+    private int intermediateResponseLength;
+
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+    public IntermediateResponseImpl( int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    // ------------------------------------------------------------------------
+    // IntermediateResponse Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the reponseName specific encoded
+     * 
+     * @return the response value
+     */
+    public byte[] getResponseValue()
+    {
+        if ( responseValue == null )
+        {
+            return null;
+        }
+
+        final byte[] copy = new byte[responseValue.length];
+        System.arraycopy( responseValue, 0, copy, 0, responseValue.length );
+        return copy;
+    }
+
+
+    /**
+     * Sets the response value
+     * 
+     * @param value the response value.
+     */
+    public void setResponseValue( byte[] value )
+    {
+        if ( value != null )
+        {
+            this.responseValue = new byte[value.length];
+            System.arraycopy( value, 0, this.responseValue, 0, value.length );
+        }
+        else
+        {
+            this.responseValue = null;
+        }
+    }
+
+
+    /**
+     * Gets the OID uniquely identifying this Intermediate response (a.k.a. its
+     * name).
+     * 
+     * @return the OID of the Intermediate response type.
+     */
+    public String getResponseName()
+    {
+        return ( ( responseName == null ) ? "" : responseName );
+    }
+
+
+    /**
+     * Gets the ResponseName bytes
+     * 
+     * @return the ResponseName bytes of the Intermediate response type.
+     */
+    /* No qualifier */byte[] getResponseNameBytes()
+    {
+        return responseNameBytes;
+    }
+
+
+    /**
+     * Sets the OID uniquely identifying this Intermediate response (a.k.a. its
+     * name).
+     * 
+     * @param oid the OID of the Intermediate response type.
+     */
+    public void setResponseName( String oid )
+    {
+        this.responseName = oid;
+    }
+
+
+    /**
+     * Sets the ResponseName bytes
+     * 
+     * @param oid the ResponseName bytes of the Intermediate response type.
+     */
+    /* No qualifier */void setResponseNameBytes( byte[] responseNameBytes )
+    {
+        this.responseNameBytes = responseNameBytes;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( responseName != null )
+        {
+            hash = hash * 17 + responseName.hashCode();
+        }
+        if ( responseValue != null )
+        {
+            hash = hash * 17 + Arrays.hashCode( responseValue );
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks to see if an object equals this IntemediateResponse.
+     * 
+     * @param obj the object to be checked for equality
+     * @return true if the obj equals this IntemediateResponse, false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        if ( !( obj instanceof IntermediateResponse ) )
+        {
+            return false;
+        }
+
+        IntermediateResponse resp = ( IntermediateResponse ) obj;
+
+        if ( ( responseName != null ) && ( resp.getResponseName() == null ) )
+        {
+            return false;
+        }
+
+        if ( ( responseName == null ) && ( resp.getResponseName() != null ) )
+        {
+            return false;
+        }
+
+        if ( ( responseName != null ) && ( resp.getResponseName() != null )
+            && !responseName.equals( resp.getResponseName() ) )
+        {
+            return false;
+        }
+
+        if ( ( responseValue != null ) && ( resp.getResponseValue() == null ) )
+        {
+            return false;
+        }
+
+        if ( ( responseValue == null ) && ( resp.getResponseValue() != null ) )
+        {
+            return false;
+        }
+
+        if ( ( responseValue != null ) && ( resp.getResponseValue() != null )
+            && !Arrays.equals( responseValue, resp.getResponseValue() ) )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Stores the encoded length for the IntermediateResponse
+     * 
+     * @param intermediateResponseLength The encoded length
+     */
+    /* No qualifier*/void setIntermediateResponseLength( int intermediateResponseLength )
+    {
+        this.intermediateResponseLength = intermediateResponseLength;
+    }
+
+
+    /**
+     * @return The encoded IntermediateResponse's length
+     */
+    /* No qualifier*/int getIntermediateResponseLength()
+    {
+        return intermediateResponseLength;
+    }
+
+
+    /**
+     * Get a String representation of an IntermediateResponse
+     * 
+     * @return An IntermediateResponse String
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Intermediate Response\n" );
+
+        if ( responseName != null )
+        {
+            sb.append( "        Response name :'" ).append( responseName ).append( "'\n" );
+        }
+
+        if ( responseValue != null )
+        {
+            sb.append( "        ResponseValue :'" );
+            sb.append( Strings.dumpBytes(responseValue) );
+            sb.append( "'\n" );
+        }
+
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/LdapEncoder.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/LdapEncoder.java
new file mode 100644
index 0000000..3a5f497
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/LdapEncoder.java
@@ -0,0 +1,2509 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.directory.shared.asn1.EncoderException;
+import org.apache.directory.shared.asn1.ber.tlv.TLV;
+import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
+import org.apache.directory.shared.asn1.ber.tlv.Value;
+import org.apache.directory.shared.asn1.util.Asn1StringUtils;
+import org.apache.directory.shared.i18n.I18n;
+import org.apache.directory.shared.ldap.codec.LdapConstants;
+import org.apache.directory.shared.ldap.codec.MessageEncoderException;
+import org.apache.directory.shared.ldap.codec.controls.CodecControl;
+import org.apache.directory.shared.ldap.entry.BinaryValue;
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.Modification;
+import org.apache.directory.shared.ldap.message.*;
+import org.apache.directory.shared.ldap.message.control.Control;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.apache.directory.shared.util.Strings;
+
+
+/**
+ * LDAP BER encoder.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class LdapEncoder
+{
+    /**
+     * Generate the PDU which contains the encoded object. 
+     * 
+     * The generation is done in two phases : 
+     * - first, we compute the length of each part and the
+     * global PDU length 
+     * - second, we produce the PDU. 
+     * 
+     * <pre>
+     * 0x30 L1 
+     *   | 
+     *   +--> 0x02 L2 MessageId  
+     *   +--> ProtocolOp 
+     *   +--> Controls 
+     *   
+     * L2 = Length(MessageId)
+     * L1 = Length(0x02) + Length(L2) + L2 + Length(ProtocolOp) + Length(Controls)
+     * LdapMessageLength = Length(0x30) + Length(L1) + L1
+     * </pre>
+     * 
+     * @param message The message to encode
+     * @return A ByteBuffer that contains the PDU
+     * @throws EncoderException If anything goes wrong.
+     */
+    public ByteBuffer encodeMessage( Message message ) throws EncoderException
+    {
+        int length = computeMessageLength( message );
+        ByteBuffer buffer = ByteBuffer.allocate( length );
+
+        try
+        {
+            try
+            {
+                // The LdapMessage Sequence
+                buffer.put( UniversalTag.SEQUENCE.getValue() );
+
+                // The length has been calculated by the computeLength method
+                buffer.put( TLV.getBytes( ( (AbstractMessage) message ).getMessageLength() ) );
+            }
+            catch ( BufferOverflowException boe )
+            {
+                throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+            }
+
+            // The message Id
+            Value.encode( buffer, message.getMessageId() );
+
+            // Add the protocolOp part
+            encodeProtocolOp( buffer, message );
+
+            // Do the same thing for Controls, if any.
+            Map<String, Control> controls = message.getControls();
+
+            if ( ( controls != null ) && ( controls.size() > 0 ) )
+            {
+                // Encode the controls
+                buffer.put( ( byte ) LdapConstants.CONTROLS_TAG );
+                buffer.put( TLV.getBytes( ( ( AbstractMessage ) message ).getControlsLength() ) );
+
+                // Encode each control
+                for ( Control control : controls.values() )
+                {
+                    ( ( CodecControl ) control ).encode( buffer );
+                }
+            }
+        }
+        catch ( EncoderException ee )
+        {
+            MessageEncoderException exception = new MessageEncoderException( message.getMessageId(), ee.getMessage() );
+
+            throw exception;
+        }
+
+        buffer.flip();
+
+        return buffer;
+    }
+
+
+    /**
+     * Compute the LdapMessage length LdapMessage : 
+     * 0x30 L1 
+     *   | 
+     *   +--> 0x02 0x0(1-4) [0..2^31-1] (MessageId) 
+     *   +--> protocolOp 
+     *   [+--> Controls] 
+     *   
+     * MessageId length = Length(0x02) + length(MessageId) + MessageId.length 
+     * L1 = length(ProtocolOp) 
+     * LdapMessage length = Length(0x30) + Length(L1) + MessageId length + L1
+     */
+    private int computeMessageLength( Message message )
+    {
+        // The length of the MessageId. It's the sum of
+        // - the tag (0x02), 1 byte
+        // - the length of the Id length, 1 byte
+        // - the Id length, 1 to 4 bytes
+        int ldapMessageLength = 1 + 1 + Value.getNbBytes( message.getMessageId() );
+
+        // Get the protocolOp length
+        ldapMessageLength += computeProtocolOpLength( message );
+
+        Map<String, Control> controls = message.getControls();
+
+        // Do the same thing for Controls, if any.
+        if ( controls.size() > 0 )
+        {
+            // Controls :
+            // 0xA0 L3
+            //   |
+            //   +--> 0x30 L4
+            //   +--> 0x30 L5
+            //   +--> ...
+            //   +--> 0x30 Li
+            //   +--> ...
+            //   +--> 0x30 Ln
+            //
+            // L3 = Length(0x30) + Length(L5) + L5
+            // + Length(0x30) + Length(L6) + L6
+            // + ...
+            // + Length(0x30) + Length(Li) + Li
+            // + ...
+            // + Length(0x30) + Length(Ln) + Ln
+            //
+            // LdapMessageLength = LdapMessageLength + Length(0x90)
+            // + Length(L3) + L3
+            int controlsSequenceLength = 0;
+
+            // We may have more than one control. ControlsLength is L4.
+            for ( Control control : controls.values() )
+            {
+                controlsSequenceLength += ( ( CodecControl ) control ).computeLength();
+            }
+
+            // Computes the controls length
+            // 1 + Length.getNbBytes( controlsSequenceLength ) + controlsSequenceLength;
+            ( ( AbstractMessage ) message ).setControlsLength( controlsSequenceLength );
+
+            // Now, add the tag and the length of the controls length
+            ldapMessageLength += 1 + TLV.getNbBytes( controlsSequenceLength ) + controlsSequenceLength;
+        }
+
+        // Store the messageLength
+        ( ( AbstractMessage ) message ).setMessageLength( ldapMessageLength );
+
+        // finally, calculate the global message size :
+        // length(Tag) + Length(length) + length
+
+        return 1 + ldapMessageLength + TLV.getNbBytes( ldapMessageLength );
+    }
+
+
+    /**
+     * Compute the LdapResult length 
+     * 
+     * LdapResult : 
+     * 0x0A 01 resultCode (0..80)
+     *   0x04 L1 matchedDN (L1 = Length(matchedDN)) 
+     *   0x04 L2 errorMessage (L2 = Length(errorMessage)) 
+     *   [0x83 L3] referrals 
+     *     | 
+     *     +--> 0x04 L4 referral 
+     *     +--> 0x04 L5 referral 
+     *     +--> ... 
+     *     +--> 0x04 Li referral 
+     *     +--> ... 
+     *     +--> 0x04 Ln referral 
+     *     
+     * L1 = Length(matchedDN) 
+     * L2 = Length(errorMessage) 
+     * L3 = n*Length(0x04) + sum(Length(L4) .. Length(Ln)) + sum(L4..Ln) 
+     * L4..n = Length(0x04) + Length(Li) + Li 
+     * Length(LdapResult) = Length(0x0x0A) +
+     *      Length(0x01) + 1 + Length(0x04) + Length(L1) + L1 + Length(0x04) +
+     *      Length(L2) + L2 + Length(0x83) + Length(L3) + L3
+     */
+    private int computeLdapResultLength( LdapResult internalLdapResult )
+    {
+        LdapResultImpl ldapResult = ( LdapResultImpl ) internalLdapResult;
+        int ldapResultLength = 0;
+
+        // The result code : always 3 bytes
+        ldapResultLength = 1 + 1 + 1;
+
+        // The matchedDN length
+        if ( ldapResult.getMatchedDn() == null )
+        {
+            ldapResultLength += 1 + 1;
+        }
+        else
+        {
+            byte[] matchedDNBytes = Strings.getBytesUtf8(StringTools
+                    .trimLeft(ldapResult.getMatchedDn().getName()));
+            ldapResultLength += 1 + TLV.getNbBytes( matchedDNBytes.length ) + matchedDNBytes.length;
+            ldapResult.setMatchedDnBytes( matchedDNBytes );
+        }
+
+        // The errorMessage length
+        byte[] errorMessageBytes = Strings.getBytesUtf8(ldapResult.getErrorMessage());
+        ldapResultLength += 1 + TLV.getNbBytes( errorMessageBytes.length ) + errorMessageBytes.length;
+        ldapResult.setErrorMessageBytes( errorMessageBytes );
+
+        int referralLength = computeReferralLength( ldapResult.getReferral() );
+
+        if ( referralLength != 0 )
+        {
+            // The referrals
+            ldapResultLength += 1 + TLV.getNbBytes( referralLength ) + referralLength;
+        }
+
+        return ldapResultLength;
+    }
+
+
+    /**
+     * Encode the LdapResult message to a PDU.
+     * 
+     * @param buffer The buffer where to put the PDU
+     * @return The PDU.
+     */
+    private ByteBuffer encodeLdapResult( ByteBuffer buffer, LdapResult internalLdapResult ) throws EncoderException
+    {
+        LdapResultImpl ldapResult = ( LdapResultImpl ) internalLdapResult;
+
+        if ( buffer == null )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
+        }
+
+        try
+        {
+            // The result code
+            buffer.put( UniversalTag.ENUMERATED.getValue() );
+            buffer.put( ( byte ) 1 );
+            buffer.put( ( byte ) ldapResult.getResultCode().getValue() );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+
+        // The matchedDN
+        Value.encode( buffer, ldapResult.getMatchedDnBytes() );
+
+        // The error message
+        Value.encode( buffer, ldapResult.getErrorMessageBytes() );
+
+        // The referrals, if any
+        Referral referral = ldapResult.getReferral();
+
+        if ( referral != null )
+        {
+            encodeReferral( buffer, referral );
+        }
+
+        return buffer;
+    }
+
+
+    /**
+     * Encode the Referral message to a PDU.
+     * 
+     * @param buffer The buffer where to put the PDU
+     * @return The PDU.
+     */
+    private void encodeReferral( ByteBuffer buffer, Referral referral ) throws EncoderException
+    {
+        Collection<byte[]> ldapUrlsBytes = referral.getLdapUrlsBytes();
+
+        if ( ( ldapUrlsBytes != null ) && ( ldapUrlsBytes.size() != 0 ) )
+        {
+            // Encode the referrals sequence
+            // The referrals length MUST have been computed before !
+            buffer.put( ( byte ) LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG );
+            buffer.put( TLV.getBytes( referral.getReferralLength() ) );
+
+            // Each referral
+            for ( byte[] ldapUrlBytes : ldapUrlsBytes )
+            {
+                // Encode the current referral
+                Value.encode( buffer, ldapUrlBytes );
+            }
+        }
+    }
+
+
+    /**
+     * Compute the AbandonRequest length 
+     * 
+     * AbandonRequest : 
+     * 0x50 0x0(1..4) abandoned MessageId 
+     * 
+     * Length(AbandonRequest) = Length(0x50) + 1 + Length(abandoned MessageId)
+     */
+    private int computeAbandonRequestLength( AbandonRequestImpl abandonRequest )
+    {
+        int length = 1 + 1 + Value.getNbBytes(abandonRequest.getAbandoned());
+
+        return length;
+    }
+
+
+    /**
+     * Compute the AddRequest length
+     * 
+     * AddRequest :
+     * 
+     * 0x68 L1
+     *  |
+     *  +--> 0x04 L2 entry
+     *  +--> 0x30 L3 (attributes)
+     *        |
+     *        +--> 0x30 L4-1 (attribute)
+     *        |     |
+     *        |     +--> 0x04 L5-1 type
+     *        |     +--> 0x31 L6-1 (values)
+     *        |           |
+     *        |           +--> 0x04 L7-1-1 value
+     *        |           +--> ...
+     *        |           +--> 0x04 L7-1-n value
+     *        |
+     *        +--> 0x30 L4-2 (attribute)
+     *        |     |
+     *        |     +--> 0x04 L5-2 type
+     *        |     +--> 0x31 L6-2 (values)
+     *        |           |
+     *        |           +--> 0x04 L7-2-1 value
+     *        |           +--> ...
+     *        |           +--> 0x04 L7-2-n value
+     *        |
+     *        +--> ...
+     *        |
+     *        +--> 0x30 L4-m (attribute)
+     *              |
+     *              +--> 0x04 L5-m type
+     *              +--> 0x31 L6-m (values)
+     *                    |
+     *                    +--> 0x04 L7-m-1 value
+     *                    +--> ...
+     *                    +--> 0x04 L7-m-n value
+     */
+    private int computeAddRequestLength( org.apache.directory.shared.ldap.codec.message.AddRequestImpl addRequest )
+    {
+        Entry entry = addRequest.getEntry();
+
+        if ( entry == null )
+        {
+            throw new IllegalArgumentException( I18n.err( I18n.ERR_04481_ENTRY_NULL_VALUE ) );
+        }
+
+        // The entry DN
+        int addRequestLength = 1 + TLV.getNbBytes( DN.getNbBytes( entry.getDn() ) ) + DN.getNbBytes( entry.getDn() );
+
+        // The attributes sequence
+        int entryLength = 0;
+
+        if ( entry.size() != 0 )
+        {
+            List<Integer> attributesLength = new LinkedList<Integer>();
+            List<Integer> valuesLength = new LinkedList<Integer>();
+
+            // Compute the attributes length
+            for ( EntryAttribute attribute : entry )
+            {
+                int localAttributeLength = 0;
+                int localValuesLength = 0;
+
+                // Get the type length
+                int idLength = attribute.getId().getBytes().length;
+                localAttributeLength = 1 + TLV.getNbBytes( idLength ) + idLength;
+
+                // The values
+                if ( attribute.size() != 0 )
+                {
+                    localValuesLength = 0;
+
+                    for ( org.apache.directory.shared.ldap.entry.Value<?> value : attribute )
+                    {
+                        int valueLength = value.getBytes().length;
+                        localValuesLength += 1 + TLV.getNbBytes( valueLength ) + valueLength;
+                    }
+
+                    localAttributeLength += 1 + TLV.getNbBytes( localValuesLength ) + localValuesLength;
+                }
+
+                // add the attribute length to the attributes length
+                entryLength += 1 + TLV.getNbBytes( localAttributeLength ) + localAttributeLength;
+
+                attributesLength.add( localAttributeLength );
+                valuesLength.add( localValuesLength );
+            }
+
+            addRequest.setAttributesLength( attributesLength );
+            addRequest.setValuesLength( valuesLength );
+            addRequest.setEntryLength( entryLength );
+        }
+
+        addRequestLength += 1 + TLV.getNbBytes( entryLength ) + entryLength;
+        addRequest.setAddRequestLength( addRequestLength );
+
+        // Return the result.
+        return 1 + TLV.getNbBytes( addRequestLength ) + addRequestLength;
+    }
+
+
+    /**
+     * Compute the AddResponse length 
+     * 
+     * AddResponse : 
+     * 
+     * 0x69 L1
+     *  |
+     *  +--> LdapResult
+     * 
+     * L1 = Length(LdapResult)
+     * 
+     * Length(AddResponse) = Length(0x69) + Length(L1) + L1
+     */
+    private int computeAddResponseLength( org.apache.directory.shared.ldap.codec.message.AddResponseImpl addResponse )
+    {
+        int addResponseLength = computeLdapResultLength( addResponse.getLdapResult() );
+
+        addResponse.setAddResponseLength( addResponseLength );
+
+        return 1 + TLV.getNbBytes( addResponseLength ) + addResponseLength;
+    }
+
+
+    /**
+     * Compute the BindRequest length 
+     * 
+     * BindRequest : 
+     * <pre>
+     * 0x60 L1 
+     *   | 
+     *   +--> 0x02 0x01 (1..127) version 
+     *   +--> 0x04 L2 name 
+     *   +--> authentication 
+     *   
+     * L2 = Length(name)
+     * L3/4 = Length(authentication) 
+     * Length(BindRequest) = Length(0x60) + Length(L1) + L1 + Length(0x02) + 1 + 1 + 
+     *      Length(0x04) + Length(L2) + L2 + Length(authentication)
+     * </pre>
+     */
+    private int computeBindRequestLength( org.apache.directory.shared.ldap.codec.message.BindRequestImpl bindRequest )
+    {
+        int bindRequestLength = 1 + 1 + 1; // Initialized with version
+
+        // The name
+        bindRequestLength += 1 + TLV.getNbBytes( DN.getNbBytes( bindRequest.getName() ) )
+            + DN.getNbBytes( bindRequest.getName() );
+
+        byte[] credentials = bindRequest.getCredentials();
+
+        // The authentication
+        if ( bindRequest.isSimple() )
+        {
+            // Compute a SimpleBind operation
+            if ( credentials != null )
+            {
+                bindRequestLength += 1 + TLV.getNbBytes( credentials.length ) + credentials.length;
+            }
+            else
+            {
+                bindRequestLength += 1 + 1;
+            }
+        }
+        else
+        {
+            byte[] mechanismBytes = Strings.getBytesUtf8(bindRequest.getSaslMechanism());
+            int saslMechanismLength = 1 + TLV.getNbBytes( mechanismBytes.length ) + mechanismBytes.length;
+            int saslCredentialsLength = 0;
+
+            if ( credentials != null )
+            {
+                saslCredentialsLength = 1 + TLV.getNbBytes( credentials.length ) + credentials.length;
+            }
+
+            int saslLength = 1 + TLV.getNbBytes( saslMechanismLength + saslCredentialsLength ) + saslMechanismLength
+                + saslCredentialsLength;
+
+            bindRequestLength += saslLength;
+
+            // Store the mechanism and credentials lengths
+            bindRequest.setSaslMechanismLength( saslMechanismLength );
+            bindRequest.setSaslCredentialsLength( saslCredentialsLength );
+        }
+
+        bindRequest.setBindRequestLength( bindRequestLength );
+
+        // Return the result.
+        return 1 + TLV.getNbBytes( bindRequestLength ) + bindRequestLength;
+    }
+
+
+    /**
+     * Compute the BindResponse length 
+     * 
+     * BindResponse : 
+     * <pre>
+     * 0x61 L1 
+     *   | 
+     *   +--> LdapResult
+     *   +--> [serverSaslCreds] 
+     *   
+     * L1 = Length(LdapResult) [ + Length(serverSaslCreds) ] 
+     * Length(BindResponse) = Length(0x61) + Length(L1) + L1
+     * </pre>
+     */
+    private int computeBindResponseLength( org.apache.directory.shared.ldap.codec.message.BindResponseImpl bindResponse )
+    {
+        int ldapResultLength = computeLdapResultLength( bindResponse.getLdapResult() );
+
+        int bindResponseLength = ldapResultLength;
+
+        byte[] serverSaslCreds = bindResponse.getServerSaslCreds();
+
+        if ( serverSaslCreds != null )
+        {
+            bindResponseLength += 1 + TLV.getNbBytes( serverSaslCreds.length ) + serverSaslCreds.length;
+        }
+
+        bindResponse.setBindResponseLength( bindResponseLength );
+
+        return 1 + TLV.getNbBytes( bindResponseLength ) + bindResponseLength;
+    }
+
+
+    /**
+     * Compute the CompareRequest length 
+     * 
+     * CompareRequest : 
+     * 0x6E L1 
+     *   | 
+     *   +--> 0x04 L2 entry 
+     *   +--> 0x30 L3 (ava) 
+     *         | 
+     *         +--> 0x04 L4 attributeDesc 
+     *         +--> 0x04 L5 assertionValue 
+     *         
+     * L3 = Length(0x04) + Length(L4) + L4 + Length(0x04) +
+     *      Length(L5) + L5 
+     * Length(CompareRequest) = Length(0x6E) + Length(L1) + L1 +
+     *      Length(0x04) + Length(L2) + L2 + Length(0x30) + Length(L3) + L3
+     * 
+     * @return The CompareRequest PDU's length
+     */
+    private int computeCompareRequestLength( org.apache.directory.shared.ldap.codec.message.CompareRequestImpl compareRequest )
+    {
+        // The entry DN
+        DN entry = compareRequest.getName();
+        int compareRequestLength = 1 + TLV.getNbBytes( DN.getNbBytes( entry ) ) + DN.getNbBytes( entry );
+
+        // The attribute value assertion
+        byte[] attributeIdBytes = Strings.getBytesUtf8(compareRequest.getAttributeId());
+        int avaLength = 1 + TLV.getNbBytes( attributeIdBytes.length ) + attributeIdBytes.length;
+        compareRequest.setAttrIdBytes( attributeIdBytes );
+
+        if ( compareRequest.getAssertionValue() instanceof BinaryValue )
+        {
+            byte[] value = compareRequest.getAssertionValue().getBytes();
+            avaLength += 1 + TLV.getNbBytes( value.length ) + value.length;
+            compareRequest.setAttrValBytes( value );
+        }
+        else
+        {
+            byte[] value = Strings.getBytesUtf8(compareRequest.getAssertionValue().getString());
+            avaLength += 1 + TLV.getNbBytes( value.length ) + value.length;
+            compareRequest.setAttrValBytes( value );
+        }
+
+        compareRequest.setAvaLength( avaLength );
+        compareRequestLength += 1 + TLV.getNbBytes( avaLength ) + avaLength;
+        compareRequest.setCompareRequestLength( compareRequestLength );
+
+        return 1 + TLV.getNbBytes( compareRequestLength ) + compareRequestLength;
+
+    }
+
+
+    /**
+     * Compute the CompareResponse length 
+     * 
+     * CompareResponse :
+     * 
+     * 0x6F L1
+     *  |
+     *  +--> LdapResult
+     * 
+     * L1 = Length(LdapResult)
+     * 
+     * Length(CompareResponse) = Length(0x6F) + Length(L1) + L1
+     */
+    private int computeCompareResponseLength( org.apache.directory.shared.ldap.codec.message.CompareResponseImpl compareResponse )
+    {
+        int compareResponseLength = computeLdapResultLength( compareResponse.getLdapResult() );
+
+        compareResponse.setCompareResponseLength( compareResponseLength );
+
+        return 1 + TLV.getNbBytes( compareResponseLength ) + compareResponseLength;
+    }
+
+
+    /**
+     * Compute the DelRequest length 
+     * 
+     * DelRequest : 
+     * 0x4A L1 entry 
+     * 
+     * L1 = Length(entry) 
+     * Length(DelRequest) = Length(0x4A) + Length(L1) + L1
+     */
+    private int computeDeleteRequestLength( org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl deleteRequest )
+    {
+        // The entry
+        return 1 + TLV.getNbBytes( DN.getNbBytes( deleteRequest.getName() ) ) + DN.getNbBytes( deleteRequest.getName() );
+    }
+
+
+    /**
+     * Compute the DelResponse length 
+     * 
+     * DelResponse :
+     * 
+     * 0x6B L1
+     *  |
+     *  +--> LdapResult
+     * 
+     * L1 = Length(LdapResult)
+     * 
+     * Length(DelResponse) = Length(0x6B) + Length(L1) + L1
+     */
+    private int computeDeleteResponseLength( org.apache.directory.shared.ldap.codec.message.DeleteResponseImpl deleteResponse )
+    {
+        int deleteResponseLength = computeLdapResultLength( deleteResponse.getLdapResult() );
+
+        deleteResponse.setDeleteResponseLength( deleteResponseLength );
+
+        return 1 + TLV.getNbBytes( deleteResponseLength ) + deleteResponseLength;
+    }
+
+
+    /**
+     * Compute the ExtendedRequest length
+     * 
+     * ExtendedRequest :
+     * 
+     * 0x77 L1
+     *  |
+     *  +--> 0x80 L2 name
+     *  [+--> 0x81 L3 value]
+     * 
+     * L1 = Length(0x80) + Length(L2) + L2
+     *      [+ Length(0x81) + Length(L3) + L3]
+     * 
+     * Length(ExtendedRequest) = Length(0x77) + Length(L1) + L1
+     */
+    private int computeExtendedRequestLength( org.apache.directory.shared.ldap.codec.message.ExtendedRequestImpl extendedRequest )
+    {
+        byte[] requestNameBytes = Strings.getBytesUtf8(extendedRequest.getRequestName());
+
+        extendedRequest.setRequestNameBytes( requestNameBytes );
+
+        int extendedRequestLength = 1 + TLV.getNbBytes( requestNameBytes.length ) + requestNameBytes.length;
+
+        if ( extendedRequest.getRequestValue() != null )
+        {
+            extendedRequestLength += 1 + TLV.getNbBytes( extendedRequest.getRequestValue().length )
+                + extendedRequest.getRequestValue().length;
+        }
+
+        extendedRequest.setExtendedRequestLength( extendedRequestLength );
+
+        return 1 + TLV.getNbBytes( extendedRequestLength ) + extendedRequestLength;
+    }
+
+
+    /**
+     * Compute the ExtendedResponse length
+     * 
+     * ExtendedResponse :
+     * 
+     * 0x78 L1
+     *  |
+     *  +--> LdapResult
+     * [+--> 0x8A L2 name
+     * [+--> 0x8B L3 response]]
+     * 
+     * L1 = Length(LdapResult)
+     *      [ + Length(0x8A) + Length(L2) + L2
+     *       [ + Length(0x8B) + Length(L3) + L3]]
+     * 
+     * Length(ExtendedResponse) = Length(0x78) + Length(L1) + L1
+     * 
+     * @return The ExtendedResponse length
+     */
+    private int computeExtendedResponseLength( org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl extendedResponse )
+    {
+        int ldapResultLength = computeLdapResultLength( extendedResponse.getLdapResult() );
+
+        int extendedResponseLength = ldapResultLength;
+
+        String id = extendedResponse.getResponseName();
+
+        if ( !Strings.isEmpty(id) )
+        {
+            byte[] idBytes = Strings.getBytesUtf8(id);
+            extendedResponse.setResponseNameBytes( idBytes );
+            int idLength = idBytes.length;
+            extendedResponseLength += 1 + TLV.getNbBytes( idLength ) + idLength;
+        }
+
+        byte[] encodedValue = extendedResponse.getResponseValue();
+
+        if ( encodedValue != null )
+        {
+            extendedResponseLength += 1 + TLV.getNbBytes( encodedValue.length ) + encodedValue.length;
+        }
+
+        extendedResponse.setExtendedResponseLength( extendedResponseLength );
+
+        return 1 + TLV.getNbBytes( extendedResponseLength ) + extendedResponseLength;
+    }
+
+
+    /**
+     * Compute the intermediateResponse length
+     * 
+     * intermediateResponse :
+     * 
+     * 0x79 L1
+     *  |
+     * [+--> 0x80 L2 name
+     * [+--> 0x81 L3 response]]
+     * 
+     * L1 = [ + Length(0x80) + Length(L2) + L2
+     *      [ + Length(0x81) + Length(L3) + L3]]
+     * 
+     * Length(IntermediateResponse) = Length(0x79) + Length(L1) + L1
+     * 
+     * @return The IntermediateResponse length
+     */
+    private int computeIntermediateResponseLength( org.apache.directory.shared.ldap.codec.message.IntermediateResponseImpl intermediateResponse )
+    {
+        int intermediateResponseLength = 0;
+
+        if ( !Strings.isEmpty(intermediateResponse.getResponseName()) )
+        {
+            byte[] responseNameBytes = Strings.getBytesUtf8(intermediateResponse.getResponseName());
+
+            int responseNameLength = responseNameBytes.length;
+            intermediateResponseLength += 1 + TLV.getNbBytes( responseNameLength ) + responseNameLength;
+            intermediateResponse.setResponseNameBytes( responseNameBytes );
+        }
+
+        byte[] encodedValue = intermediateResponse.getResponseValue();
+
+        if ( encodedValue != null )
+        {
+            intermediateResponseLength += 1 + TLV.getNbBytes( encodedValue.length ) + encodedValue.length;
+        }
+
+        intermediateResponse.setIntermediateResponseLength( intermediateResponseLength );
+
+        return 1 + TLV.getNbBytes( intermediateResponseLength ) + intermediateResponseLength;
+    }
+
+
+    /**
+     * Compute the ModifyRequest length 
+     * 
+     * ModifyRequest :
+     * 
+     * 0x66 L1
+     *  |
+     *  +--> 0x04 L2 object
+     *  +--> 0x30 L3 modifications
+     *        |
+     *        +--> 0x30 L4-1 modification sequence
+     *        |     |
+     *        |     +--> 0x0A 0x01 (0..2) operation
+     *        |     +--> 0x30 L5-1 modification
+     *        |           |
+     *        |           +--> 0x04 L6-1 type
+     *        |           +--> 0x31 L7-1 vals
+     *        |                 |
+     *        |                 +--> 0x04 L8-1-1 attributeValue
+     *        |                 +--> 0x04 L8-1-2 attributeValue
+     *        |                 +--> ...
+     *        |                 +--> 0x04 L8-1-i attributeValue
+     *        |                 +--> ...
+     *        |                 +--> 0x04 L8-1-n attributeValue
+     *        |
+     *        +--> 0x30 L4-2 modification sequence
+     *        .     |
+     *        .     +--> 0x0A 0x01 (0..2) operation
+     *        .     +--> 0x30 L5-2 modification
+     *                    |
+     *                    +--> 0x04 L6-2 type
+     *                    +--> 0x31 L7-2 vals
+     *                          |
+     *                          +--> 0x04 L8-2-1 attributeValue
+     *                          +--> 0x04 L8-2-2 attributeValue
+     *                          +--> ...
+     *                          +--> 0x04 L8-2-i attributeValue
+     *                          +--> ...
+     *                          +--> 0x04 L8-2-n attributeValue
+     */
+    private int computeModifyRequestLength( ModifyRequestImpl modifyRequest )
+    {
+        // Initialized with name
+        int modifyRequestLength = 1 + TLV.getNbBytes( DN.getNbBytes( modifyRequest.getName() ) )
+            + DN.getNbBytes( modifyRequest.getName() );
+
+        // All the changes length
+        int changesLength = 0;
+
+        Collection<Modification> modifications = modifyRequest.getModifications();
+
+        if ( ( modifications != null ) && ( modifications.size() != 0 ) )
+        {
+            List<Integer> changeLength = new LinkedList<Integer>();
+            List<Integer> modificationLength = new LinkedList<Integer>();
+            List<Integer> valuesLength = new LinkedList<Integer>();
+
+            for ( Modification modification : modifications )
+            {
+                // Modification sequence length initialized with the operation
+                int localModificationSequenceLength = 1 + 1 + 1;
+                int localValuesLength = 0;
+
+                // Modification length initialized with the type
+                int typeLength = modification.getAttribute().getId().length();
+                int localModificationLength = 1 + TLV.getNbBytes( typeLength ) + typeLength;
+
+                // Get all the values
+                if ( modification.getAttribute().size() != 0 )
+                {
+                    for ( org.apache.directory.shared.ldap.entry.Value<?> value : modification.getAttribute() )
+                    {
+                        localValuesLength += 1 + TLV.getNbBytes( value.getBytes().length ) + value.getBytes().length;
+                    }
+                }
+
+                localModificationLength += 1 + TLV.getNbBytes( localValuesLength ) + localValuesLength;
+
+                // Compute the modificationSequenceLength
+                localModificationSequenceLength += 1 + TLV.getNbBytes( localModificationLength )
+                    + localModificationLength;
+
+                // Add the tag and the length
+                changesLength += 1 + TLV.getNbBytes( localModificationSequenceLength )
+                    + localModificationSequenceLength;
+
+                // Store the arrays of values
+                valuesLength.add( localValuesLength );
+                modificationLength.add( localModificationLength );
+                changeLength.add( localModificationSequenceLength );
+            }
+
+            // Add the modifications length to the modificationRequestLength
+            modifyRequestLength += 1 + TLV.getNbBytes( changesLength ) + changesLength;
+            modifyRequest.setChangeLength( changeLength );
+            modifyRequest.setModificationLength( modificationLength );
+            modifyRequest.setValuesLength( valuesLength );
+        }
+
+        modifyRequest.setChangesLength( changesLength );
+        modifyRequest.setModifyRequestLength( modifyRequestLength );
+
+        return 1 + TLV.getNbBytes( modifyRequestLength ) + modifyRequestLength;
+
+    }
+
+
+    /**
+     * Compute the ModifyResponse length 
+     * 
+     * ModifyResponse : 
+     * <pre>
+     * 0x67 L1 
+     *   | 
+     *   +--> LdapResult 
+     *   
+     * L1 = Length(LdapResult) 
+     * Length(ModifyResponse) = Length(0x67) + Length(L1) + L1
+     * </pre>
+     */
+    private int computeModifyResponseLength( ModifyResponseImpl modifyResponse )
+    {
+        int modifyResponseLength = computeLdapResultLength( modifyResponse.getLdapResult() );
+
+        modifyResponse.setModifyResponseLength( modifyResponseLength );
+
+        return 1 + TLV.getNbBytes( modifyResponseLength ) + modifyResponseLength;
+    }
+
+
+    /**
+     * Compute the ModifyDNRequest length
+     * 
+     * ModifyDNRequest :
+     * <pre>
+     * 0x6C L1
+     *  |
+     *  +--> 0x04 L2 entry
+     *  +--> 0x04 L3 newRDN
+     *  +--> 0x01 0x01 (true/false) deleteOldRDN (3 bytes)
+     * [+--> 0x80 L4 newSuperior ] 
+     * 
+     * L2 = Length(0x04) + Length(Length(entry)) + Length(entry) 
+     * L3 = Length(0x04) + Length(Length(newRDN)) + Length(newRDN) 
+     * L4 = Length(0x80) + Length(Length(newSuperior)) + Length(newSuperior)
+     * L1 = L2 + L3 + 3 [+ L4] 
+     * 
+     * Length(ModifyDNRequest) = Length(0x6C) + Length(L1) + L1
+     * </pre>
+     * 
+     * @return The PDU's length of a ModifyDN Request
+     */
+    private int computeModifyDnRequestLength( ModifyDnRequestImpl modifyDnResponse )
+    {
+        int newRdnlength = Strings.getBytesUtf8(modifyDnResponse.getNewRdn().getName()).length;
+
+        int modifyDNRequestLength = 1 + TLV.getNbBytes( DN.getNbBytes( modifyDnResponse.getName() ) )
+            + DN.getNbBytes( modifyDnResponse.getName() ) + 1 + TLV.getNbBytes( newRdnlength ) + newRdnlength + 1 + 1
+            + 1; // deleteOldRDN
+
+        if ( modifyDnResponse.getNewSuperior() != null )
+        {
+            modifyDNRequestLength += 1 + TLV.getNbBytes( DN.getNbBytes( modifyDnResponse.getNewSuperior() ) )
+                + DN.getNbBytes( modifyDnResponse.getNewSuperior() );
+        }
+
+        modifyDnResponse.setModifyDnRequestLength( modifyDNRequestLength );
+
+        return 1 + TLV.getNbBytes( modifyDNRequestLength ) + modifyDNRequestLength;
+    }
+
+
+    /**
+     * Compute the ModifyDNResponse length 
+     * 
+     * ModifyDNResponse : 
+     * <pre>
+     * 0x6D L1 
+     *   | 
+     *   +--> LdapResult 
+     *   
+     * L1 = Length(LdapResult) 
+     * Length(ModifyDNResponse) = Length(0x6D) + Length(L1) + L1
+     * </pre>
+     */
+    private int computeModifyDnResponseLength( ModifyDnResponseImpl modifyDnResponse )
+    {
+        int modifyDnResponseLength = computeLdapResultLength( modifyDnResponse.getLdapResult() );
+
+        modifyDnResponse.setModifyDnResponseLength( modifyDnResponseLength );
+
+        return 1 + TLV.getNbBytes( modifyDnResponseLength ) + modifyDnResponseLength;
+    }
+
+
+    private int computeReferralLength( Referral referral )
+    {
+        if ( referral != null )
+        {
+            Collection<String> ldapUrls = referral.getLdapUrls();
+
+            if ( ( ldapUrls != null ) && ( ldapUrls.size() != 0 ) )
+            {
+                int referralLength = 0;
+
+                // Each referral
+                for ( String ldapUrl : ldapUrls )
+                {
+                    byte[] ldapUrlBytes = Strings.getBytesUtf8(ldapUrl);
+                    referralLength += 1 + TLV.getNbBytes( ldapUrlBytes.length ) + ldapUrlBytes.length;
+                    referral.addLdapUrlBytes( ldapUrlBytes );
+                }
+
+                referral.setReferralLength( referralLength );
+
+                return referralLength;
+            }
+            else
+            {
+                return 0;
+            }
+        }
+        else
+        {
+            return 0;
+        }
+    }
+
+
+    /**
+     * Compute the SearchRequest length
+     * 
+     * SearchRequest :
+     * <pre>
+     * 0x63 L1
+     *  |
+     *  +--> 0x04 L2 baseObject
+     *  +--> 0x0A 0x01 scope
+     *  +--> 0x0A 0x01 derefAliases
+     *  +--> 0x02 0x0(1..4) sizeLimit
+     *  +--> 0x02 0x0(1..4) timeLimit
+     *  +--> 0x01 0x01 typesOnly
+     *  +--> filter.computeLength()
+     *  +--> 0x30 L3 (Attribute description list)
+     *        |
+     *        +--> 0x04 L4-1 Attribute description 
+     *        +--> 0x04 L4-2 Attribute description 
+     *        +--> ... 
+     *        +--> 0x04 L4-i Attribute description 
+     *        +--> ... 
+     *        +--> 0x04 L4-n Attribute description 
+     *        </pre>
+     */
+    private int computeSearchRequestLength( SearchRequestImpl searchRequest )
+    {
+        int searchRequestLength = 0;
+
+        // The baseObject
+        searchRequestLength += 1 + TLV.getNbBytes( DN.getNbBytes( searchRequest.getBase() ) )
+            + DN.getNbBytes( searchRequest.getBase() );
+
+        // The scope
+        searchRequestLength += 1 + 1 + 1;
+
+        // The derefAliases
+        searchRequestLength += 1 + 1 + 1;
+
+        // The sizeLimit
+        searchRequestLength += 1 + 1 + Value.getNbBytes( searchRequest.getSizeLimit() );
+
+        // The timeLimit
+        searchRequestLength += 1 + 1 + Value.getNbBytes( searchRequest.getTimeLimit() );
+
+        // The typesOnly
+        searchRequestLength += 1 + 1 + 1;
+
+        // The filter
+        searchRequestLength += searchRequest.getCurrentFilter().computeLength();
+
+        // The attributes description list
+        int attributeDescriptionListLength = 0;
+
+        if ( ( searchRequest.getAttributes() != null ) && ( searchRequest.getAttributes().size() != 0 ) )
+        {
+            // Compute the attributes length
+            for ( String attribute : searchRequest.getAttributes() )
+            {
+                // add the attribute length to the attributes length
+                int idLength = Strings.getBytesUtf8(attribute).length;
+                attributeDescriptionListLength += 1 + TLV.getNbBytes( idLength ) + idLength;
+            }
+        }
+
+        searchRequest.setAttributeDescriptionListLength( attributeDescriptionListLength );
+
+        searchRequestLength += 1 + TLV.getNbBytes( attributeDescriptionListLength ) + attributeDescriptionListLength;
+
+        searchRequest.setSearchRequestLength( searchRequestLength );
+        // Return the result.
+        return 1 + TLV.getNbBytes( searchRequestLength ) + searchRequestLength;
+    }
+
+
+    /**
+     * Compute the SearchResultDone length 
+     * 
+     * SearchResultDone : 
+     * <pre>
+     * 0x65 L1 
+     *   | 
+     *   +--> LdapResult 
+     *   
+     * L1 = Length(LdapResult) 
+     * Length(SearchResultDone) = Length(0x65) + Length(L1) + L1
+     * </pre>
+     */
+    private int computeSearchResultDoneLength( SearchResultDoneImpl searchResultDone )
+    {
+        int searchResultDoneLength = computeLdapResultLength( searchResultDone.getLdapResult() );
+
+        searchResultDone.setSearchResultDoneLength( searchResultDoneLength );
+
+        return 1 + TLV.getNbBytes( searchResultDoneLength ) + searchResultDoneLength;
+    }
+
+
+    /**
+     * Compute the SearchResultEntry length
+     * 
+     * SearchResultEntry :
+     * <pre>
+     * 0x64 L1
+     *  |
+     *  +--> 0x04 L2 objectName
+     *  +--> 0x30 L3 (attributes)
+     *        |
+     *        +--> 0x30 L4-1 (partial attributes list)
+     *        |     |
+     *        |     +--> 0x04 L5-1 type
+     *        |     +--> 0x31 L6-1 (values)
+     *        |           |
+     *        |           +--> 0x04 L7-1-1 value
+     *        |           +--> ...
+     *        |           +--> 0x04 L7-1-n value
+     *        |
+     *        +--> 0x30 L4-2 (partial attributes list)
+     *        |     |
+     *        |     +--> 0x04 L5-2 type
+     *        |     +--> 0x31 L6-2 (values)
+     *        |           |
+     *        |           +--> 0x04 L7-2-1 value
+     *        |           +--> ...
+     *        |           +--> 0x04 L7-2-n value
+     *        |
+     *        +--> ...
+     *        |
+     *        +--> 0x30 L4-m (partial attributes list)
+     *              |
+     *              +--> 0x04 L5-m type
+     *              +--> 0x31 L6-m (values)
+     *                    |
+     *                    +--> 0x04 L7-m-1 value
+     *                    +--> ...
+     *                    +--> 0x04 L7-m-n value
+     * </pre>
+     */
+    private int computeSearchResultEntryLength( SearchResultEntryImpl searchResultEntry )
+    {
+        DN dn = searchResultEntry.getObjectName();
+
+        byte[] dnBytes = Strings.getBytesUtf8(dn.getName());
+
+        // The entry
+        int searchResultEntryLength = 1 + TLV.getNbBytes( dnBytes.length ) + dnBytes.length;
+        searchResultEntry.setObjectNameBytes( dnBytes );
+
+        // The attributes sequence
+        int attributesLength = 0;
+
+        Entry entry = searchResultEntry.getEntry();
+
+        if ( ( entry != null ) && ( entry.size() != 0 ) )
+        {
+            List<Integer> attributeLength = new LinkedList<Integer>();
+            List<Integer> valsLength = new LinkedList<Integer>();
+
+            // Store those lists in the object
+            searchResultEntry.setAttributeLength( attributeLength );
+            searchResultEntry.setValsLength( valsLength );
+
+            // Compute the attributes length
+            for ( EntryAttribute attribute : entry )
+            {
+                int localAttributeLength = 0;
+                int localValuesLength = 0;
+
+                // Get the type length
+                int idLength = attribute.getId().getBytes().length;
+                localAttributeLength = 1 + TLV.getNbBytes( idLength ) + idLength;
+
+                if ( attribute.size() != 0 )
+                {
+                    // The values
+                    if ( attribute.size() > 0 )
+                    {
+                        localValuesLength = 0;
+
+                        for ( org.apache.directory.shared.ldap.entry.Value<?> value : attribute )
+                        {
+                            byte[] binaryValue = value.getBytes();
+                            localValuesLength += 1 + TLV.getNbBytes( binaryValue.length ) + binaryValue.length;
+                        }
+
+                        localAttributeLength += 1 + TLV.getNbBytes( localValuesLength ) + localValuesLength;
+                    }
+                    else
+                    {
+                        // We have to deal with the special wase where
+                        // we don't have a value.
+                        // It will be encoded as an empty OCTETSTRING,
+                        // so it will be two byte slong (0x04 0x00)
+                        localAttributeLength += 1 + 1;
+                    }
+                }
+                else
+                {
+                    // We have no values. We will just have an empty SET OF :
+                    // 0x31 0x00
+                    localAttributeLength += 1 + 1;
+                }
+
+                // add the attribute length to the attributes length
+                attributesLength += 1 + TLV.getNbBytes( localAttributeLength ) + localAttributeLength;
+
+                // Store the lengths of the encoded attributes and values
+                attributeLength.add( localAttributeLength );
+                valsLength.add( localValuesLength );
+            }
+
+            // Store the lengths of the entry
+            searchResultEntry.setAttributesLength( attributesLength );
+        }
+
+        searchResultEntryLength += 1 + TLV.getNbBytes( attributesLength ) + attributesLength;
+
+        // Store the length of the response 
+        searchResultEntry.setSearchResultEntryLength( searchResultEntryLength );
+
+        // Return the result.
+        return 1 + TLV.getNbBytes( searchResultEntryLength ) + searchResultEntryLength;
+    }
+
+
+    /**
+     * Compute the SearchResultReference length
+     * 
+     * SearchResultReference :
+     * <pre>
+     * 0x73 L1
+     *  |
+     *  +--> 0x04 L2 reference
+     *  +--> 0x04 L3 reference
+     *  +--> ...
+     *  +--> 0x04 Li reference
+     *  +--> ...
+     *  +--> 0x04 Ln reference
+     * 
+     * L1 = n*Length(0x04) + sum(Length(Li)) + sum(Length(reference[i]))
+     * 
+     * Length(SearchResultReference) = Length(0x73 + Length(L1) + L1
+     * </pre>
+     */
+    private int computeSearchResultReferenceLength( SearchResultReferenceImpl searchResultReference )
+    {
+        int searchResultReferenceLength = 0;
+
+        // We may have more than one reference.
+        Referral referral = searchResultReference.getReferral();
+
+        int referralLength = computeReferralLength( referral );
+
+        if ( referralLength != 0 )
+        {
+            searchResultReference.setReferral( referral );
+
+            searchResultReferenceLength = referralLength;
+        }
+
+        // Store the length of the response 
+        searchResultReference.setSearchResultReferenceLength( searchResultReferenceLength );
+
+        return 1 + TLV.getNbBytes( searchResultReferenceLength ) + searchResultReferenceLength;
+    }
+
+
+    /**
+     * Compute the UnBindRequest length 
+     * 
+     * UnBindRequest : 
+     * 0x42 00
+     */
+    private int computeUnbindRequestLength( )
+    {
+        return 2; // Always 2
+    }
+
+
+    /**
+     * Encode the Abandon protocolOp part
+     */
+    private void encodeAbandonRequest( ByteBuffer buffer, AbandonRequestImpl abandonRequest ) throws EncoderException
+    {
+        try
+        {
+            // The tag
+            buffer.put( LdapConstants.ABANDON_REQUEST_TAG );
+
+            // The length. It has to be evaluated depending on
+            // the abandoned messageId value.
+            buffer.put( ( byte ) Value.getNbBytes( abandonRequest.getAbandoned() ) );
+
+            // The abandoned messageId
+            buffer.put( Value.getBytes( abandonRequest.getAbandoned() ) );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            String msg = I18n.err( I18n.ERR_04005 );
+            throw new EncoderException( msg );
+        }
+    }
+
+
+    /**
+     * Encode the AddRequest message to a PDU. 
+     * 
+     * AddRequest :
+     * 
+     * 0x68 LL
+     *   0x04 LL entry
+     *   0x30 LL attributesList
+     *     0x30 LL attributeList
+     *       0x04 LL attributeDescription
+     *       0x31 LL attributeValues
+     *         0x04 LL attributeValue
+     *         ... 
+     *         0x04 LL attributeValue
+     *     ... 
+     *     0x30 LL attributeList
+     *       0x04 LL attributeDescription
+     *       0x31 LL attributeValue
+     *         0x04 LL attributeValue
+     *         ... 
+     *         0x04 LL attributeValue 
+     * 
+     * @param buffer The buffer where to put the PDU
+     */
+    private void encodeAddRequest( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.AddRequestImpl addRequest ) throws EncoderException
+    {
+        try
+        {
+            // The AddRequest Tag
+            buffer.put( LdapConstants.ADD_REQUEST_TAG );
+            buffer.put( TLV.getBytes( addRequest.getAddRequestLength() ) );
+
+            // The entry
+            Value.encode( buffer, DN.getBytes( addRequest.getEntryDn() ) );
+
+            // The attributes sequence
+            buffer.put( UniversalTag.SEQUENCE.getValue() );
+            buffer.put( TLV.getBytes( addRequest.getEntryLength() ) );
+
+            // The partial attribute list
+            Entry entry = addRequest.getEntry();
+
+            if ( entry.size() != 0 )
+            {
+                int attributeNumber = 0;
+
+                // Compute the attributes length
+                for ( EntryAttribute attribute : entry )
+                {
+                    // The attributes list sequence
+                    buffer.put( UniversalTag.SEQUENCE.getValue() );
+                    int localAttributeLength = addRequest.getAttributesLength().get( attributeNumber );
+                    buffer.put( TLV.getBytes( localAttributeLength ) );
+
+                    // The attribute type
+                    Value.encode( buffer, attribute.getId() );
+
+                    // The values
+                    buffer.put( UniversalTag.SET.getValue() );
+                    int localValuesLength = addRequest.getValuesLength().get( attributeNumber );
+                    buffer.put( TLV.getBytes( localValuesLength ) );
+
+                    if ( attribute.size() != 0 )
+                    {
+                        for ( org.apache.directory.shared.ldap.entry.Value<?> value : attribute )
+                        {
+                            if ( value.isBinary() )
+                            {
+                                Value.encode( buffer, value.getBytes() );
+                            }
+                            else
+                            {
+                                Value.encode(buffer, value.getString());
+                            }
+                        }
+                    }
+
+                    // Go to the next attribute number;
+                    attributeNumber++;
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( "The PDU buffer size is too small !" );
+        }
+    }
+
+
+    /**
+     * Encode the AddResponse message to a PDU.
+     * 
+     * @param buffer The buffer where to put the PDU
+     */
+    private void encodeAddResponse( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.AddResponseImpl addResponse ) throws EncoderException
+    {
+        try
+        {
+            // The AddResponse Tag
+            buffer.put( LdapConstants.ADD_RESPONSE_TAG );
+            buffer.put( TLV.getBytes( addResponse.getAddResponseLength() ) );
+
+            // The LdapResult
+            encodeLdapResult( buffer, addResponse.getLdapResult() );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the BindRequest message to a PDU. 
+     * 
+     * BindRequest : 
+     * <pre>
+     * 0x60 LL 
+     *   0x02 LL version         0x80 LL simple 
+     *   0x04 LL name           /   
+     *   authentication.encode() 
+     *                          \ 0x83 LL mechanism [0x04 LL credential]
+     * </pre>
+     * 
+     * @param buffer The buffer where to put the PDU
+     * @return The PDU.
+     */
+    private void encodeBindRequest( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.BindRequestImpl bindRequest ) throws EncoderException
+    {
+        try
+        {
+            // The BindRequest Tag
+            buffer.put( LdapConstants.BIND_REQUEST_TAG );
+            buffer.put( TLV.getBytes( bindRequest.getBindRequestLength() ) );
+
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+
+        // The version (LDAP V3 only)
+        Value.encode( buffer, 3 );
+
+        // The name
+        Value.encode( buffer, DN.getBytes( bindRequest.getName() ) );
+
+        byte[] credentials = bindRequest.getCredentials();
+
+        // The authentication
+        if ( bindRequest.isSimple() )
+        {
+            // Simple authentication
+            try
+            {
+                // The simpleAuthentication Tag
+                buffer.put( ( byte ) LdapConstants.BIND_REQUEST_SIMPLE_TAG );
+
+                if ( credentials != null )
+                {
+                    buffer.put( TLV.getBytes( credentials.length ) );
+
+                    if ( credentials.length != 0 )
+                    {
+                        buffer.put( credentials );
+                    }
+                }
+                else
+                {
+                    buffer.put( ( byte ) 0 );
+                }
+            }
+            catch ( BufferOverflowException boe )
+            {
+                String msg = I18n.err( I18n.ERR_04005 );
+                throw new EncoderException( msg );
+            }
+        }
+        else
+        {
+            // SASL Bind
+            try
+            {
+                // The saslAuthentication Tag
+                buffer.put( ( byte ) LdapConstants.BIND_REQUEST_SASL_TAG );
+
+                byte[] mechanismBytes = Strings.getBytesUtf8(bindRequest.getSaslMechanism());
+
+                buffer.put( TLV
+                    .getBytes( bindRequest.getSaslMechanismLength() + bindRequest.getSaslCredentialsLength() ) );
+
+                Value.encode( buffer, mechanismBytes );
+
+                if ( credentials != null )
+                {
+                    Value.encode( buffer, credentials );
+                }
+            }
+            catch ( BufferOverflowException boe )
+            {
+                String msg = I18n.err( I18n.ERR_04005 );
+                throw new EncoderException( msg );
+            }
+        }
+    }
+
+
+    /**
+     * Encode the BindResponse message to a PDU.
+     * 
+     * BindResponse :
+     * <pre>
+     * LdapResult.encode 
+     * [0x87 LL serverSaslCreds]
+     * </pre>
+     * 
+     * @param buffer The buffer where to put the PDU
+     * @return The PDU.
+     */
+    private void encodeBindResponse( ByteBuffer bb, org.apache.directory.shared.ldap.codec.message.BindResponseImpl bindResponse ) throws EncoderException
+    {
+        try
+        {
+            // The BindResponse Tag
+            bb.put( LdapConstants.BIND_RESPONSE_TAG );
+            bb.put( TLV.getBytes( bindResponse.getBindResponseLength() ) );
+
+            // The LdapResult
+            encodeLdapResult( bb, bindResponse.getLdapResult() );
+
+            // The serverSaslCredential, if any
+            byte[] serverSaslCreds = bindResponse.getServerSaslCreds();
+
+            if ( serverSaslCreds != null )
+            {
+                bb.put( ( byte ) LdapConstants.SERVER_SASL_CREDENTIAL_TAG );
+
+                bb.put( TLV.getBytes( serverSaslCreds.length ) );
+
+                if ( serverSaslCreds.length != 0 )
+                {
+                    bb.put( serverSaslCreds );
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the CompareRequest message to a PDU. 
+     * 
+     * CompareRequest : 
+     *   0x6E LL 
+     *     0x04 LL entry 
+     *     0x30 LL attributeValueAssertion 
+     *       0x04 LL attributeDesc 
+     *       0x04 LL assertionValue
+     * 
+     * @param buffer The buffer where to put the PDU
+     */
+    private void encodeCompareRequest( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.CompareRequestImpl compareRequest ) throws EncoderException
+    {
+        try
+        {
+            // The CompareRequest Tag
+            buffer.put( LdapConstants.COMPARE_REQUEST_TAG );
+            buffer.put( TLV.getBytes( compareRequest.getCompareRequestLength() ) );
+
+            // The entry
+            Value.encode( buffer, DN.getBytes( compareRequest.getName() ) );
+
+            // The attributeValueAssertion sequence Tag
+            buffer.put( UniversalTag.SEQUENCE.getValue() );
+            buffer.put( TLV.getBytes( compareRequest.getAvaLength() ) );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+
+        // The attributeDesc
+        Value.encode( buffer, compareRequest.getAttrIdBytes() );
+
+        // The assertionValue
+        Value.encode( buffer, ( byte[] ) compareRequest.getAttrValBytes() );
+    }
+
+
+    /**
+     * Encode the CompareResponse message to a PDU.
+     * 
+     * @param buffer The buffer where to put the PDU
+     */
+    private void encodeCompareResponse( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.CompareResponseImpl compareResponse )
+        throws EncoderException
+    {
+        try
+        {
+            // The CompareResponse Tag
+            buffer.put( LdapConstants.COMPARE_RESPONSE_TAG );
+            buffer.put( TLV.getBytes( compareResponse.getCompareResponseLength() ) );
+
+            // The LdapResult
+            encodeLdapResult( buffer, compareResponse.getLdapResult() );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the DelRequest message to a PDU. 
+     * 
+     * DelRequest : 
+     * 0x4A LL entry
+     * 
+     * @param buffer The buffer where to put the PDU
+     */
+    private void encodeDeleteRequest( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl deleteRequest ) throws EncoderException
+    {
+        try
+        {
+            // The DelRequest Tag
+            buffer.put( LdapConstants.DEL_REQUEST_TAG );
+
+            // The entry
+            buffer.put( TLV.getBytes( DN.getNbBytes( deleteRequest.getName() ) ) );
+            buffer.put( DN.getBytes( deleteRequest.getName() ) );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the DelResponse message to a PDU.
+     * 
+     * @param buffer The buffer where to put the PDU
+     */
+    private void encodeDeleteResponse( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.DeleteResponseImpl deleteResponse ) throws EncoderException
+    {
+        try
+        {
+            // The DelResponse Tag
+            buffer.put( LdapConstants.DEL_RESPONSE_TAG );
+            buffer.put( TLV.getBytes( deleteResponse.getDeleteResponseLength() ) );
+
+            // The LdapResult
+            encodeLdapResult( buffer, deleteResponse.getLdapResult() );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the ExtendedRequest message to a PDU. 
+     * 
+     * ExtendedRequest :
+     * 
+     * 0x80 LL resquest name
+     * [0x81 LL request value]
+     * 
+     * @param buffer The buffer where to put the PDU
+     * @return The PDU.
+     */
+    private void encodeExtendedRequest( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.ExtendedRequestImpl extendedRequest )
+        throws EncoderException
+    {
+        try
+        {
+            // The BindResponse Tag
+            buffer.put( LdapConstants.EXTENDED_REQUEST_TAG );
+            buffer.put( TLV.getBytes( extendedRequest.getExtendedRequestLength() ) );
+
+            // The requestName, if any
+            if ( extendedRequest.getRequestNameBytes() == null )
+            {
+                throw new EncoderException( I18n.err( I18n.ERR_04043 ) );
+            }
+
+            buffer.put( ( byte ) LdapConstants.EXTENDED_REQUEST_NAME_TAG );
+            buffer.put( TLV.getBytes( extendedRequest.getRequestNameBytes().length ) );
+
+            if ( extendedRequest.getRequestNameBytes().length != 0 )
+            {
+                buffer.put( extendedRequest.getRequestNameBytes() );
+            }
+
+            // The requestValue, if any
+            if ( extendedRequest.getRequestValue() != null )
+            {
+                buffer.put( ( byte ) LdapConstants.EXTENDED_REQUEST_VALUE_TAG );
+
+                buffer.put( TLV.getBytes( extendedRequest.getRequestValue().length ) );
+
+                if ( extendedRequest.getRequestValue().length != 0 )
+                {
+                    buffer.put( extendedRequest.getRequestValue() );
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+
+    }
+
+
+    /**
+     * Encode the ExtendedResponse message to a PDU. 
+     * ExtendedResponse :
+     * LdapResult.encode()
+     * [0x8A LL response name]
+     * [0x8B LL response]
+     * 
+     * @param buffer The buffer where to put the PDU
+     * @return The PDU.
+     */
+    private void encodeExtendedResponse( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl extendedResponse )
+        throws EncoderException
+    {
+        try
+        {
+            // The ExtendedResponse Tag
+            buffer.put( LdapConstants.EXTENDED_RESPONSE_TAG );
+            buffer.put( TLV.getBytes( extendedResponse.getExtendedResponseLength() ) );
+
+            // The LdapResult
+            encodeLdapResult( buffer, extendedResponse.getLdapResult() );
+
+            // The ID, if any
+            byte[] idBytes = extendedResponse.getResponseNameBytes();
+
+            if ( idBytes != null )
+            {
+                buffer.put( ( byte ) LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG );
+                buffer.put( TLV.getBytes( idBytes.length ) );
+
+                if ( idBytes.length != 0 )
+                {
+                    buffer.put( idBytes );
+                }
+            }
+
+            // The encodedValue, if any
+            byte[] encodedValue = extendedResponse.getResponseValue();
+
+            if ( encodedValue != null )
+            {
+                buffer.put( ( byte ) LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG );
+
+                buffer.put( TLV.getBytes( encodedValue.length ) );
+
+                if ( encodedValue.length != 0 )
+                {
+                    buffer.put( encodedValue );
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the IntermediateResponse message to a PDU. 
+     * IntermediateResponse :
+     *   0x79 LL
+     *     [0x80 LL response name]
+     *     [0x81 LL responseValue]
+     * 
+     * @param buffer The buffer where to put the PDU
+     */
+    private void encodeIntermediateResponse( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.IntermediateResponseImpl intermediateResponse )
+        throws EncoderException
+    {
+        try
+        {
+            // The ExtendedResponse Tag
+            buffer.put( LdapConstants.INTERMEDIATE_RESPONSE_TAG );
+            buffer.put( TLV.getBytes( intermediateResponse.getIntermediateResponseLength() ) );
+
+            // The responseName, if any
+            byte[] responseNameBytes = intermediateResponse.getResponseNameBytes();
+
+            if ( ( responseNameBytes != null ) && ( responseNameBytes.length != 0 ) )
+            {
+                buffer.put( ( byte ) LdapConstants.INTERMEDIATE_RESPONSE_NAME_TAG );
+                buffer.put( TLV.getBytes( responseNameBytes.length ) );
+                buffer.put( responseNameBytes );
+            }
+
+            // The encodedValue, if any
+            byte[] encodedValue = intermediateResponse.getResponseValue();
+
+            if ( encodedValue != null )
+            {
+                buffer.put( ( byte ) LdapConstants.INTERMEDIATE_RESPONSE_VALUE_TAG );
+
+                buffer.put( TLV.getBytes( encodedValue.length ) );
+
+                if ( encodedValue.length != 0 )
+                {
+                    buffer.put( encodedValue );
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the ModifyRequest message to a PDU. 
+     * 
+     * ModifyRequest : 
+     * <pre>
+     * 0x66 LL
+     *   0x04 LL object
+     *   0x30 LL modifiations
+     *     0x30 LL modification sequence
+     *       0x0A 0x01 operation
+     *       0x30 LL modification
+     *         0x04 LL type
+     *         0x31 LL vals
+     *           0x04 LL attributeValue
+     *           ... 
+     *           0x04 LL attributeValue
+     *     ... 
+     *     0x30 LL modification sequence
+     *       0x0A 0x01 operation
+     *       0x30 LL modification
+     *         0x04 LL type
+     *         0x31 LL vals
+     *           0x04 LL attributeValue
+     *           ... 
+     *           0x04 LL attributeValue
+     * </pre>
+     * 
+     * @param buffer The buffer where to put the PDU
+     * @return The PDU.
+     */
+    private void encodeModifyRequest( ByteBuffer buffer, ModifyRequestImpl modifyRequest ) throws EncoderException
+    {
+        try
+        {
+            // The AddRequest Tag
+            buffer.put( LdapConstants.MODIFY_REQUEST_TAG );
+            buffer.put( TLV.getBytes( modifyRequest.getModifyRequestLength() ) );
+
+            // The entry
+            Value.encode( buffer, DN.getBytes( modifyRequest.getName() ) );
+
+            // The modifications sequence
+            buffer.put( UniversalTag.SEQUENCE.getValue() );
+            buffer.put( TLV.getBytes( modifyRequest.getChangesLength() ) );
+
+            // The modifications list
+            Collection<Modification> modifications = modifyRequest.getModifications();
+
+            if ( ( modifications != null ) && ( modifications.size() != 0 ) )
+            {
+                int modificationNumber = 0;
+
+                // Compute the modifications length
+                for ( Modification modification : modifications )
+                {
+                    // The modification sequence
+                    buffer.put( UniversalTag.SEQUENCE.getValue() );
+                    int localModificationSequenceLength = modifyRequest.getChangeLength().get( modificationNumber );
+                    buffer.put( TLV.getBytes( localModificationSequenceLength ) );
+
+                    // The operation. The value has to be changed, it's not
+                    // the same value in DirContext and in RFC 2251.
+                    buffer.put( UniversalTag.ENUMERATED.getValue() );
+                    buffer.put( ( byte ) 1 );
+                    buffer.put( ( byte ) modification.getOperation().getValue() );
+
+                    // The modification
+                    buffer.put( UniversalTag.SEQUENCE.getValue() );
+                    int localModificationLength = modifyRequest.getModificationLength().get( modificationNumber );
+                    buffer.put( TLV.getBytes( localModificationLength ) );
+
+                    // The modification type
+                    Value.encode( buffer, modification.getAttribute().getId() );
+
+                    // The values
+                    buffer.put( UniversalTag.SET.getValue() );
+                    int localValuesLength = modifyRequest.getValuesLength().get( modificationNumber );
+                    buffer.put( TLV.getBytes( localValuesLength ) );
+
+                    if ( modification.getAttribute().size() != 0 )
+                    {
+                        for ( org.apache.directory.shared.ldap.entry.Value<?> value : modification.getAttribute() )
+                        {
+                            if ( !value.isBinary() )
+                            {
+                                Value.encode( buffer, value.getString() );
+                            }
+                            else
+                            {
+                                Value.encode( buffer, value.getBytes() );
+                            }
+                        }
+                    }
+
+                    // Go to the next modification number;
+                    modificationNumber++;
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the ModifyResponse message to a PDU.
+     * 
+     * @param buffer The buffer where to put the PDU
+     */
+    private void encodeModifyResponse( ByteBuffer buffer, ModifyResponseImpl modifyResponse ) throws EncoderException
+    {
+        try
+        {
+            // The ModifyResponse Tag
+            buffer.put( LdapConstants.MODIFY_RESPONSE_TAG );
+            buffer.put( TLV.getBytes( modifyResponse.getModifyResponseLength() ) );
+
+            // The LdapResult
+            encodeLdapResult( buffer, modifyResponse.getLdapResult() );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the ModifyDNRequest message to a PDU. 
+     * 
+     * ModifyDNRequest :
+     * <pre>
+     * 0x6C LL
+     *   0x04 LL entry
+     *   0x04 LL newRDN
+     *   0x01 0x01 deleteOldRDN
+     *   [0x80 LL newSuperior]
+     * </pre>
+     * @param buffer The buffer where to put the PDU
+     * @return The PDU.
+     */
+    private void encodeModifyDnRequest( ByteBuffer buffer, ModifyDnRequestImpl modifyDnRequest )
+        throws EncoderException
+    {
+        try
+        {
+            // The ModifyDNRequest Tag
+            buffer.put( LdapConstants.MODIFY_DN_REQUEST_TAG );
+            buffer.put( TLV.getBytes( modifyDnRequest.getModifyDnResponseLength() ) );
+
+            // The entry
+
+            Value.encode( buffer, DN.getBytes( modifyDnRequest.getName() ) );
+
+            // The newRDN
+            Value.encode( buffer, modifyDnRequest.getNewRdn().getName() );
+
+            // The flag deleteOldRdn
+            Value.encode( buffer, modifyDnRequest.getDeleteOldRdn() );
+
+            // The new superior, if any
+            if ( modifyDnRequest.getNewSuperior() != null )
+            {
+                // Encode the reference
+                buffer.put( ( byte ) LdapConstants.MODIFY_DN_REQUEST_NEW_SUPERIOR_TAG );
+
+                int newSuperiorLength = DN.getNbBytes( modifyDnRequest.getNewSuperior() );
+
+                buffer.put( TLV.getBytes( newSuperiorLength ) );
+
+                if ( newSuperiorLength != 0 )
+                {
+                    buffer.put( DN.getBytes( modifyDnRequest.getNewSuperior() ) );
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+
+    }
+
+
+    /**
+     * Encode the ModifyDnResponse message to a PDU.
+     * 
+     * @param buffer The buffer where to put the PDU
+     */
+    private void encodeModifyDnResponse( ByteBuffer buffer, ModifyDnResponseImpl modifyDnResponse )
+        throws EncoderException
+    {
+        try
+        {
+            // The ModifyResponse Tag
+            buffer.put( LdapConstants.MODIFY_DN_RESPONSE_TAG );
+            buffer.put( TLV.getBytes( modifyDnResponse.getModifyDnResponseLength() ) );
+
+            // The LdapResult
+            encodeLdapResult( buffer, modifyDnResponse.getLdapResult() );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the SearchRequest message to a PDU.
+     * 
+     * SearchRequest :
+     * <pre>
+     * 0x63 LL
+     *   0x04 LL baseObject
+     *   0x0A 01 scope
+     *   0x0A 01 derefAliases
+     *   0x02 0N sizeLimit
+     *   0x02 0N timeLimit
+     *   0x01 0x01 typesOnly
+     *   filter.encode()
+     *   0x30 LL attributeDescriptionList
+     *     0x04 LL attributeDescription
+     *     ... 
+     *     0x04 LL attributeDescription
+     * </pre>
+     * @param buffer The buffer where to put the PDU
+     * @return The PDU.
+     */
+    private void encodeSearchRequest( ByteBuffer buffer, SearchRequestImpl searchRequest ) throws EncoderException
+    {
+        try
+        {
+            // The SearchRequest Tag
+            buffer.put( LdapConstants.SEARCH_REQUEST_TAG );
+            buffer.put( TLV.getBytes( searchRequest.getSearchRequestLength() ) );
+
+            // The baseObject
+            Value.encode( buffer, DN.getBytes( searchRequest.getBase() ) );
+
+            // The scope
+            Value.encodeEnumerated( buffer, searchRequest.getScope().getScope() );
+
+            // The derefAliases
+            Value.encodeEnumerated( buffer, searchRequest.getDerefAliases().getValue() );
+
+            // The sizeLimit
+            Value.encode( buffer, searchRequest.getSizeLimit() );
+
+            // The timeLimit
+            Value.encode( buffer, searchRequest.getTimeLimit() );
+
+            // The typesOnly
+            Value.encode( buffer, searchRequest.getTypesOnly() );
+
+            // The filter
+            searchRequest.getCurrentFilter().encode( buffer );
+
+            // The attributeDescriptionList
+            buffer.put( UniversalTag.SEQUENCE.getValue() );
+            buffer.put( TLV.getBytes( searchRequest.getAttributeDescriptionListLength() ) );
+
+            if ( ( searchRequest.getAttributes() != null ) && ( searchRequest.getAttributes().size() != 0 ) )
+            {
+                // encode each attribute
+                for ( String attribute : searchRequest.getAttributes() )
+                {
+                    Value.encode( buffer, attribute );
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+
+    }
+
+
+    /**
+     * Encode the SearchResultDone message to a PDU.
+     * 
+     * @param buffer The buffer where to put the PDU
+     */
+    private void encodeSearchResultDone( ByteBuffer buffer, SearchResultDoneImpl searchResultDone )
+        throws EncoderException
+    {
+        try
+        {
+            // The searchResultDone Tag
+            buffer.put( LdapConstants.SEARCH_RESULT_DONE_TAG );
+            buffer.put( TLV.getBytes( searchResultDone.getSearchResultDoneLength() ) );
+
+            // The LdapResult
+            encodeLdapResult( buffer, searchResultDone.getLdapResult() );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the SearchResultEntry message to a PDU.
+     * 
+     * SearchResultEntry :
+     * <pre>
+     * 0x64 LL
+     *   0x04 LL objectName
+     *   0x30 LL attributes
+     *     0x30 LL partialAttributeList
+     *       0x04 LL type
+     *       0x31 LL vals
+     *         0x04 LL attributeValue
+     *         ... 
+     *         0x04 LL attributeValue
+     *     ... 
+     *     0x30 LL partialAttributeList
+     *       0x04 LL type
+     *       0x31 LL vals
+     *         0x04 LL attributeValue
+     *         ... 
+     *         0x04 LL attributeValue 
+     * </pre>
+     * @param buffer The buffer where to put the PDU
+     * @return The PDU.
+     */
+    private void encodeSearchResultEntry( ByteBuffer buffer, SearchResultEntryImpl searchResultEntry )
+        throws EncoderException
+    {
+        try
+        {
+            // The SearchResultEntry Tag
+            buffer.put( LdapConstants.SEARCH_RESULT_ENTRY_TAG );
+            buffer.put( TLV.getBytes( searchResultEntry.getSearchResultEntryLength() ) );
+
+            // The objectName
+            Value.encode( buffer, searchResultEntry.getObjectNameBytes() );
+
+            // The attributes sequence
+            buffer.put( UniversalTag.SEQUENCE.getValue() );
+            buffer.put( TLV.getBytes( searchResultEntry.getAttributesLength() ) );
+
+            // The partial attribute list
+            Entry entry = searchResultEntry.getEntry();
+
+            if ( ( entry != null ) && ( entry.size() != 0 ) )
+            {
+                int attributeNumber = 0;
+
+                // Compute the attributes length
+                for ( EntryAttribute attribute : entry )
+                {
+                    // The partial attribute list sequence
+                    buffer.put( UniversalTag.SEQUENCE.getValue() );
+                    int localAttributeLength = searchResultEntry.getAttributeLength().get( attributeNumber );
+                    buffer.put( TLV.getBytes( localAttributeLength ) );
+
+                    // The attribute type
+                    Value.encode( buffer, Asn1StringUtils.asciiStringToByte( attribute.getUpId() ) );
+
+                    // The values
+                    buffer.put( UniversalTag.SET.getValue() );
+                    int localValuesLength = searchResultEntry.getValsLength().get( attributeNumber );
+                    buffer.put( TLV.getBytes( localValuesLength ) );
+
+                    if ( attribute.size() > 0 )
+                    {
+                        for ( org.apache.directory.shared.ldap.entry.Value<?> value : attribute )
+                        {
+                            if ( !value.isBinary() )
+                            {
+                                Value.encode( buffer, value.getString() );
+                            }
+                            else
+                            {
+                                Value.encode( buffer, value.getBytes() );
+                            }
+                        }
+                    }
+
+                    // Go to the next attribute number;
+                    attributeNumber++;
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Encode the Unbind protocolOp part
+     */
+    private void encodeUnbindRequest( ByteBuffer buffer ) throws EncoderException
+    {
+        try
+        {
+            // The tag
+            buffer.put( LdapConstants.UNBIND_REQUEST_TAG );
+
+            // The length is always null.
+            buffer.put( ( byte ) 0 );
+        }
+        catch ( BufferOverflowException boe )
+        {
+            String msg = I18n.err( I18n.ERR_04005 );
+            throw new EncoderException( msg );
+        }
+    }
+
+
+    /**
+     * Encode the SearchResultReference message to a PDU.
+     * 
+     * SearchResultReference :
+     * <pre>
+     * 0x73 LL
+     *   0x04 LL reference
+     *   [0x04 LL reference]*
+     * </pre>
+     * @param buffer The buffer where to put the PDU
+     * @return The PDU.
+     */
+    private void encodeSearchResultReference( ByteBuffer buffer, SearchResultReferenceImpl searchResultReference )
+        throws EncoderException
+    {
+        try
+        {
+            // The SearchResultReference Tag
+            buffer.put( LdapConstants.SEARCH_RESULT_REFERENCE_TAG );
+            buffer.put( TLV.getBytes( searchResultReference.getSearchResultReferenceLength() ) );
+
+            // The referrals, if any
+            Referral referral = searchResultReference.getReferral();
+
+            if ( referral != null )
+            {
+                // Each referral
+                for ( byte[] ldapUrlBytes : referral.getLdapUrlsBytes() )
+                {
+                    // Encode the current referral
+                    Value.encode( buffer, ldapUrlBytes );
+                }
+            }
+        }
+        catch ( BufferOverflowException boe )
+        {
+            throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
+        }
+    }
+
+
+    /**
+     * Compute the protocolOp length 
+     */
+    private int computeProtocolOpLength( Message message )
+    {
+        switch ( message.getType() )
+        {
+            case ABANDON_REQUEST:
+                return computeAbandonRequestLength( (AbandonRequestImpl) message );
+
+            case ADD_REQUEST:
+                return computeAddRequestLength( (org.apache.directory.shared.ldap.codec.message.AddRequestImpl) message );
+
+            case ADD_RESPONSE:
+                return computeAddResponseLength( (org.apache.directory.shared.ldap.codec.message.AddResponseImpl) message );
+
+            case BIND_REQUEST:
+                return computeBindRequestLength( (org.apache.directory.shared.ldap.codec.message.BindRequestImpl) message );
+
+            case BIND_RESPONSE:
+                return computeBindResponseLength( (org.apache.directory.shared.ldap.codec.message.BindResponseImpl) message );
+
+            case COMPARE_REQUEST:
+                return computeCompareRequestLength( (org.apache.directory.shared.ldap.codec.message.CompareRequestImpl) message );
+
+            case COMPARE_RESPONSE:
+                return computeCompareResponseLength( (org.apache.directory.shared.ldap.codec.message.CompareResponseImpl) message );
+
+            case DEL_REQUEST:
+                return computeDeleteRequestLength( (org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl) message );
+
+            case DEL_RESPONSE:
+                return computeDeleteResponseLength( (org.apache.directory.shared.ldap.codec.message.DeleteResponseImpl) message );
+
+            case EXTENDED_REQUEST:
+                return computeExtendedRequestLength( (org.apache.directory.shared.ldap.codec.message.ExtendedRequestImpl) message );
+
+            case EXTENDED_RESPONSE:
+                return computeExtendedResponseLength( (org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl) message );
+
+            case INTERMEDIATE_RESPONSE:
+                return computeIntermediateResponseLength( (org.apache.directory.shared.ldap.codec.message.IntermediateResponseImpl) message );
+
+            case MODIFY_REQUEST:
+                return computeModifyRequestLength( ( ModifyRequestImpl ) message );
+
+            case MODIFY_RESPONSE:
+                return computeModifyResponseLength( ( ModifyResponseImpl ) message );
+
+            case MODIFYDN_REQUEST:
+                return computeModifyDnRequestLength( ( ModifyDnRequestImpl ) message );
+
+            case MODIFYDN_RESPONSE:
+                return computeModifyDnResponseLength( ( ModifyDnResponseImpl ) message );
+
+            case SEARCH_REQUEST:
+                return computeSearchRequestLength( ( SearchRequestImpl ) message );
+
+            case SEARCH_RESULT_DONE:
+                return computeSearchResultDoneLength( ( SearchResultDoneImpl ) message );
+
+            case SEARCH_RESULT_ENTRY:
+                return computeSearchResultEntryLength( ( SearchResultEntryImpl ) message );
+
+            case SEARCH_RESULT_REFERENCE:
+                return computeSearchResultReferenceLength( ( SearchResultReferenceImpl ) message );
+
+            case UNBIND_REQUEST:
+                return computeUnbindRequestLength( );
+
+            default:
+                return 0;
+        }
+    }
+
+
+    private void encodeProtocolOp( ByteBuffer bb, Message message ) throws EncoderException
+    {
+        switch ( message.getType() )
+        {
+            case ABANDON_REQUEST:
+                encodeAbandonRequest( bb, (AbandonRequestImpl) message );
+                break;
+
+            case ADD_REQUEST:
+                encodeAddRequest( bb, (org.apache.directory.shared.ldap.codec.message.AddRequestImpl) message );
+                break;
+
+            case ADD_RESPONSE:
+                encodeAddResponse( bb, (org.apache.directory.shared.ldap.codec.message.AddResponseImpl) message );
+                break;
+
+            case BIND_REQUEST:
+                encodeBindRequest( bb, (org.apache.directory.shared.ldap.codec.message.BindRequestImpl) message );
+                break;
+
+            case BIND_RESPONSE:
+                encodeBindResponse( bb, (org.apache.directory.shared.ldap.codec.message.BindResponseImpl) message );
+                break;
+
+            case COMPARE_REQUEST:
+                encodeCompareRequest( bb, (org.apache.directory.shared.ldap.codec.message.CompareRequestImpl) message );
+                break;
+
+            case COMPARE_RESPONSE:
+                encodeCompareResponse( bb, (org.apache.directory.shared.ldap.codec.message.CompareResponseImpl) message );
+                break;
+
+            case DEL_REQUEST:
+                encodeDeleteRequest( bb, (org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl) message );
+                break;
+
+            case DEL_RESPONSE:
+                encodeDeleteResponse( bb, (org.apache.directory.shared.ldap.codec.message.DeleteResponseImpl) message );
+                break;
+
+            case EXTENDED_REQUEST:
+                encodeExtendedRequest( bb, (org.apache.directory.shared.ldap.codec.message.ExtendedRequestImpl) message );
+                break;
+
+            case EXTENDED_RESPONSE:
+                encodeExtendedResponse( bb, (org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl) message );
+                break;
+
+            case INTERMEDIATE_RESPONSE:
+                encodeIntermediateResponse( bb, (org.apache.directory.shared.ldap.codec.message.IntermediateResponseImpl) message );
+                break;
+
+            case MODIFY_REQUEST:
+                encodeModifyRequest( bb, ( ModifyRequestImpl ) message );
+                break;
+
+            case MODIFY_RESPONSE:
+                encodeModifyResponse( bb, ( ModifyResponseImpl ) message );
+                break;
+
+            case MODIFYDN_REQUEST:
+                encodeModifyDnRequest( bb, ( ModifyDnRequestImpl ) message );
+                break;
+
+            case MODIFYDN_RESPONSE:
+                encodeModifyDnResponse( bb, ( ModifyDnResponseImpl ) message );
+                break;
+
+            case SEARCH_REQUEST:
+                encodeSearchRequest( bb, ( SearchRequestImpl ) message );
+                break;
+
+            case SEARCH_RESULT_DONE:
+                encodeSearchResultDone( bb, ( SearchResultDoneImpl ) message );
+                break;
+
+            case SEARCH_RESULT_ENTRY:
+                encodeSearchResultEntry( bb, ( SearchResultEntryImpl ) message );
+                break;
+
+            case SEARCH_RESULT_REFERENCE:
+                encodeSearchResultReference( bb, ( SearchResultReferenceImpl ) message );
+                break;
+
+            case UNBIND_REQUEST:
+                encodeUnbindRequest( bb );
+                break;
+        }
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/LdapResultImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/LdapResultImpl.java
new file mode 100644
index 0000000..cee829c
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/LdapResultImpl.java
@@ -0,0 +1,590 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.LdapResult;
+import org.apache.directory.shared.ldap.message.Referral;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.name.DN;
+
+
+/**
+ * LdapResult implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class LdapResultImpl implements LdapResult
+{
+    static final long serialVersionUID = -1446626887394613213L;
+
+    /** Lowest matched entry Dn - defaults to empty string */
+    private DN matchedDn;
+
+    /** Temporary storage of the byte[] representing the matchedDN */
+    private byte[] matchedDnBytes;
+
+    /** Referral associated with this LdapResult if the errorCode is REFERRAL */
+    private Referral referral;
+
+    /** Decriptive error message - defaults to empty string */
+    private String errorMessage;
+
+    /** Temporary storage for message bytes */
+    private byte[] errorMessageBytes;
+
+    /** Resultant operation error code - defaults to SUCCESS */
+    private ResultCodeEnum resultCode = ResultCodeEnum.SUCCESS;
+
+
+    // ------------------------------------------------------------------------
+    // LdapResult Interface Method Implementations
+    // ------------------------------------------------------------------------
+    /**
+     * Gets the descriptive error message associated with the error code. May be
+     * null for SUCCESS, COMPARETRUE, COMPAREFALSE and REFERRAL operations.
+     * 
+     * @return the descriptive error message.
+     */
+    public String getErrorMessage()
+    {
+        return errorMessage;
+    }
+
+
+    /**
+     * @return The encoded Error message
+     */
+    /*No qualifier*/byte[] getErrorMessageBytes()
+    {
+        return errorMessageBytes;
+    }
+
+
+    /**
+     * Sets the descriptive error message associated with the error code. May be
+     * null for SUCCESS, COMPARETRUE, and COMPAREFALSE operations.
+     * 
+     * @param errorMessage
+     *            the descriptive error message.
+     */
+    public void setErrorMessage( String errorMessage )
+    {
+        this.errorMessage = errorMessage;
+    }
+
+
+    /**
+     * Set the encoded message's bytes
+     * @param errorMessageBytes The encoded bytes
+     */
+    /*No qualifier*/void setErrorMessageBytes( byte[] errorMessageBytes )
+    {
+        this.errorMessageBytes = errorMessageBytes;
+    }
+
+
+    /**
+     * Gets the lowest entry in the directory that was matched. For result codes
+     * of noSuchObject, aliasProblem, invalidDNSyntax and
+     * aliasDereferencingProblem, the matchedDN field is set to the name of the
+     * lowest entry (object or alias) in the directory that was matched. If no
+     * aliases were dereferenced while attempting to locate the entry, this will
+     * be a truncated form of the name provided, or if aliases were
+     * dereferenced, of the resulting name, as defined in section 12.5 of X.511
+     * [8]. The matchedDN field is to be set to a zero length string with all
+     * other result codes.
+     * 
+     * @return the Dn of the lowest matched entry.
+     */
+    public DN getMatchedDn()
+    {
+        return matchedDn;
+    }
+
+
+    /**
+     * @return the encoded MatchedDN
+     */
+    /*No qualifier*/byte[] getMatchedDnBytes()
+    {
+        return matchedDnBytes;
+    }
+
+
+    /**
+     * Sets the lowest entry in the directory that was matched.
+     * 
+     * @see #getMatchedDn()
+     * @param matchedDn the Dn of the lowest matched entry.
+     */
+    public void setMatchedDn( DN matchedDn )
+    {
+        this.matchedDn = matchedDn;
+    }
+
+
+    /**
+     * Sets the encoded value for MatchedDn
+     * 
+     * @param matchedDnBytes The encoded MatchedDN
+     */
+    /*No qualifier*/void setMatchedDnBytes( byte[] matchedDnBytes )
+    {
+        this.matchedDnBytes = matchedDnBytes;
+    }
+
+
+    /**
+     * Gets the result code enumeration associated with the response.
+     * Corresponds to the <b> resultCode </b> field within the LDAPResult ASN.1
+     * structure.
+     * 
+     * @return the result code enum value.
+     */
+    public ResultCodeEnum getResultCode()
+    {
+        return resultCode;
+    }
+
+
+    /**
+     * Sets the result code enumeration associated with the response.
+     * Corresponds to the <b> resultCode </b> field within the LDAPResult ASN.1
+     * structure.
+     * 
+     * @param resultCode
+     *            the result code enum value.
+     */
+    public void setResultCode( ResultCodeEnum resultCode )
+    {
+        this.resultCode = resultCode;
+    }
+
+
+    /**
+     * Gets the Referral associated with this LdapResult if the resultCode
+     * property is set to the REFERRAL ResultCodeEnum.
+     * 
+     * @return the referral on REFERRAL errors, null on all others.
+     */
+    public Referral getReferral()
+    {
+        return referral;
+    }
+
+
+    /**
+     * Gets whether or not this result represents a Referral. For referrals the
+     * error code is set to REFERRAL and the referral property is not null.
+     * 
+     * @return true if this result represents a referral.
+     */
+    public boolean isReferral()
+    {
+        return referral != null;
+    }
+
+
+    /**
+     * Sets the Referral associated with this LdapResult if the resultCode
+     * property is set to the REFERRAL ResultCodeEnum. Setting this property
+     * will result in a true return from isReferral and the resultCode should be
+     * set to REFERRAL.
+     * 
+     * @param referral
+     *            optional referral on REFERRAL errors.
+     */
+    public void setReferral( Referral referral )
+    {
+        this.referral = referral;
+    }
+
+
+    /**
+     * @see Object#hashCode()
+     * @return the instance's hash code 
+     */
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( referral != null )
+        {
+            hash = hash * 17 + referral.hashCode();
+        }
+        hash = hash * 17 + resultCode.hashCode();
+        if ( errorMessage != null )
+        {
+            hash = hash * 17 + errorMessage.hashCode();
+        }
+        if ( matchedDn != null )
+        {
+            hash = hash * 17 + matchedDn.hashCode();
+        }
+
+        return hash;
+    }
+
+
+    /**
+     * @param obj The object to compare with
+     * @return <code>true</code> if both objects are equals
+     */
+    public boolean equals( Object obj )
+    {
+        // quickly return true if this is the obj
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        // return false if object does not implement interface
+        if ( !( obj instanceof LdapResult ) )
+        {
+            return false;
+        }
+
+        // compare all the like elements of the two LdapResult objects
+        LdapResult result = ( LdapResult ) obj;
+
+        if ( referral == null && result.getReferral() != null )
+        {
+            return false;
+        }
+
+        if ( result.getReferral() == null && referral != null )
+        {
+            return false;
+        }
+
+        if ( referral != null && result.getReferral() != null && !referral.equals( result.getReferral() ) )
+        {
+            return false;
+        }
+
+        if ( !resultCode.equals( result.getResultCode() ) )
+        {
+            return false;
+        }
+
+        // Handle Error Messages where "" is considered equivalent to null
+        String errMsg0 = errorMessage;
+        String errMsg1 = result.getErrorMessage();
+
+        if ( errMsg0 == null )
+        {
+            errMsg0 = "";
+        }
+
+        if ( errMsg1 == null )
+        {
+            errMsg1 = "";
+        }
+
+        if ( !errMsg0.equals( errMsg1 ) )
+        {
+            return false;
+        }
+
+        if ( matchedDn != null )
+        {
+            if ( !matchedDn.equals( result.getMatchedDn() ) )
+            {
+                return false;
+            }
+        }
+        else if ( result.getMatchedDn() != null ) // one is null other is not
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Get a String representation of a LdapResult
+     * 
+     * @return A LdapResult String
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "        Ldap Result\n" );
+        sb.append( "            Result code : (" ).append( resultCode ).append( ')' );
+
+        switch ( resultCode )
+        {
+
+            case SUCCESS:
+                sb.append( " success\n" );
+                break;
+
+            case OPERATIONS_ERROR:
+                sb.append( " operationsError\n" );
+                break;
+
+            case PROTOCOL_ERROR:
+                sb.append( " protocolError\n" );
+                break;
+
+            case TIME_LIMIT_EXCEEDED:
+                sb.append( " timeLimitExceeded\n" );
+                break;
+
+            case SIZE_LIMIT_EXCEEDED:
+                sb.append( " sizeLimitExceeded\n" );
+                break;
+
+            case COMPARE_FALSE:
+                sb.append( " compareFalse\n" );
+                break;
+
+            case COMPARE_TRUE:
+                sb.append( " compareTrue\n" );
+                break;
+
+            case AUTH_METHOD_NOT_SUPPORTED:
+                sb.append( " authMethodNotSupported\n" );
+                break;
+
+            case STRONG_AUTH_REQUIRED:
+                sb.append( " strongAuthRequired\n" );
+                break;
+
+            case REFERRAL:
+                sb.append( " referral -- new\n" );
+                break;
+
+            case ADMIN_LIMIT_EXCEEDED:
+                sb.append( " adminLimitExceeded -- new\n" );
+                break;
+
+            case UNAVAILABLE_CRITICAL_EXTENSION:
+                sb.append( " unavailableCriticalExtension -- new\n" );
+                break;
+
+            case CONFIDENTIALITY_REQUIRED:
+                sb.append( " confidentialityRequired -- new\n" );
+                break;
+
+            case SASL_BIND_IN_PROGRESS:
+                sb.append( " saslBindInProgress -- new\n" );
+                break;
+
+            case NO_SUCH_ATTRIBUTE:
+                sb.append( " noSuchAttribute\n" );
+                break;
+
+            case UNDEFINED_ATTRIBUTE_TYPE:
+                sb.append( " undefinedAttributeType\n" );
+                break;
+
+            case INAPPROPRIATE_MATCHING:
+                sb.append( " inappropriateMatching\n" );
+                break;
+
+            case CONSTRAINT_VIOLATION:
+                sb.append( " constraintViolation\n" );
+                break;
+
+            case ATTRIBUTE_OR_VALUE_EXISTS:
+                sb.append( " attributeOrValueExists\n" );
+                break;
+
+            case INVALID_ATTRIBUTE_SYNTAX:
+                sb.append( " invalidAttributeSyntax\n" );
+                break;
+
+            case NO_SUCH_OBJECT:
+                sb.append( " noSuchObject\n" );
+                break;
+
+            case ALIAS_PROBLEM:
+                sb.append( " aliasProblem\n" );
+                break;
+
+            case INVALID_DN_SYNTAX:
+                sb.append( " invalidDNSyntax\n" );
+                break;
+
+            case ALIAS_DEREFERENCING_PROBLEM:
+                sb.append( " aliasDereferencingProblem\n" );
+                break;
+
+            case INAPPROPRIATE_AUTHENTICATION:
+                sb.append( " inappropriateAuthentication\n" );
+                break;
+
+            case INVALID_CREDENTIALS:
+                sb.append( " invalidCredentials\n" );
+                break;
+
+            case INSUFFICIENT_ACCESS_RIGHTS:
+                sb.append( " insufficientAccessRights\n" );
+                break;
+
+            case BUSY:
+                sb.append( " busy\n" );
+                break;
+
+            case UNAVAILABLE:
+                sb.append( " unavailable\n" );
+                break;
+
+            case UNWILLING_TO_PERFORM:
+                sb.append( " unwillingToPerform\n" );
+                break;
+
+            case LOOP_DETECT:
+                sb.append( " loopDetect\n" );
+                break;
+
+            case NAMING_VIOLATION:
+                sb.append( " namingViolation\n" );
+                break;
+
+            case OBJECT_CLASS_VIOLATION:
+                sb.append( " objectClassViolation\n" );
+                break;
+
+            case NOT_ALLOWED_ON_NON_LEAF:
+                sb.append( " notAllowedOnNonLeaf\n" );
+                break;
+
+            case NOT_ALLOWED_ON_RDN:
+                sb.append( " notAllowedOnRDN\n" );
+                break;
+
+            case ENTRY_ALREADY_EXISTS:
+                sb.append( " entryAlreadyExists\n" );
+                break;
+
+            case OBJECT_CLASS_MODS_PROHIBITED:
+                sb.append( " objectClassModsProhibited\n" );
+                break;
+
+            case AFFECTS_MULTIPLE_DSAS:
+                sb.append( " affectsMultipleDSAs -- new\n" );
+                break;
+
+            case OTHER:
+                sb.append( " other\n" );
+                break;
+
+            default:
+                switch ( resultCode.getResultCode() )
+                {
+                    case 9:
+                        sb.append( " -- 9 reserved --\n" );
+                        break;
+
+                    case 22:
+                    case 23:
+                    case 24:
+                    case 25:
+                    case 26:
+                    case 27:
+                    case 28:
+                    case 29:
+                    case 30:
+                    case 31:
+                        sb.append( " -- 22-31 unused --\n" );
+                        break;
+
+                    case 35:
+                        sb.append( " -- 35 reserved for undefined isLeaf --\n" );
+                        break;
+
+                    case 37:
+                    case 38:
+                    case 39:
+                    case 40:
+                    case 41:
+                    case 42:
+                    case 43:
+                    case 44:
+                    case 45:
+                    case 46:
+                    case 47:
+                        sb.append( " -- 37-47 unused --\n" );
+                        break;
+
+                    case 55:
+                    case 56:
+                    case 57:
+                    case 58:
+                    case 59:
+                    case 60:
+                    case 61:
+                    case 62:
+                    case 63:
+                        sb.append( " -- 55-63 unused --\n" );
+                        break;
+
+                    case 70:
+                        sb.append( " -- 70 reserved for CLDAP --\n" );
+                        break;
+
+                    case 72:
+                    case 73:
+                    case 74:
+                    case 75:
+                    case 76:
+                    case 77:
+                    case 78:
+                    case 79:
+                        sb.append( " -- 72-79 unused --\n" );
+                        break;
+
+                    case 81:
+                    case 82:
+                    case 83:
+                    case 84:
+                    case 85:
+                    case 86:
+                    case 87:
+                    case 88:
+                    case 89:
+                    case 90:
+                        sb.append( " -- 81-90 reserved for APIs --" );
+                        break;
+
+                    default:
+                        sb.append( "Unknown error code : " ).append( resultCode );
+                        break;
+                }
+        }
+
+        sb.append( "            Matched DN : '" ).append( matchedDn ).append( "'\n" );
+        sb.append( "            Error message : '" ).append( errorMessage ).append( "'\n" );
+
+        if ( referral != null )
+        {
+            sb.append( "            Referrals :\n" );
+
+            sb.append( "                Referral :" ).append( referral.toString() ).append( '\n' );
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyDnRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyDnRequestImpl.java
new file mode 100644
index 0000000..45b4d68
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyDnRequestImpl.java
@@ -0,0 +1,385 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.*;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.ldap.name.RDN;
+
+
+/**
+ * ModifyDNRequest implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class ModifyDnRequestImpl extends AbstractAbandonableRequest implements ModifyDnRequest
+{
+    static final long serialVersionUID = 1233507339633051696L;
+
+    /** PDU's modify Dn candidate <b>entry</b> distinguished name property */
+    private DN name;
+
+    /** PDU's <b>newrdn</b> relative distinguished name property */
+    private RDN newRdn;
+
+    /** PDU's <b>newSuperior</b> distinguished name property */
+    private DN newSuperior;
+
+    /** PDU's <b>deleteOldRdn</b> flag */
+    private boolean deleteOldRdn = false;
+
+    /** The associated response */
+    private ModifyDnResponse response;
+
+    /** The modify DN request length */
+    private int modifyDnRequestLength;
+
+
+    // -----------------------------------------------------------------------
+    // Constructors
+    // -----------------------------------------------------------------------
+    /**
+     * Creates a ModifyDnRequest implementing object used to perform a
+     * dn change on an entry potentially resulting in an entry move.
+     */
+    public ModifyDnRequestImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates a Lockable ModifyDnRequest implementing object used to perform a
+     * dn change on an entry potentially resulting in an entry move.
+     * 
+     * @param id the sequence id of this message
+     */
+    public ModifyDnRequestImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // ModifyDnRequest Interface Method Implementations
+    // -----------------------------------------------------------------------
+
+    /**
+     * Gets the flag which determines if the old Rdn attribute is to be removed
+     * from the entry when the new Rdn is used in its stead. This property
+     * corresponds to the <b>deleteoldrdn</b>
+     * 
+     * @return true if the old rdn is to be deleted, false if it is not
+     */
+    public boolean getDeleteOldRdn()
+    {
+        return deleteOldRdn;
+    }
+
+
+    /**
+     * Sets the flag which determines if the old Rdn attribute is to be removed
+     * from the entry when the new Rdn is used in its stead. This property
+     * corresponds to the <b>deleteoldrdn</b>
+     * 
+     * @param deleteOldRdn true if the old rdn is to be deleted, false if it is not
+     */
+    public void setDeleteOldRdn( boolean deleteOldRdn )
+    {
+        this.deleteOldRdn = deleteOldRdn;
+    }
+
+
+    /**
+     * Gets whether or not this request is a DN change resulting in a move
+     * operation. Setting the newSuperior property to a non-null name, toggles
+     * this flag.
+     * 
+     * @return true if the newSuperior property is <b>NOT</b> null, false
+     *         otherwise.
+     */
+    public boolean isMove()
+    {
+        return newSuperior != null;
+    }
+
+
+    /**
+     * Gets the entry's distinguished name representing the <b>entry</b> PDU
+     * field.
+     * 
+     * @return the distinguished name of the entry.
+     */
+    public DN getName()
+    {
+        return name;
+    }
+
+
+    /**
+     * Sets the entry's distinguished name representing the <b>entry</b> PDU
+     * field.
+     * 
+     * @param name
+     *            the distinguished name of the entry.
+     */
+    public void setName( DN name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * Gets the new relative distinguished name for the entry which represents
+     * the PDU's <b>newrdn</b> field.
+     * 
+     * @return the relative dn with one component
+     */
+    public RDN getNewRdn()
+    {
+        return newRdn;
+    }
+
+
+    /**
+     * Sets the new relative distinguished name for the entry which represents
+     * the PDU's <b>newrdn</b> field.
+     * 
+     * @param newRdn the relative dn with one component
+     */
+    public void setNewRdn( RDN newRdn )
+    {
+        this.newRdn = newRdn;
+    }
+
+
+    /**
+     * Gets the optional distinguished name of the new superior entry where the
+     * candidate entry is to be moved. This property corresponds to the PDU's
+     * <b>newSuperior</b> field. May be null representing a simple Rdn change
+     * rather than a move operation.
+     * 
+     * @return the dn of the superior entry the candidate entry is moved under.
+     */
+    public DN getNewSuperior()
+    {
+        return newSuperior;
+    }
+
+
+    /**
+     * Sets the optional distinguished name of the new superior entry where the
+     * candidate entry is to be moved. This property corresponds to the PDU's
+     * <b>newSuperior</b> field. May be null representing a simple Rdn change
+     * rather than a move operation. Setting this property to a non-null value
+     * toggles the move flag obtained via the <code>isMove</code> method.
+     * 
+     * @param newSuperior the dn of the superior entry the candidate entry for DN
+     *            modification is moved under.
+     */
+    public void setNewSuperior( DN newSuperior )
+    {
+        this.newSuperior = newSuperior;
+    }
+
+
+    // ------------------------------------------------------------------------
+    // SingleReplyRequest Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the protocol response message type for this request which produces
+     * at least one response.
+     * 
+     * @return the message type of the response.
+     */
+    public MessageTypeEnum getResponseType()
+    {
+        return RESP_TYPE;
+    }
+
+
+    /**
+     * The result containing response for this request.
+     * 
+     * @return the result containing response for this request
+     */
+    public ResultResponse getResultResponse()
+    {
+        if ( response == null )
+        {
+            response = new ModifyDnResponseImpl( getMessageId() );
+        }
+
+        return response;
+    }
+
+
+    /**
+     * @return The encoded ModifyDnRequest's length
+     */
+    /* No Qualifier*/void setModifyDnRequestLength( int modifyDnRequestLength )
+    {
+        this.modifyDnRequestLength = modifyDnRequestLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the ModifyDnRequest
+     * @param modifyDnRequestLength The encoded length
+     */
+    /* No Qualifier*/int getModifyDnResponseLength()
+    {
+        return modifyDnRequestLength;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( name != null )
+        {
+            hash = hash * 17 + name.hashCode();
+        }
+        hash = hash * 17 + ( deleteOldRdn ? 0 : 1 );
+
+        if ( newRdn != null )
+        {
+            hash = hash * 17 + newRdn.hashCode();
+        }
+        if ( newSuperior != null )
+        {
+            hash = hash * 17 + newSuperior.hashCode();
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks to see of an object equals this ModifyDnRequest stub. The equality
+     * presumes all ModifyDnRequest specific properties are the same.
+     * 
+     * @param obj the object to compare with this stub
+     * @return true if the obj is equal to this stub, false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        ModifyDnRequest req = ( ModifyDnRequest ) obj;
+
+        if ( name != null && req.getName() == null )
+        {
+            return false;
+        }
+
+        if ( name == null && req.getName() != null )
+        {
+            return false;
+        }
+
+        if ( name != null && req.getName() != null && !name.equals( req.getName() ) )
+        {
+            return false;
+        }
+
+        if ( deleteOldRdn != req.getDeleteOldRdn() )
+        {
+            return false;
+        }
+
+        if ( newRdn != null && req.getNewRdn() == null )
+        {
+            return false;
+        }
+
+        if ( newRdn == null && req.getNewRdn() != null )
+        {
+            return false;
+        }
+
+        if ( newRdn != null && req.getNewRdn() != null && !newRdn.equals( req.getNewRdn() ) )
+        {
+            return false;
+        }
+
+        if ( newSuperior != null && req.getNewSuperior() == null )
+        {
+            return false;
+        }
+
+        if ( newSuperior == null && req.getNewSuperior() != null )
+        {
+            return false;
+        }
+
+        if ( newSuperior != null && req.getNewSuperior() != null && !newSuperior.equals( req.getNewSuperior() ) )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Get a String representation of a ModifyDNRequest
+     * 
+     * @return A ModifyDNRequest String
+     */
+    public String toString()
+    {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append( "    ModifyDN Response\n" );
+        sb.append( "        Entry : '" ).append( name ).append( "'\n" );
+        if ( newRdn != null )
+        {
+            sb.append( "        New RDN : '" ).append( newRdn.toString() ).append( "'\n" );
+        }
+        sb.append( "        Delete old RDN : " ).append( deleteOldRdn ).append( "\n" );
+
+        if ( newSuperior != null )
+        {
+            sb.append( "        New superior : '" ).append( newSuperior.toString() ).append( "'\n" );
+        }
+
+        // The controls
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyDnResponseImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyDnResponseImpl.java
new file mode 100644
index 0000000..45f18de
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyDnResponseImpl.java
@@ -0,0 +1,97 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.AbstractResultResponse;
+import org.apache.directory.shared.ldap.message.ModifyDnResponse;
+
+/**
+ * ModifyDnResponse implementation
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ */
+class ModifyDnResponseImpl extends AbstractResultResponse implements ModifyDnResponse
+{
+    /** The encoded modifyDnResponse length */
+    private int modifyDnResponseLength;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    static final long serialVersionUID = 996870775343263543L;
+
+
+    /**
+     * Creates a ModifyDnResponse as a reply to an ModifyDnRequest.
+     */
+    public ModifyDnResponseImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates a ModifyDnResponse as a reply to an ModifyDnRequest.
+     * 
+     * @param id the sequence if of this response
+     */
+    public ModifyDnResponseImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    /**
+     * @return The encoded ModifyDnResponse's length
+     */
+    /* No Qualifier*/void setModifyDnResponseLength( int modifyDnResponseLength )
+    {
+        this.modifyDnResponseLength = modifyDnResponseLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the ModifyDnResponse
+     * @param modifyDnResponseLength The encoded length
+     */
+    /* No Qualifier*/int getModifyDnResponseLength()
+    {
+        return modifyDnResponseLength;
+    }
+
+
+    /**
+     * Get a String representation of a ModifyDNResponse
+     * 
+     * @return A ModifyDNResponse String
+     */
+    public String toString()
+    {
+
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Modify DN Response\n" );
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyRequestImpl.java
new file mode 100644
index 0000000..68fabfa
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyRequestImpl.java
@@ -0,0 +1,622 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.directory.shared.ldap.entry.DefaultEntryAttribute;
+import org.apache.directory.shared.ldap.entry.DefaultModification;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.Modification;
+import org.apache.directory.shared.ldap.entry.ModificationOperation;
+import org.apache.directory.shared.ldap.message.*;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.util.Strings;
+
+
+/**
+ * Lockable ModifyRequest implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class ModifyRequestImpl extends AbstractAbandonableRequest implements ModifyRequest
+{
+    static final long serialVersionUID = -505803669028990304L;
+
+    /** Dn of the entry to modify or PDU's <b>object</b> field */
+    private DN name;
+
+    /** Sequence of modifications or PDU's <b>modification</b> seqence field */
+    private List<Modification> mods = new ArrayList<Modification>();
+
+    /** The associated response */
+    private ModifyResponse response;
+
+    /** The current attribute being decoded */
+    private EntryAttribute currentAttribute;
+
+    /** A local storage for the operation */
+    private ModificationOperation currentOperation;
+
+    /** The modify request length */
+    private int modifyRequestLength;
+
+    /** The changes length */
+    private int changesLength;
+
+    /** The list of all change lengths */
+    private List<Integer> changeLength = new LinkedList<Integer>();
+
+    /** The list of all the modification lengths */
+    private List<Integer> modificationLength = new LinkedList<Integer>();
+
+    /** The list of all the value lengths */
+    private List<Integer> valuesLength = new LinkedList<Integer>();
+
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Creates a ModifyRequest implementing object used to modify the
+     * attributes of an entry.
+     */
+    public ModifyRequestImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates a ModifyRequest implementing object used to modify the
+     * attributes of an entry.
+     * 
+     * @param id the sequential message identifier
+     */
+    public ModifyRequestImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    // ------------------------------------------------------------------------
+    // ModifyRequest Interface Method Implementations
+    // ------------------------------------------------------------------------
+    /**
+     * Gets an immutable Collection of modification items representing the
+     * atomic changes to perform on the candidate entry to modify.
+     * 
+     * @return an immutable Collection of Modification instances.
+     */
+    public Collection<Modification> getModifications()
+    {
+        return Collections.unmodifiableCollection( mods );
+    }
+
+
+    /**
+     * Gets the distinguished name of the entry to be modified by this request.
+     * This property represents the PDU's <b>object</b> field.
+     * 
+     * @return the DN of the modified entry.
+     */
+    public DN getName()
+    {
+        return name;
+    }
+
+
+    /**
+     * Sets the distinguished name of the entry to be modified by this request.
+     * This property represents the PDU's <b>object</b> field.
+     * 
+     * @param name the DN of the modified entry.
+     */
+    public void setName( DN name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * Adds a Modification to the set of modifications composing this modify
+     * request.
+     * 
+     * @param mod a Modification to add
+     */
+    public void addModification( Modification mod )
+    {
+        mods.add( mod );
+    }
+
+
+    private void addModification( ModificationOperation modOp, String attributeName, byte[]... attributeValue )
+    {
+        EntryAttribute attr = new DefaultEntryAttribute( attributeName, attributeValue );
+        addModification( attr, modOp );
+    }
+
+
+    private void addModification( ModificationOperation modOp, String attributeName, String... attributeValue )
+    {
+        EntryAttribute attr = new DefaultEntryAttribute( attributeName, attributeValue );
+        addModification( attr, modOp );
+    }
+
+
+    public void addModification( EntryAttribute attr, ModificationOperation modOp )
+    {
+        mods.add( new DefaultModification( modOp, attr ) );
+    }
+
+
+    /**
+     *
+     * marks a given attribute for addition in the target entry with the
+     * given values.
+     *
+     * @param attributeName name of the attribute to be added
+     * @param attributeValue values of the attribute
+     */
+    public void add( String attributeName, String... attributeValue )
+    {
+        addModification( ModificationOperation.ADD_ATTRIBUTE, attributeName, attributeValue );
+    }
+
+
+    /**
+     * @see #add(String, String...)
+     */
+    public void add( String attributeName, byte[]... attributeValue )
+    {
+        addModification( ModificationOperation.ADD_ATTRIBUTE, attributeName, attributeValue );
+    }
+
+
+    /**
+     *
+     * marks a given attribute for addition in the target entry.
+     *
+     * @param attr the attribute to be added
+     */
+    public void add( EntryAttribute attr )
+    {
+        addModification( attr, ModificationOperation.ADD_ATTRIBUTE );
+    }
+
+
+    /**
+     * @see #replace(String, String...)
+     */
+    public void replace( String attributeName )
+    {
+        addModification( ModificationOperation.REPLACE_ATTRIBUTE, attributeName, Strings.EMPTY_STRINGS );
+    }
+
+
+    /**
+     *
+     * marks a given attribute for replacement with the given
+     * values in the target entry.
+     *
+     * @param attributeName name of the attribute to be added
+     * @param attributeValue values of the attribute
+     */
+    public void replace( String attributeName, String... attributeValue )
+    {
+        addModification( ModificationOperation.REPLACE_ATTRIBUTE, attributeName, attributeValue );
+    }
+
+
+    /**
+     * @see #replace(String, String...)
+     */
+    public void replace( String attributeName, byte[]... attributeValue )
+    {
+        addModification( ModificationOperation.REPLACE_ATTRIBUTE, attributeName, attributeValue );
+    }
+
+
+    /**
+     *
+     * marks a given attribute for replacement in the target entry.
+     *
+     * @param attr the attribute to be added
+     */
+    public void replace( EntryAttribute attr )
+    {
+        addModification( attr, ModificationOperation.REPLACE_ATTRIBUTE );
+    }
+
+
+    /**
+     * Store the current operation
+     * 
+     * @param currentOperation The currentOperation to set.
+     */
+    public void setCurrentOperation( int currentOperation )
+    {
+        this.currentOperation = ModificationOperation.getOperation( currentOperation );
+    }
+
+
+    /**
+     * Add a new attributeTypeAndValue
+     * 
+     * @param type The attribute's name
+     */
+    public void addAttributeTypeAndValues( String type )
+    {
+        currentAttribute = new DefaultEntryAttribute( type );
+
+        Modification modification = new DefaultModification( currentOperation, currentAttribute );
+        mods.add( modification );
+    }
+
+
+    /**
+     * Return the current attribute's type
+     */
+    public String getCurrentAttributeType()
+    {
+        return currentAttribute.getId();
+    }
+
+
+    /**
+     * Add a new value to the current attribute
+     * 
+     * @param value The value to add
+     */
+    public void addAttributeValue( byte[] value )
+    {
+        currentAttribute.add( value );
+    }
+
+
+    /**
+     * Add a new value to the current attribute
+     * 
+     * @param value The value to add
+     */
+    public void addAttributeValue( String value )
+    {
+        currentAttribute.add( value );
+    }
+
+
+    /**
+     * Removes a Modification to the set of modifications composing this
+     * modify request.
+     * 
+     * @param mod a Modification to remove.
+     */
+    public void removeModification( Modification mod )
+    {
+        mods.remove( mod );
+    }
+
+
+    /**
+     * marks a given attribute for removal with the given
+     * values from the target entry.
+     *
+     * @param attributeName name of the attribute to be added
+     * @param attributeValue values of the attribute
+     */
+    public void remove( String attributeName, String... attributeValue )
+    {
+        addModification( ModificationOperation.REMOVE_ATTRIBUTE, attributeName, attributeValue );
+    }
+
+
+    /**
+     * @see #remove(String, String...)
+     */
+    public void remove( String attributeName, byte[]... attributeValue )
+    {
+        addModification( ModificationOperation.REMOVE_ATTRIBUTE, attributeName, attributeValue );
+    }
+
+
+    /**
+     * marks a given attribute for removal from the target entry.
+     *
+     * @param attr the attribute to be added
+     */
+    public void remove( EntryAttribute attr )
+    {
+        addModification( attr, ModificationOperation.REMOVE_ATTRIBUTE );
+    }
+
+
+    // ------------------------------------------------------------------------
+    // SingleReplyRequest Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the protocol response message type for this request which produces
+     * at least one response.
+     * 
+     * @return the message type of the response.
+     */
+    public MessageTypeEnum getResponseType()
+    {
+        return RESP_TYPE;
+    }
+
+
+    /**
+     * The result containing response for this request.
+     * 
+     * @return the result containing response for this request
+     */
+    public ResultResponse getResultResponse()
+    {
+        if ( response == null )
+        {
+            response = new ModifyResponseImpl( getMessageId() );
+        }
+
+        return response;
+    }
+
+
+    /**
+     * @return The encoded ModifyRequest's length
+     */
+    /* No Qualifier*/void setModifyRequestLength( int modifyRequestLength )
+    {
+        this.modifyRequestLength = modifyRequestLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the ModifyRequest
+     * @param modifyRequestLength The encoded length
+     */
+    /* No Qualifier*/int getModifyRequestLength()
+    {
+        return modifyRequestLength;
+    }
+
+
+    /**
+     * @return The encoded Changes length
+     */
+    /* No Qualifier*/void setChangesLength( int changesLength )
+    {
+        this.changesLength = changesLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the Changes
+     * @param changesLength The encoded length
+     */
+    /* No Qualifier*/int getChangesLength()
+    {
+        return changesLength;
+    }
+
+
+    /**
+     * @return The list of encoded Change length
+     */
+    /* No Qualifier*/void setChangeLength( List<Integer> changeLength )
+    {
+        this.changeLength = changeLength;
+    }
+
+
+    /**
+     * Stores the list of encoded change length
+     * @param changeLength The list of encoded Change length
+     */
+    /* No Qualifier*/List<Integer> getChangeLength()
+    {
+        return changeLength;
+    }
+
+
+    /**
+     * @return The list of encoded Modification length
+     */
+    /* No Qualifier*/void setModificationLength( List<Integer> modificationLength )
+    {
+        this.modificationLength = modificationLength;
+    }
+
+
+    /**
+     * Stores the list of encoded modification length
+     * @param modificationLength The list of encoded Modification length
+     */
+    /* No Qualifier*/List<Integer> getModificationLength()
+    {
+        return modificationLength;
+    }
+
+
+    /**
+     * @return The list of encoded Values length
+     */
+    /* No Qualifier*/void setValuesLength( List<Integer> valuesLength )
+    {
+        this.valuesLength = valuesLength;
+    }
+
+
+    /**
+     * Stores the list of encoded Values length
+     * @param valuesLength The list of encoded Values length
+     */
+    /* No Qualifier*/List<Integer> getValuesLength()
+    {
+        return valuesLength;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( name != null )
+        {
+            hash = hash * 17 + name.hashCode();
+        }
+        hash = hash * 17 + mods.size();
+        for ( int i = 0; i < mods.size(); i++ )
+        {
+            hash = hash * 17 + ( ( DefaultModification ) mods.get( i ) ).hashCode();
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks to see if ModifyRequest stub equals another by factoring in checks
+     * for the name and modification items of the request.
+     * 
+     * @param obj
+     *            the object to compare this ModifyRequest to
+     * @return true if obj equals this ModifyRequest, false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        ModifyRequest req = ( ModifyRequest ) obj;
+
+        if ( name != null && req.getName() == null )
+        {
+            return false;
+        }
+
+        if ( name == null && req.getName() != null )
+        {
+            return false;
+        }
+
+        if ( name != null && req.getName() != null && !name.equals( req.getName() ) )
+        {
+            return false;
+        }
+
+        if ( req.getModifications().size() != mods.size() )
+        {
+            return false;
+        }
+
+        Iterator<Modification> list = req.getModifications().iterator();
+
+        for ( int i = 0; i < mods.size(); i++ )
+        {
+            Modification item = list.next();
+
+            if ( item == null )
+            {
+                if ( mods.get( i ) != null )
+                {
+                    return false;
+                }
+            }
+            else
+
+            if ( !item.equals( ( DefaultModification ) mods.get( i ) ) )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Get a String representation of a ModifyRequest
+     * 
+     * @return A ModifyRequest String
+     */
+    public String toString()
+    {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append( "    Modify Request\n" );
+        sb.append( "        Object : '" ).append( name ).append( "'\n" );
+
+        if ( mods != null )
+        {
+
+            for ( int i = 0; i < mods.size(); i++ )
+            {
+
+                DefaultModification modification = ( DefaultModification ) mods.get( i );
+
+                sb.append( "            Modification[" ).append( i ).append( "]\n" );
+                sb.append( "                Operation : " );
+
+                switch ( modification.getOperation() )
+                {
+                    case ADD_ATTRIBUTE:
+                        sb.append( " add\n" );
+                        break;
+
+                    case REPLACE_ATTRIBUTE:
+                        sb.append( " replace\n" );
+                        break;
+
+                    case REMOVE_ATTRIBUTE:
+                        sb.append( " delete\n" );
+                        break;
+                }
+
+                sb.append( "                Modification\n" );
+                sb.append( modification.getAttribute() );
+            }
+        }
+
+        // The controls
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyResponseImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyResponseImpl.java
new file mode 100644
index 0000000..9e1d85d
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ModifyResponseImpl.java
@@ -0,0 +1,96 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.AbstractResultResponse;
+import org.apache.directory.shared.ldap.message.ModifyResponse;
+
+/**
+ * ModifyResponse implementation
+ * 
+ */
+class ModifyResponseImpl extends AbstractResultResponse implements ModifyResponse
+{
+    /** The encoded modifyResponse length */
+    private int modifyResponseLength;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    static final long serialVersionUID = 4132526905748233730L;
+
+
+    /**
+     * Creates a ModifyResponse as a reply to an ModifyRequest.
+     */
+    public ModifyResponseImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates a ModifyResponse as a reply to an ModifyRequest.
+     * 
+     * @param id the sequence id for this response
+     */
+    public ModifyResponseImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    /**
+     * Stores the encoded length for the ModifyResponse
+     * @param modifyResponseLength The encoded length
+     */
+    /*No qualifier*/void setModifyResponseLength( int modifyResponseLength )
+    {
+        this.modifyResponseLength = modifyResponseLength;
+    }
+
+
+    /**
+     * @return The encoded ModifyResponse's length
+     */
+    /*No qualifier*/int getModifyResponseLength()
+    {
+        return modifyResponseLength;
+    }
+
+
+    /**
+     * Get a String representation of a ModifyResponse
+     * 
+     * @return A ModifyResponse String
+     */
+    public String toString()
+    {
+
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Modify Response\n" );
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ReferralImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ReferralImpl.java
new file mode 100644
index 0000000..cf28812
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/ReferralImpl.java
@@ -0,0 +1,219 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.Referral;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+
+
+/**
+ * A Referral implementation. For the time being this implementation uses a
+ * String representation for LDAPURLs. In the future an LdapUrl interface with
+ * default implementations will be used once a parser for an LdapUrl is created.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class ReferralImpl implements Referral
+{
+    static final long serialVersionUID = 2638820668325359096L;
+
+    /** Sequence of LDAPUrls composing this Referral */
+    private final List<String> urls = new ArrayList<String>();
+
+    /** The encoded LdapURL */
+    private final List<byte[]> urlsBytes = new ArrayList<byte[]>();
+
+    /** The length of the referral */
+    private int referralLength;
+
+
+    // ------------------------------------------------------------------------
+    // LdapResult Interface Method Implementations
+    // ------------------------------------------------------------------------
+    /**
+     * {@inheritDoc}
+     */
+    public int getReferralLength()
+    {
+        return referralLength;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setReferralLength( int referralLength )
+    {
+        this.referralLength = referralLength;
+    }
+
+
+    /**
+     * Gets an unmodifiable set of alternative referral urls.
+     * 
+     * @return the alternative url objects.
+     */
+    public Collection<String> getLdapUrls()
+    {
+        return Collections.unmodifiableCollection( urls );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Collection<byte[]> getLdapUrlsBytes()
+    {
+        return urlsBytes;
+    }
+
+
+    /**
+     * Adds an LDAPv3 URL to this Referral.
+     * 
+     * @param url the LDAPv3 URL to add
+     */
+    public void addLdapUrl( String url )
+    {
+        urls.add( url );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addLdapUrlBytes( byte[] urlBytes )
+    {
+        urlsBytes.add( urlBytes );
+    }
+
+
+    /**
+     * Removes an LDAPv3 URL to this Referral.
+     * 
+     * @param url
+     *            the LDAPv3 URL to remove
+     */
+    public void removeLdapUrl( String url )
+    {
+        urls.remove( url );
+    }
+
+
+    /**
+     * @see Object#hashCode()
+     * @return the instance's hash code 
+     */
+    public int hashCode()
+    {
+        int hash = 37;
+        hash = hash * 17 + urls.size();
+
+        // Order doesn't matter, so just add the url hashCode
+        for ( String url : urls )
+        {
+            hash = hash + url.hashCode();
+        }
+
+        return hash;
+    }
+
+
+    /**
+     * Compares this Referral implementation to see if it is the same as
+     * another. The classes do not have to be the same implementation to return
+     * true. Both this and the compared Referral must have the same entries
+     * exactly. The order of Referral URLs does not matter.
+     * 
+     * @param obj
+     *            the object to compare this ReferralImpl to
+     * @return true if both implementations contain exactly the same URLs
+     */
+    public boolean equals( Object obj )
+    {
+        // just in case for speed return true if obj is this object
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( obj instanceof Referral )
+        {
+            Collection<String> refs = ( ( Referral ) obj ).getLdapUrls();
+
+            // if their sizes do not match they are not equal
+            if ( refs.size() != urls.size() )
+            {
+                return false;
+            }
+
+            Iterator<String> list = urls.iterator();
+
+            while ( list.hasNext() )
+            {
+                // if one of our urls is not contained in the obj return false
+                if ( !refs.contains( list.next() ) )
+                {
+                    return false;
+                }
+            }
+
+            // made it through the checks so we have a match
+            return true;
+        }
+
+        return false;
+    }
+
+
+    /**
+     * Get a String representation of a Referral
+     * 
+     * @return A Referral String
+     */
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer();
+
+        if ( ( urls != null ) && ( urls.size() != 0 ) )
+        {
+            sb.append( "            Referrals :\n" );
+
+            Object[] urlsArray = urls.toArray();
+
+            for ( int i = 0; i < urlsArray.length; i++ )
+            {
+
+                String referral = ( String ) urlsArray[i];
+
+                sb.append( "                Referral[" ).append( i ).append( "] :" ).append( referral ).append( '\n' );
+            }
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchRequestImpl.java
new file mode 100644
index 0000000..316cd00
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchRequestImpl.java
@@ -0,0 +1,1158 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.directory.shared.asn1.ber.Asn1Container;
+import org.apache.directory.shared.asn1.ber.tlv.TLV;
+import org.apache.directory.shared.asn1.DecoderException;
+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.search.AndFilter;
+import org.apache.directory.shared.ldap.codec.search.AttributeValueAssertionFilter;
+import org.apache.directory.shared.ldap.codec.search.ConnectorFilter;
+import org.apache.directory.shared.ldap.codec.search.ExtensibleMatchFilter;
+import org.apache.directory.shared.ldap.codec.search.Filter;
+import org.apache.directory.shared.ldap.codec.search.NotFilter;
+import org.apache.directory.shared.ldap.codec.search.OrFilter;
+import org.apache.directory.shared.ldap.codec.search.PresentFilter;
+import org.apache.directory.shared.ldap.codec.search.SubstringFilter;
+import org.apache.directory.shared.ldap.entry.Value;
+import org.apache.directory.shared.ldap.exception.LdapException;
+import org.apache.directory.shared.ldap.exception.LdapProtocolErrorException;
+import org.apache.directory.shared.ldap.filter.AndNode;
+import org.apache.directory.shared.ldap.filter.ApproximateNode;
+import org.apache.directory.shared.ldap.filter.BranchNode;
+import org.apache.directory.shared.ldap.filter.BranchNormalizedVisitor;
+import org.apache.directory.shared.ldap.filter.EqualityNode;
+import org.apache.directory.shared.ldap.filter.ExprNode;
+import org.apache.directory.shared.ldap.filter.ExtensibleNode;
+import org.apache.directory.shared.ldap.filter.FilterParser;
+import org.apache.directory.shared.ldap.filter.GreaterEqNode;
+import org.apache.directory.shared.ldap.filter.LeafNode;
+import org.apache.directory.shared.ldap.filter.LessEqNode;
+import org.apache.directory.shared.ldap.filter.NotNode;
+import org.apache.directory.shared.ldap.filter.OrNode;
+import org.apache.directory.shared.ldap.filter.PresenceNode;
+import org.apache.directory.shared.ldap.filter.SearchScope;
+import org.apache.directory.shared.ldap.filter.SimpleNode;
+import org.apache.directory.shared.ldap.filter.SubstringNode;
+import org.apache.directory.shared.ldap.message.*;
+import org.apache.directory.shared.ldap.name.DN;
+
+
+/**
+ * SearchRequest implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ */
+class SearchRequestImpl extends AbstractAbandonableRequest implements SearchRequest
+{
+    static final long serialVersionUID = -5655881944020886218L;
+
+    /** Search base distinguished name */
+    private DN baseDn;
+
+    /** A temporary storage for a terminal Filter */
+    private Filter terminalFilter;
+
+    /** Search filter expression tree's root node */
+    private ExprNode filterNode;
+
+    /** The current filter. This is used while decoding a PDU */
+    private Filter currentFilter;
+
+    /** The global filter. This is used while decoding a PDU */
+    private Filter topFilter;
+
+    /** The SearchRequest TLV id */
+    private int tlvId;
+
+    /** Search scope enumeration value */
+    private SearchScope scope;
+
+    /** Types only return flag */
+    private boolean typesOnly;
+
+    /** Max size in entries to return */
+    private long sizeLimit;
+
+    /** Max seconds to wait for search to complete */
+    private int timeLimit;
+
+    /** Alias dereferencing mode enumeration value (default to DEREF_ALWAYS) */
+    private AliasDerefMode aliasDerefMode = AliasDerefMode.DEREF_ALWAYS;
+
+    /** Attributes to return */
+    private List<String> attributes = new ArrayList<String>();
+
+    /** The final result containing SearchResponseDone response */
+    private SearchResultDone response;
+
+    /** The searchRequest length */
+    private int searchRequestLength;
+
+    /** The attributeDescriptionList length */
+    private int attributeDescriptionListLength;
+
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+    /**
+     * Creates a SearcRequest implementing object used to search the
+     * DIT.
+     */
+    public SearchRequestImpl()
+    {
+        super( -1, MessageTypeEnum.SEARCH_REQUEST );
+    }
+
+
+    /**
+     * Creates a Lockable SearcRequest implementing object used to search the
+     * DIT.
+     * 
+     * @param id the sequential message identifier
+     */
+    public SearchRequestImpl( final int id )
+    {
+        super( id, MessageTypeEnum.SEARCH_REQUEST );
+    }
+
+
+    /**
+     * Transform the Filter part of a SearchRequest to an ExprNode
+     * 
+     * @param codecFilter The filter to be transformed
+     * @return An ExprNode
+     */
+    private ExprNode transform( Filter filter )
+    {
+        if ( filter != null )
+        {
+            // Transform OR, AND or NOT leaves
+            if ( filter instanceof ConnectorFilter )
+            {
+                BranchNode branch = null;
+
+                if ( filter instanceof AndFilter )
+                {
+                    branch = new AndNode();
+                }
+                else if ( filter instanceof OrFilter )
+                {
+                    branch = new OrNode();
+                }
+                else if ( filter instanceof NotFilter )
+                {
+                    branch = new NotNode();
+                }
+
+                List<Filter> filtersSet = ( ( ConnectorFilter ) filter ).getFilterSet();
+
+                // Loop on all AND/OR children
+                if ( filtersSet != null )
+                {
+                    for ( Filter node : filtersSet )
+                    {
+                        branch.addNode( transform( node ) );
+                    }
+                }
+
+                return branch;
+            }
+            else
+            {
+                // Transform PRESENT or ATTRIBUTE_VALUE_ASSERTION
+                LeafNode branch = null;
+
+                if ( filter instanceof PresentFilter )
+                {
+                    branch = new PresenceNode( ( ( PresentFilter ) filter ).getAttributeDescription() );
+                }
+                else if ( filter instanceof AttributeValueAssertionFilter )
+                {
+                    AttributeValueAssertion ava = ( ( AttributeValueAssertionFilter ) filter ).getAssertion();
+
+                    // Transform =, >=, <=, ~= filters
+                    switch ( ( ( AttributeValueAssertionFilter ) filter ).getFilterType() )
+                    {
+                        case LdapConstants.EQUALITY_MATCH_FILTER:
+                            branch = new EqualityNode( ava.getAttributeDesc(), ava.getAssertionValue() );
+
+                            break;
+
+                        case LdapConstants.GREATER_OR_EQUAL_FILTER:
+                            branch = new GreaterEqNode( ava.getAttributeDesc(), ava.getAssertionValue() );
+
+                            break;
+
+                        case LdapConstants.LESS_OR_EQUAL_FILTER:
+                            branch = new LessEqNode( ava.getAttributeDesc(), ava.getAssertionValue() );
+
+                            break;
+
+                        case LdapConstants.APPROX_MATCH_FILTER:
+                            branch = new ApproximateNode( ava.getAttributeDesc(), ava.getAssertionValue() );
+
+                            break;
+                    }
+
+                }
+                else if ( filter instanceof SubstringFilter )
+                {
+                    // Transform Substring filters
+                    SubstringFilter substrFilter = ( SubstringFilter ) filter;
+                    String initialString = null;
+                    String finalString = null;
+                    List<String> anyString = null;
+
+                    if ( substrFilter.getInitialSubstrings() != null )
+                    {
+                        initialString = substrFilter.getInitialSubstrings();
+                    }
+
+                    if ( substrFilter.getFinalSubstrings() != null )
+                    {
+                        finalString = substrFilter.getFinalSubstrings();
+                    }
+
+                    if ( substrFilter.getAnySubstrings() != null )
+                    {
+                        anyString = new ArrayList<String>();
+
+                        for ( String any : substrFilter.getAnySubstrings() )
+                        {
+                            anyString.add( any );
+                        }
+                    }
+
+                    branch = new SubstringNode( anyString, substrFilter.getType(), initialString, finalString );
+                }
+                else if ( filter instanceof ExtensibleMatchFilter )
+                {
+                    // Transform Extensible Match Filter
+                    ExtensibleMatchFilter extFilter = ( ExtensibleMatchFilter ) filter;
+                    String matchingRule = null;
+
+                    Value<?> value = extFilter.getMatchValue();
+
+                    if ( extFilter.getMatchingRule() != null )
+                    {
+                        matchingRule = extFilter.getMatchingRule();
+                    }
+
+                    branch = new ExtensibleNode( extFilter.getType(), value, matchingRule, extFilter.isDnAttributes() );
+                }
+
+                return branch;
+            }
+        }
+        else
+        {
+            // We have found nothing to transform. Return null then.
+            return null;
+        }
+    }
+
+
+    /**
+     * Transform an ExprNode filter to a Filter
+     * 
+     * @param exprNode The filter to be transformed
+     * @return A filter
+     */
+    private static Filter transform( ExprNode exprNode )
+    {
+        if ( exprNode != null )
+        {
+            Filter filter = null;
+
+            // Transform OR, AND or NOT leaves
+            if ( exprNode instanceof BranchNode )
+            {
+                if ( exprNode instanceof AndNode )
+                {
+                    filter = new AndFilter();
+                }
+                else if ( exprNode instanceof OrNode )
+                {
+                    filter = new OrFilter();
+                }
+                else if ( exprNode instanceof NotNode )
+                {
+                    filter = new NotFilter();
+                }
+
+                List<ExprNode> children = ( ( BranchNode ) exprNode ).getChildren();
+
+                // Loop on all AND/OR children
+                if ( children != null )
+                {
+                    for ( ExprNode child : children )
+                    {
+                        try
+                        {
+                            ( ( ConnectorFilter ) filter ).addFilter( transform( child ) );
+                        }
+                        catch ( DecoderException de )
+                        {
+                            return null;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                if ( exprNode instanceof PresenceNode )
+                {
+                    // Transform Presence Node
+                    filter = new PresentFilter();
+                    ( ( PresentFilter ) filter ).setAttributeDescription( ( ( PresenceNode ) exprNode ).getAttribute() );
+                }
+                else if ( exprNode instanceof SimpleNode<?> )
+                {
+                    if ( exprNode instanceof EqualityNode<?> )
+                    {
+                        filter = new AttributeValueAssertionFilter( LdapConstants.EQUALITY_MATCH_FILTER );
+                        AttributeValueAssertion assertion = new AttributeValueAssertion();
+                        assertion.setAttributeDesc( ( ( EqualityNode<?> ) exprNode ).getAttribute() );
+                        assertion.setAssertionValue( ( ( EqualityNode<?> ) exprNode ).getValue() );
+                        ( ( AttributeValueAssertionFilter ) filter ).setAssertion( assertion );
+                    }
+                    else if ( exprNode instanceof GreaterEqNode<?> )
+                    {
+                        filter = new AttributeValueAssertionFilter( LdapConstants.GREATER_OR_EQUAL_FILTER );
+                        AttributeValueAssertion assertion = new AttributeValueAssertion();
+                        assertion.setAttributeDesc( ( ( GreaterEqNode<?> ) exprNode ).getAttribute() );
+                        assertion.setAssertionValue( ( ( GreaterEqNode<?> ) exprNode ).getValue() );
+                        ( ( AttributeValueAssertionFilter ) filter ).setAssertion( assertion );
+                    }
+                    else if ( exprNode instanceof LessEqNode<?> )
+                    {
+                        filter = new AttributeValueAssertionFilter( LdapConstants.LESS_OR_EQUAL_FILTER );
+                        AttributeValueAssertion assertion = new AttributeValueAssertion();
+                        assertion.setAttributeDesc( ( ( LessEqNode<?> ) exprNode ).getAttribute() );
+                        assertion.setAssertionValue( ( ( LessEqNode<?> ) exprNode ).getValue() );
+                        ( ( AttributeValueAssertionFilter ) filter ).setAssertion( assertion );
+                    }
+                    else if ( exprNode instanceof ApproximateNode<?> )
+                    {
+                        filter = new AttributeValueAssertionFilter( LdapConstants.APPROX_MATCH_FILTER );
+                        AttributeValueAssertion assertion = new AttributeValueAssertion();
+                        assertion.setAttributeDesc( ( ( ApproximateNode<?> ) exprNode ).getAttribute() );
+                        assertion.setAssertionValue( ( ( ApproximateNode<?> ) exprNode ).getValue() );
+                        ( ( AttributeValueAssertionFilter ) filter ).setAssertion( assertion );
+                    }
+                }
+                else if ( exprNode instanceof SubstringNode )
+                {
+                    // Transform Substring Nodes
+                    filter = new SubstringFilter();
+
+                    ( ( SubstringFilter ) filter ).setType( ( ( SubstringNode ) exprNode ).getAttribute() );
+                    String initialString = ( ( SubstringNode ) exprNode ).getInitial();
+                    String finalString = ( ( SubstringNode ) exprNode ).getFinal();
+                    List<String> anyStrings = ( ( SubstringNode ) exprNode ).getAny();
+
+                    if ( initialString != null )
+                    {
+                        ( ( SubstringFilter ) filter ).setInitialSubstrings( initialString );
+                    }
+
+                    if ( finalString != null )
+                    {
+                        ( ( SubstringFilter ) filter ).setFinalSubstrings( finalString );
+                    }
+
+                    if ( anyStrings != null )
+                    {
+                        for ( String any : anyStrings )
+                        {
+                            ( ( SubstringFilter ) filter ).addAnySubstrings( any );
+                        }
+                    }
+                }
+                else if ( exprNode instanceof ExtensibleNode )
+                {
+                    // Transform Extensible Node
+                    filter = new ExtensibleMatchFilter();
+
+                    String attribute = ( ( ExtensibleNode ) exprNode ).getAttribute();
+                    String matchingRule = ( ( ExtensibleNode ) exprNode ).getMatchingRuleId();
+                    boolean dnAttributes = ( ( ExtensibleNode ) exprNode ).hasDnAttributes();
+                    Value<?> value = ( ( ExtensibleNode ) exprNode ).getValue();
+
+                    if ( attribute != null )
+                    {
+                        ( ( ExtensibleMatchFilter ) filter ).setType( attribute );
+                    }
+
+                    if ( matchingRule != null )
+                    {
+                        ( ( ExtensibleMatchFilter ) filter ).setMatchingRule( matchingRule );
+                    }
+
+                    ( ( ExtensibleMatchFilter ) filter ).setMatchValue( value );
+                    ( ( ExtensibleMatchFilter ) filter ).setDnAttributes( dnAttributes );
+                }
+            }
+
+            return filter;
+        }
+        else
+        {
+            // We have found nothing to transform. Return null then.
+            return null;
+        }
+    }
+
+
+    // ------------------------------------------------------------------------
+    // SearchRequest Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets a list of the attributes to be returned from each entry which
+     * matches the search filter. There are two special values which may be
+     * used: an empty list with no attributes, and the attribute description
+     * string "*". Both of these signify that all user attributes are to be
+     * returned. (The "*" allows the client to request all user attributes in
+     * addition to specific operational attributes). Attributes MUST be named at
+     * most once in the list, and are returned at most once in an entry. If
+     * there are attribute descriptions in the list which are not recognized,
+     * they are ignored by the server. If the client does not want any
+     * attributes returned, it can specify a list containing only the attribute
+     * with OID "1.1". This OID was chosen arbitrarily and does not correspond
+     * to any attribute in use. Client implementors should note that even if all
+     * user attributes are requested, some attributes of the entry may not be
+     * included in search results due to access control or other restrictions.
+     * Furthermore, servers will not return operational attributes, such as
+     * objectClasses or attributeTypes, unless they are listed by name, since
+     * there may be extremely large number of values for certain operational
+     * attributes.
+     * 
+     * @return the collection of attributes to return for each entry
+     */
+    public List<String> getAttributes()
+    {
+        return Collections.unmodifiableList( attributes );
+    }
+
+
+    /**
+     * Gets the search base as a distinguished name.
+     * 
+     * @return the search base
+     */
+    public DN getBase()
+    {
+        return baseDn;
+    }
+
+
+    /**
+     * Sets the search base as a distinguished name.
+     * 
+     * @param base
+     *            the search base
+     */
+    public void setBase( DN base )
+    {
+        baseDn = base;
+    }
+
+
+    /**
+     * Gets the alias handling parameter.
+     * 
+     * @return the alias handling parameter enumeration.
+     */
+    public AliasDerefMode getDerefAliases()
+    {
+        return aliasDerefMode;
+    }
+
+
+    /**
+     * Sets the alias handling parameter.
+     * 
+     * @param aliasDerefAliases
+     *            the alias handling parameter enumeration.
+     */
+    public void setDerefAliases( AliasDerefMode aliasDerefAliases )
+    {
+        this.aliasDerefMode = aliasDerefAliases;
+    }
+
+
+    /**
+     * Gets the search filter associated with this search request.
+     * 
+     * @return the expression node for the root of the filter expression tree.
+     */
+    public ExprNode getFilter()
+    {
+        if ( filterNode == null )
+        {
+            filterNode = transform( topFilter );
+        }
+
+        return filterNode;
+    }
+
+
+    /**
+     * Get the terminal filter
+     * 
+     * @return Returns the terminal filter.
+     */
+    public Filter getTerminalFilter()
+    {
+        return terminalFilter;
+    }
+
+
+    /**
+     * Set the terminal filter
+     * 
+     * @param terminalFilter the teminalFilter.
+     */
+    public void setTerminalFilter( Filter terminalFilter )
+    {
+        this.terminalFilter = terminalFilter;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setFilter( ExprNode filter )
+    {
+        this.filterNode = filter;
+    }
+
+
+    /**
+     * Set the current filter
+     * 
+     * @param filter The filter to set.
+     */
+    public void setCurrentFilter( Filter filter )
+    {
+        currentFilter = filter;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setFilter( String filter ) throws LdapException
+    {
+        try
+        {
+            filterNode = FilterParser.parse( filter );
+            this.currentFilter = transform( filterNode );
+        }
+        catch ( ParseException pe )
+        {
+            String msg = "The filter" + filter + " is invalid.";
+            throw new LdapProtocolErrorException( msg );
+        }
+    }
+
+
+    /**
+     * Get the parent Filter, if any
+     * 
+     * @return The parent filter
+     */
+    public Filter getCurrentFilter()
+    {
+        return currentFilter;
+    }
+
+
+    /**
+     * Add a current filter. We have two cases :
+     * - there is no previous current filter : the filter
+     * is the top level filter
+     * - there is a previous current filter : the filter is added 
+     * to the currentFilter set, and the current filter is changed
+     * 
+     * In any case, the previous current filter will always be a
+     * ConnectorFilter when this method is called.
+     * 
+     * @param localFilter The filter to set.
+     */
+    public void addCurrentFilter( Filter localFilter ) throws DecoderException
+    {
+        if ( currentFilter != null )
+        {
+            // Ok, we have a parent. The new Filter will be added to
+            // this parent, and will become the currentFilter if it's a connector.
+            ( ( ConnectorFilter ) currentFilter ).addFilter( localFilter );
+            localFilter.setParent( currentFilter, currentFilter.getTlvId() );
+
+            if ( localFilter instanceof ConnectorFilter )
+            {
+                currentFilter = localFilter;
+            }
+        }
+        else
+        {
+            // No parent. This Filter will become the root.
+            currentFilter = localFilter;
+            currentFilter.setParent( null, tlvId );
+            topFilter = localFilter;
+        }
+    }
+
+
+    /**
+     * This method is used to clear the filter's stack for terminated elements. An element
+     * is considered as terminated either if :
+     *  - it's a final element (ie an element which cannot contains a Filter)
+     *  - its current length equals its expected length.
+     * 
+     * @param container The container being decoded
+     */
+    public void unstackFilters( Asn1Container container )
+    {
+        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+        TLV tlv = ldapMessageContainer.getCurrentTLV();
+        TLV localParent = tlv.getParent();
+        Filter localFilter = terminalFilter;
+
+        // The parent has been completed, so fold it
+        while ( ( localParent != null ) && ( localParent.getExpectedLength() == 0 ) )
+        {
+            int parentTlvId = localFilter.getParent() != null ? localFilter.getParent().getTlvId() : localFilter
+                .getParentTlvId();
+
+            if ( localParent.getId() != parentTlvId )
+            {
+                localParent = localParent.getParent();
+
+            }
+            else
+            {
+                Filter filterParent = localFilter.getParent();
+
+                // We have a special case with PresentFilter, which has not been 
+                // pushed on the stack, so we need to get its parent's parent
+                if ( localFilter instanceof PresentFilter )
+                {
+                    if ( filterParent == null )
+                    {
+                        // We don't have parent, get out
+                        break;
+                    }
+
+                    filterParent = filterParent.getParent();
+                }
+                else if ( filterParent instanceof Filter )
+                {
+                    filterParent = filterParent.getParent();
+                }
+
+                if ( filterParent instanceof Filter )
+                {
+                    // The parent is a filter ; it will become the new currentFilter
+                    // and we will loop again. 
+                    currentFilter = ( Filter ) filterParent;
+                    localFilter = currentFilter;
+                    localParent = localParent.getParent();
+                }
+                else
+                {
+                    // We can stop the recursion, we have reached the searchResult Object
+                    break;
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Gets the different response types generated by a search request.
+     * 
+     * @return the RESPONSE_TYPES array
+     * @see #RESPONSE_TYPES
+     */
+    public MessageTypeEnum[] getResponseTypes()
+    {
+        return RESPONSE_TYPES.clone();
+    }
+
+
+    /**
+     * Gets the search scope parameter enumeration.
+     * 
+     * @return the scope enumeration parameter.
+     */
+    public SearchScope getScope()
+    {
+        return scope;
+    }
+
+
+    /**
+     * Sets the search scope parameter enumeration.
+     * 
+     * @param scope the scope enumeration parameter.
+     */
+    public void setScope( SearchScope scope )
+    {
+        this.scope = scope;
+    }
+
+
+    /**
+     * A sizelimit that restricts the maximum number of entries to be returned
+     * as a result of the search. A value of 0 in this field indicates that no
+     * client-requested sizelimit restrictions are in effect for the search.
+     * Servers may enforce a maximum number of entries to return.
+     * 
+     * @return search size limit.
+     */
+    public long getSizeLimit()
+    {
+        return sizeLimit;
+    }
+
+
+    /**
+     * Sets sizelimit that restricts the maximum number of entries to be
+     * returned as a result of the search. A value of 0 in this field indicates
+     * that no client-requested sizelimit restrictions are in effect for the
+     * search. Servers may enforce a maximum number of entries to return.
+     * 
+     * @param entriesMax maximum search result entries to return.
+     */
+    public void setSizeLimit( long entriesMax )
+    {
+        sizeLimit = entriesMax;
+    }
+
+
+    /**
+     * Gets the timelimit that restricts the maximum time (in seconds) allowed
+     * for a search. A value of 0 in this field indicates that no client-
+     * requested timelimit restrictions are in effect for the search.
+     * 
+     * @return the search time limit in seconds.
+     */
+    public int getTimeLimit()
+    {
+        return timeLimit;
+    }
+
+
+    /**
+     * Sets the timelimit that restricts the maximum time (in seconds) allowed
+     * for a search. A value of 0 in this field indicates that no client-
+     * requested timelimit restrictions are in effect for the search.
+     * 
+     * @param secondsMax the search time limit in seconds.
+     */
+    public void setTimeLimit( int secondsMax )
+    {
+        timeLimit = secondsMax;
+    }
+
+
+    /**
+     * An indicator as to whether search results will contain both attribute
+     * types and values, or just attribute types. Setting this field to TRUE
+     * causes only attribute types (no values) to be returned. Setting this
+     * field to FALSE causes both attribute types and values to be returned.
+     * 
+     * @return true for only types, false for types and values.
+     */
+    public boolean getTypesOnly()
+    {
+        return typesOnly;
+    }
+
+
+    /**
+     * An indicator as to whether search results will contain both attribute
+     * types and values, or just attribute types. Setting this field to TRUE
+     * causes only attribute types (no values) to be returned. Setting this
+     * field to FALSE causes both attribute types and values to be returned.
+     * 
+     * @param typesOnly true for only types, false for types and values.
+     */
+    public void setTypesOnly( boolean typesOnly )
+    {
+        this.typesOnly = typesOnly;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addAttributes( String... attributesToAdd )
+    {
+        for ( String attribute : attributesToAdd )
+        {
+            this.attributes.add( attribute );
+        }
+    }
+
+
+    /**
+     * Removes an attribute to the set of entry attributes to return.
+     * 
+     * @param attribute the attribute description or identifier.
+     */
+    public void removeAttribute( String attribute )
+    {
+        attributes.remove( attribute );
+    }
+
+
+    /**
+     * The result containing response for this request.
+     * 
+     * @return the result containing response for this request
+     */
+    public ResultResponse getResultResponse()
+    {
+        if ( response == null )
+        {
+            response = new SearchResultDoneImpl( getMessageId() );
+        }
+
+        return response;
+    }
+
+
+    /**
+     * Stores the encoded length for the SearchRequest
+     * @param searchRequestLength The encoded length
+     */
+    /*No qualifier*/void setSearchRequestLength( int searchRequestLength )
+    {
+        this.searchRequestLength = searchRequestLength;
+    }
+
+
+    /**
+     * @return The encoded SearchRequest's length
+     */
+    /*No qualifier*/int getSearchRequestLength()
+    {
+        return searchRequestLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the list of attributes
+     * @param attributeDescriptionListLength The encoded length of the attributes
+     */
+    /*No qualifier*/void setAttributeDescriptionListLength( int attributeDescriptionListLength )
+    {
+        this.attributeDescriptionListLength = attributeDescriptionListLength;
+    }
+
+
+    /**
+     * @return The encoded SearchRequest's attributes length
+     */
+    /*No qualifier*/int getAttributeDescriptionListLength()
+    {
+        return attributeDescriptionListLength;
+    }
+
+
+    /**
+     * Set the SearchRequest PDU TLV's Id
+     * @param tlvId The TLV id
+     */
+    public void setTlvId( int tlvId )
+    {
+        this.tlvId = tlvId;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+
+        if ( baseDn != null )
+        {
+            hash = hash * 17 + baseDn.hashCode();
+        }
+
+        hash = hash * 17 + aliasDerefMode.hashCode();
+        hash = hash * 17 + scope.hashCode();
+        hash = hash * 17 + Long.valueOf( sizeLimit ).hashCode();
+        hash = hash * 17 + timeLimit;
+        hash = hash * 17 + ( typesOnly ? 0 : 1 );
+
+        if ( attributes != null )
+        {
+            hash = hash * 17 + attributes.size();
+
+            // Order doesn't matter, thus just add hashCode
+            for ( String attr : attributes )
+            {
+                hash = hash + attr.hashCode();
+            }
+        }
+
+        BranchNormalizedVisitor visitor = new BranchNormalizedVisitor();
+        filterNode.accept( visitor );
+        hash = hash * 17 + currentFilter.toString().hashCode();
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks to see if two search requests are equal. The Lockable properties
+     * and the get/set context specific parameters are not consulted to
+     * determine equality. The filter expression tree comparison will normalize
+     * the child order of filter branch nodes then generate a string
+     * representation which is comparable. For the time being this is a very
+     * costly operation.
+     * 
+     * @param obj the object to check for equality to this SearchRequest
+     * @return true if the obj is a SearchRequest and equals this SearchRequest,
+     *         false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        SearchRequest req = ( SearchRequest ) obj;
+
+        if ( !req.getBase().equals( baseDn ) )
+        {
+            return false;
+        }
+
+        if ( req.getDerefAliases() != aliasDerefMode )
+        {
+            return false;
+        }
+
+        if ( req.getScope() != scope )
+        {
+            return false;
+        }
+
+        if ( req.getSizeLimit() != sizeLimit )
+        {
+            return false;
+        }
+
+        if ( req.getTimeLimit() != timeLimit )
+        {
+            return false;
+        }
+
+        if ( req.getTypesOnly() != typesOnly )
+        {
+            return false;
+        }
+
+        if ( req.getAttributes() == null && attributes != null && attributes.size() > 0 )
+        {
+            return false;
+        }
+
+        if ( req.getAttributes() != null && attributes == null && req.getAttributes().size() > 0 )
+        {
+            return false;
+        }
+
+        if ( req.getAttributes() != null && attributes != null )
+        {
+            if ( req.getAttributes().size() != attributes.size() )
+            {
+                return false;
+            }
+
+            Iterator<String> list = attributes.iterator();
+
+            while ( list.hasNext() )
+            {
+                if ( !req.getAttributes().contains( list.next() ) )
+                {
+                    return false;
+                }
+            }
+        }
+
+        BranchNormalizedVisitor visitor = new BranchNormalizedVisitor();
+        req.getFilter().accept( visitor );
+        filterNode.accept( visitor );
+
+        String myFilterString = currentFilter.toString();
+        String reqFilterString = req.getFilter().toString();
+
+        return myFilterString.equals( reqFilterString );
+    }
+
+
+    /**
+     * Return a string the represent a SearchRequest
+     * {@inheritDoc}
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    SearchRequest\n" );
+        sb.append( "        baseDn : '" ).append( baseDn ).append( "'\n" );
+
+        if ( currentFilter != null )
+        {
+            sb.append( "        filter : '" );
+            sb.append( currentFilter.toString() );
+            sb.append( "'\n" );
+        }
+
+        sb.append( "        scope : " );
+
+        switch ( scope )
+        {
+            case OBJECT:
+                sb.append( "base object" );
+                break;
+
+            case ONELEVEL:
+                sb.append( "single level" );
+                break;
+
+            case SUBTREE:
+                sb.append( "whole subtree" );
+                break;
+        }
+
+        sb.append( '\n' );
+
+        sb.append( "        typesOnly : " ).append( typesOnly ).append( '\n' );
+
+        sb.append( "        Size Limit : " );
+
+        if ( sizeLimit == 0L )
+        {
+            sb.append( "no limit" );
+        }
+        else
+        {
+            sb.append( sizeLimit );
+        }
+
+        sb.append( '\n' );
+
+        sb.append( "        Time Limit : " );
+
+        if ( timeLimit == 0 )
+        {
+            sb.append( "no limit" );
+        }
+        else
+        {
+            sb.append( timeLimit );
+        }
+
+        sb.append( '\n' );
+
+        sb.append( "        Deref Aliases : " );
+
+        switch ( aliasDerefMode )
+        {
+            case NEVER_DEREF_ALIASES:
+                sb.append( "never Deref Aliases" );
+                break;
+
+            case DEREF_IN_SEARCHING:
+                sb.append( "deref In Searching" );
+                break;
+
+            case DEREF_FINDING_BASE_OBJ:
+                sb.append( "deref Finding Base Obj" );
+                break;
+
+            case DEREF_ALWAYS:
+                sb.append( "deref Always" );
+                break;
+        }
+
+        sb.append( '\n' );
+        sb.append( "        attributes : " );
+
+        boolean isFirst = true;
+
+        if ( attributes != null )
+        {
+            Iterator<String> it = attributes.iterator();
+
+            while ( it.hasNext() )
+            {
+                if ( isFirst )
+                {
+                    isFirst = false;
+                }
+                else
+                {
+                    sb.append( ", " );
+                }
+
+                sb.append( '\'' ).append( it.next() ).append( '\'' );
+            }
+
+        }
+
+        sb.append( '\n' );
+
+        // The controls
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
\ No newline at end of file
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchResultDoneImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchResultDoneImpl.java
new file mode 100644
index 0000000..f91e2b3
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchResultDoneImpl.java
@@ -0,0 +1,145 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.AbstractResultResponse;
+import org.apache.directory.shared.ldap.message.LdapResult;
+import org.apache.directory.shared.ldap.message.SearchResultDone;
+
+/**
+ * SearchResponseDone implementation
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ */
+class SearchResultDoneImpl extends AbstractResultResponse implements SearchResultDone
+{
+    /** The encoded searchResultDone length */
+    private int searchResultDoneLength;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    static final long serialVersionUID = 8698484213877460215L;
+
+
+    /**
+     * Creates a SearchResponseDone as a reply to an SearchRequest to
+     * indicate the end of a search operation.
+     */
+    public SearchResultDoneImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates a SearchResponseDone as a reply to an SearchRequest to
+     * indicate the end of a search operation.
+     * 
+     * @param id the session unique message id
+     */
+    public SearchResultDoneImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        hash = hash * 17 + getLdapResult().hashCode();
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks for equality by using the underlying LdapResult objects of this
+     * SearchResponseDone stub.
+     * 
+     * @param obj
+     *            the object to be tested for equality
+     * @return true if obj is equivalent to this SearchResponseDone impl
+     */
+    public boolean equals( Object obj )
+    {
+        // quickly return if the obj is this object
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        LdapResult result = ( ( SearchResultDone ) obj ).getLdapResult();
+
+        if ( !getLdapResult().equals( result ) )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Stores the encoded length for the SearchResultDone
+     * @param searchResultDoneLength The encoded length
+     */
+    /*No qualifier*/void setSearchResultDoneLength( int searchResultDoneLength )
+    {
+        this.searchResultDoneLength = searchResultDoneLength;
+    }
+
+
+    /**
+     * @return The encoded SearchResultDone's length
+     */
+    /*No qualifier*/int getSearchResultDoneLength()
+    {
+        return searchResultDoneLength;
+    }
+
+
+    /**
+     * Get a String representation of a SearchResultDone
+     * 
+     * @return A SearchResultDone String
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Search Result Done\n" );
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchResultEntryImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchResultEntryImpl.java
new file mode 100644
index 0000000..0759686
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchResultEntryImpl.java
@@ -0,0 +1,357 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import java.util.List;
+
+import org.apache.directory.shared.ldap.entry.DefaultEntry;
+import org.apache.directory.shared.ldap.entry.DefaultEntryAttribute;
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.exception.LdapException;
+import org.apache.directory.shared.ldap.message.AbstractResponse;
+import org.apache.directory.shared.ldap.message.SearchResultEntry;
+import org.apache.directory.shared.ldap.message.control.Control;
+import org.apache.directory.shared.ldap.name.DN;
+
+
+/**
+ * Lockable SearchResponseEntry implementation
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class SearchResultEntryImpl extends AbstractResponse implements SearchResultEntry
+{
+    static final long serialVersionUID = -8357316233060886637L;
+
+    /** Entry returned in response to search */
+    private Entry entry = new DefaultEntry();
+
+    /** The current attribute being decoded */
+    private EntryAttribute currentAttribute;
+
+    /** A temporary storage for the byte[] representing the objectName */
+    private byte[] objectNameBytes;
+
+    /** The search result entry length */
+    private int searchResultEntryLength;
+
+    /** The partial attributes length */
+    private int attributesLength;
+
+    /** The list of all attributes length */
+    private List<Integer> attributeLength;
+
+    /** The list of all vals length */
+    private List<Integer> valsLength;
+
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+    /**
+     * Creates a SearchResponseEntry as a reply to an SearchRequest to
+     * indicate the end of a search operation.
+     */
+    public SearchResultEntryImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates a SearchResponseEntry as a reply to an SearchRequest to
+     * indicate the end of a search operation.
+     * 
+     * @param id the session unique message id
+     */
+    public SearchResultEntryImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    // ------------------------------------------------------------------------
+    // SearchResponseEntry Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the entry
+     * 
+     * @return the entry
+     */
+    public Entry getEntry()
+    {
+        return entry;
+    }
+
+
+    /**
+     * Create a new attribute
+     * 
+     * @param type The attribute's type
+     */
+    public void addAttribute( String type ) throws LdapException
+    {
+        currentAttribute = new DefaultEntryAttribute( type );
+
+        entry.put( currentAttribute );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public EntryAttribute getCurrentAttribute()
+    {
+        return currentAttribute;
+    }
+
+
+    /**
+     * Add a new value to the current attribute
+     * 
+     * @param value The added value
+     */
+    public void addAttributeValue( Object value )
+    {
+        if ( value instanceof String )
+        {
+            currentAttribute.add( ( String ) value );
+        }
+        else
+        {
+            currentAttribute.add( ( byte[] ) value );
+        }
+    }
+
+
+    /**
+     * Sets the entry.
+     * 
+     * @param entry the entry
+     */
+    public void setEntry( Entry entry )
+    {
+        this.entry = entry;
+    }
+
+
+    /**
+     * Gets the distinguished name of the entry object returned.
+     * 
+     * @return the Dn of the entry returned.
+     */
+    public DN getObjectName()
+    {
+        return ( entry == null ? null : entry.getDn() );
+    }
+
+
+    /**
+     * Gets the distinguished name bytes of the entry object returned.
+     * 
+     * @return the Dn bytes of the entry returned.
+     */
+    /*No qualifier*/byte[] getObjectNameBytes()
+    {
+        return objectNameBytes;
+    }
+
+
+    /**
+     * Sets the distinguished name bytes of the entry object returned.
+     * 
+     * @param objectNameBytes the Dn bytes of the entry returned.
+     */
+    /*No qualifier*/void setObjectNameBytes( byte[] objectNameBytes )
+    {
+        this.objectNameBytes = objectNameBytes;
+    }
+
+
+    /**
+     * Sets the distinguished name of the entry object returned.
+     * 
+     * @param objectName the Dn of the entry returned.
+     */
+    public void setObjectName( DN objectName )
+    {
+        if ( entry != null )
+        {
+            entry.setDn( objectName );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( entry != null )
+        {
+            hash = hash * 17 + entry.hashCode();
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks for equality by comparing the objectName, and attributes
+     * properties of this Message after delegating to the super.equals() method.
+     * 
+     * @param obj
+     *            the object to test for equality with this message
+     * @return true if the obj is equal false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        if ( !( obj instanceof SearchResultEntry ) )
+        {
+            return false;
+        }
+
+        SearchResultEntry resp = ( SearchResultEntry ) obj;
+
+        return entry.equals( resp.getEntry() );
+    }
+
+
+    /**
+     * @return The encoded SearchResultEntry's length
+     */
+    /*No qualifier*/int getSearchResultEntryLength()
+    {
+        return searchResultEntryLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the SearchResultEntry
+     * @param searchResultEntryLength The encoded length
+     */
+    /*No qualifier*/void setSearchResultEntryLength( int searchResultEntryLength )
+    {
+        this.searchResultEntryLength = searchResultEntryLength;
+    }
+
+
+    /**
+     * @return The encoded PartialAttributeList's length
+     */
+    /*No qualifier*/int getAttributesLength()
+    {
+        return attributesLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the Attributes
+     * @param attributeLength The list of encoded lengths
+     */
+    /*No qualifier*/void setAttributesLength( int attributesLength )
+    {
+        this.attributesLength = attributesLength;
+    }
+
+
+    /**
+     * @return The encoded PartialAttributeList's length
+     */
+    /*No qualifier*/List<Integer> getAttributeLength()
+    {
+        return attributeLength;
+    }
+
+
+    /**
+     * @return The list of encoded Attributes' length
+     */
+    /*No qualifier*/void setAttributeLength( List<Integer> attributeLength )
+    {
+        this.attributeLength = attributeLength;
+    }
+
+
+    /**
+     * @return The list of encoded values' length
+     */
+    /*No qualifier*/List<Integer> getValsLength()
+    {
+        return valsLength;
+    }
+
+
+    /**
+     * Stores the list of encoded length for the values 
+     * @param valsLength The list of encoded lengths
+     */
+    /*No qualifier*/void setValsLength( List<Integer> valsLength )
+    {
+        this.valsLength = valsLength;
+    }
+
+
+    /**
+     * Return a string representation of a SearchResultEntry request
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Search Result Entry\n" );
+
+        if ( entry != null )
+        {
+            sb.append( entry );
+        }
+        else
+        {
+            sb.append( "            No entry\n" );
+        }
+
+        if ( ( controls != null ) && ( controls.size() != 0 ) )
+        {
+            for ( Control control : controls.values() )
+            {
+                sb.append( control );
+            }
+        }
+
+        return sb.toString();
+    }
+
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchResultReferenceImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchResultReferenceImpl.java
new file mode 100644
index 0000000..f263e42
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/SearchResultReferenceImpl.java
@@ -0,0 +1,228 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.ldap.message.*;
+import org.apache.directory.shared.ldap.message.control.Control;
+
+
+/**
+ * SearchResponseReference implementation
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class SearchResultReferenceImpl extends AbstractResponse implements SearchResultReference
+{
+    static final long serialVersionUID = 7423807019951309810L;
+
+    /** Referral holding the reference urls */
+    private Referral referral = new ReferralImpl();
+
+    /** The length of the referral */
+    private int referralLength;
+
+    /** The search result reference length */
+    private int searchResultReferenceLength;
+
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+    /**
+     * Creates a SearchResponseReference as a reply to an SearchRequest
+     * to indicate the end of a search operation.
+     */
+    public SearchResultReferenceImpl()
+    {
+        super( -1, TYPE );
+    }
+
+
+    /**
+     * Creates a SearchResponseReference as a reply to an SearchRequest
+     * to indicate the end of a search operation.
+     * 
+     * @param id the session unique message id
+     */
+    public SearchResultReferenceImpl( final int id )
+    {
+        super( id, TYPE );
+    }
+
+
+    // ------------------------------------------------------------------------
+    // SearchResponseReference Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets the sequence of LdapUrls as a Referral instance.
+     * 
+     * @return the sequence of LdapUrls
+     */
+    public Referral getReferral()
+    {
+        return this.referral;
+    }
+
+
+    /**
+     * Sets the sequence of LdapUrls as a Referral instance.
+     * 
+     * @param referral the sequence of LdapUrls
+     */
+    public void setReferral( Referral referral )
+    {
+        this.referral = referral;
+    }
+
+
+    /**
+     * @return The encoded Referral's length
+     */
+    /* No qualifier */int getReferralLength()
+    {
+        return referralLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the Referrals
+     * @param searchReferralLength The encoded length
+     */
+    /* No qualifier */void setReferralLength( int referralLength )
+    {
+        this.referralLength = referralLength;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( this.referral != null )
+        {
+            hash = hash * 17 + this.referral.hashCode();
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
+     * Checks to see if an object is equal to this SearchResponseReference stub.
+     * 
+     * @param obj
+     *            the object to compare to this response stub
+     * @return true if the objects are equivalent false otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+
+        SearchResultReference resp = ( SearchResultReference ) obj;
+
+        if ( this.referral != null && resp.getReferral() == null )
+        {
+            return false;
+        }
+
+        if ( this.referral == null && resp.getReferral() != null )
+        {
+            return false;
+        }
+
+        if ( this.referral != null && resp.getReferral() != null && !this.referral.equals( resp.getReferral() ) )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * @return The encoded SearchResultReference's length
+     */
+    /* No qualifier */int getSearchResultReferenceLength()
+    {
+        return searchResultReferenceLength;
+    }
+
+
+    /**
+     * Stores the encoded length for the SearchResultReference's
+     * @param searchResultReferenceLength The encoded length
+     */
+    /* No qualifier */void setSearchResultReferenceLength( int searchResultReferenceLength )
+    {
+        this.searchResultReferenceLength = searchResultReferenceLength;
+    }
+
+
+    /**
+     * Returns the Search Result Reference string
+     * 
+     * @return The Search Result Reference string
+     */
+    public String toString()
+    {
+
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    Search Result Reference\n" );
+
+        if ( ( referral == null ) || ( referral.getLdapUrls() == null ) || ( referral.getLdapUrls().size() == 0 ) )
+        {
+            sb.append( "        No Reference\n" );
+        }
+        else
+        {
+            sb.append( "        References\n" );
+
+            for ( String url : referral.getLdapUrls() )
+            {
+                sb.append( "            '" ).append( url ).append( "'\n" );
+            }
+        }
+
+        if ( ( controls != null ) && ( controls.size() != 0 ) )
+        {
+            for ( Control control : controls.values() )
+            {
+                sb.append( control );
+            }
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/UnbindRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/UnbindRequestImpl.java
new file mode 100644
index 0000000..37c1e8e
--- /dev/null
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/message/UnbindRequestImpl.java
@@ -0,0 +1,77 @@
+/*
+ *  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.shared.ldap.codec.message;
+
+
+import org.apache.directory.shared.i18n.I18n;
+import org.apache.directory.shared.ldap.message.AbstractRequest;
+import org.apache.directory.shared.ldap.message.UnbindRequest;
+
+
+/**
+ * Lockable UnbindRequest implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ */
+class UnbindRequestImpl extends AbstractRequest implements UnbindRequest
+{
+    static final long serialVersionUID = -6217184085100410116L;
+
+
+    /**
+     * Creates an UnbindRequest which takes no parameter other than those in the
+     * outer envelope to disconnect and end a client session on the server
+     * without producing any response.
+     * 
+     * @param id the sequential message identifier.
+     */
+    public UnbindRequestImpl( final int id )
+    {
+        super( id, TYPE, false );
+    }
+
+
+    /**
+     * RFC 2251 [Section 4.11]: Abandon, Bind, Unbind, and StartTLS operations
+     * cannot be abandoned.
+     */
+    public void abandon()
+    {
+        throw new UnsupportedOperationException( I18n.err( I18n.ERR_04185 ) );
+    }
+
+
+    /**
+     * Get a String representation of a UnBindRequest
+     * 
+     * @return A UnBindRequest String
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "    UnBind Request" );
+
+        // The controls
+        sb.append( super.toString() );
+
+        return sb.toString();
+    }
+}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/JndiUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/JndiUtils.java
index ee918f5..b068496 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/JndiUtils.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/util/JndiUtils.java
@@ -198,7 +198,7 @@
             public ExtendedResponse createExtendedResponse( String id, byte[] berValue, int offset, int length )
                 throws NamingException
             {
-                org.apache.directory.shared.ldap.message.ExtendedResponse response = new ExtendedResponseImpl( request
+                org.apache.directory.shared.ldap.message.ExtendedResponse response = new org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl( request
                     .getMessageId(), request.getRequestName() );
                 response.setResponseName( id );
                 response.setResponseValue( berValue );
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapControlTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapControlTest.java
index b0fcc91..3a675f9 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapControlTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapControlTest.java
@@ -35,8 +35,7 @@
 import org.apache.directory.shared.asn1.DecoderException;
 import org.apache.directory.shared.asn1.EncoderException;
 import org.apache.directory.shared.ldap.message.AbandonRequest;
-import org.apache.directory.shared.ldap.message.AbandonRequestImpl;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.AbandonRequestImpl;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
 import org.junit.Test;
@@ -48,7 +47,7 @@
 public class LdapControlTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapMessageTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapMessageTest.java
index 5081945..480998c 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapMessageTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapMessageTest.java
@@ -32,10 +32,8 @@
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.asn1.ber.Asn1Decoder;
 import org.apache.directory.shared.asn1.EncoderException;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.UnbindRequest;
-import org.apache.directory.shared.ldap.message.UnbindRequestImpl;
 import org.apache.directory.shared.util.Strings;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -51,7 +49,7 @@
 public class LdapMessageTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     // ~ Methods
@@ -317,7 +315,7 @@
         assertEquals( 500, message.getMessageId() );
 
         // Check the length
-        UnbindRequest internalUnbindRequest = new UnbindRequestImpl( message.getMessageId() );
+        UnbindRequest internalUnbindRequest = new org.apache.directory.shared.ldap.codec.message.UnbindRequestImpl( message.getMessageId() );
 
         try
         {
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapResultTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapResultTest.java
index 978bb28..9d67a0d 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapResultTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/LdapResultTest.java
@@ -35,7 +35,7 @@
 import org.apache.directory.shared.asn1.ber.Asn1Decoder;
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.ldap.message.AddResponse;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.Referral;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.util.Strings;
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/abandon/AbandonRequestTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/abandon/AbandonRequestTest.java
index 19825a4..5e24a52 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/abandon/AbandonRequestTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/abandon/AbandonRequestTest.java
@@ -36,8 +36,7 @@
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.message.AbandonRequest;
-import org.apache.directory.shared.ldap.message.AbandonRequestImpl;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.AbandonRequestImpl;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
 import org.junit.Test;
@@ -54,7 +53,7 @@
 public class AbandonRequestTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/add/AddRequestTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/add/AddRequestTest.java
index 959e2ff..8cf84f2 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/add/AddRequestTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/add/AddRequestTest.java
@@ -44,8 +44,7 @@
 import org.apache.directory.shared.ldap.entry.EntryAttribute;
 import org.apache.directory.shared.ldap.entry.Value;
 import org.apache.directory.shared.ldap.message.AddRequest;
-import org.apache.directory.shared.ldap.message.AddResponseImpl;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
@@ -64,7 +63,7 @@
 public class AddRequestTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
@@ -309,8 +308,8 @@
         {
             assertTrue( de instanceof ResponseCarryingException );
             Message response = ( ( ResponseCarryingException ) de ).getResponse();
-            assertTrue( response instanceof AddResponseImpl );
-            assertEquals( ResultCodeEnum.NAMING_VIOLATION, ( ( AddResponseImpl ) response ).getLdapResult()
+            assertTrue( response instanceof org.apache.directory.shared.ldap.codec.message.AddResponseImpl);
+            assertEquals( ResultCodeEnum.NAMING_VIOLATION, ( (org.apache.directory.shared.ldap.codec.message.AddResponseImpl) response ).getLdapResult()
                 .getResultCode() );
             return;
         }
@@ -380,8 +379,8 @@
         {
             assertTrue( de instanceof ResponseCarryingException );
             Message response = ( ( ResponseCarryingException ) de ).getResponse();
-            assertTrue( response instanceof AddResponseImpl );
-            assertEquals( ResultCodeEnum.INVALID_DN_SYNTAX, ( ( AddResponseImpl ) response ).getLdapResult()
+            assertTrue( response instanceof org.apache.directory.shared.ldap.codec.message.AddResponseImpl);
+            assertEquals( ResultCodeEnum.INVALID_DN_SYNTAX, ( (org.apache.directory.shared.ldap.codec.message.AddResponseImpl) response ).getLdapResult()
                 .getResultCode() );
             return;
         }
@@ -522,8 +521,8 @@
         {
             assertTrue( de instanceof ResponseCarryingException );
             Message response = ( ( ResponseCarryingException ) de ).getResponse();
-            assertTrue( response instanceof AddResponseImpl );
-            assertEquals( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, ( ( AddResponseImpl ) response ).getLdapResult()
+            assertTrue( response instanceof org.apache.directory.shared.ldap.codec.message.AddResponseImpl);
+            assertEquals( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, ( (org.apache.directory.shared.ldap.codec.message.AddResponseImpl) response ).getLdapResult()
                 .getResultCode() );
             return;
         }
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/add/AddResponseTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/add/AddResponseTest.java
index 05ce462..d9dd699 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/add/AddResponseTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/add/AddResponseTest.java
@@ -35,7 +35,6 @@
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.message.AddResponse;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
@@ -51,7 +50,7 @@
 public class AddResponseTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindRequestPerfTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindRequestPerfTest.java
index 4891049..cde9d41 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindRequestPerfTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindRequestPerfTest.java
@@ -36,8 +36,7 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.controls.ControlImpl;
 import org.apache.directory.shared.ldap.message.BindRequest;
-import org.apache.directory.shared.ldap.message.BindRequestImpl;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.ldap.name.DN;
 import org.apache.directory.shared.util.Strings;
@@ -54,7 +53,7 @@
 public class BindRequestPerfTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new LdapEncoder();
 
 
     /**
@@ -178,7 +177,7 @@
         for ( int i = 0; i < nbLoops; i++ )
         {
             // Check the decoded BindRequest
-            BindRequest bindRequest = new BindRequestImpl( 1 );
+            BindRequest bindRequest = new org.apache.directory.shared.ldap.codec.message.BindRequestImpl( 1 );
 
             bindRequest.setSimple( true );
             bindRequest.setName( name );
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindRequestTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindRequestTest.java
index 17fd51d..7e7c92f 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindRequestTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindRequestTest.java
@@ -37,8 +37,8 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.ResponseCarryingException;
 import org.apache.directory.shared.ldap.message.BindRequest;
-import org.apache.directory.shared.ldap.message.BindResponseImpl;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.BindResponseImpl;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
@@ -55,7 +55,7 @@
 public class BindRequestTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindResponseTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindResponseTest.java
index e4d2a63..7be5c65 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindResponseTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/bind/BindResponseTest.java
@@ -37,7 +37,7 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.search.controls.pagedSearch.PagedResultsControl;
 import org.apache.directory.shared.ldap.message.BindResponse;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
@@ -53,7 +53,7 @@
 public class BindResponseTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/compare/CompareRequestTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/compare/CompareRequestTest.java
index d6ee119..14976c7 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/compare/CompareRequestTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/compare/CompareRequestTest.java
@@ -36,8 +36,7 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.ResponseCarryingException;
 import org.apache.directory.shared.ldap.message.CompareRequest;
-import org.apache.directory.shared.ldap.message.CompareResponseImpl;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
@@ -291,8 +290,8 @@
         {
             assertTrue( de instanceof ResponseCarryingException );
             Message response = ( ( ResponseCarryingException ) de ).getResponse();
-            assertTrue( response instanceof CompareResponseImpl );
-            assertEquals( ResultCodeEnum.INVALID_DN_SYNTAX, ( ( CompareResponseImpl ) response ).getLdapResult()
+            assertTrue( response instanceof org.apache.directory.shared.ldap.codec.message.CompareResponseImpl);
+            assertEquals( ResultCodeEnum.INVALID_DN_SYNTAX, ( (org.apache.directory.shared.ldap.codec.message.CompareResponseImpl) response ).getLdapResult()
                 .getResultCode() );
             return;
         }
@@ -339,8 +338,8 @@
         {
             assertTrue( de instanceof ResponseCarryingException );
             Message response = ( ( ResponseCarryingException ) de ).getResponse();
-            assertTrue( response instanceof CompareResponseImpl );
-            assertEquals( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, ( ( CompareResponseImpl ) response ).getLdapResult()
+            assertTrue( response instanceof org.apache.directory.shared.ldap.codec.message.CompareResponseImpl);
+            assertEquals( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, ( (org.apache.directory.shared.ldap.codec.message.CompareResponseImpl) response ).getLdapResult()
                 .getResultCode() );
             return;
         }
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/compare/CompareResponseTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/compare/CompareResponseTest.java
index 9c265d1..1fc3d7d 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/compare/CompareResponseTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/compare/CompareResponseTest.java
@@ -35,7 +35,6 @@
 import org.apache.directory.shared.asn1.EncoderException;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.message.CompareResponse;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
@@ -53,7 +52,7 @@
 public class CompareResponseTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/del/DelRequestTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/del/DelRequestTest.java
index f68e994..4661de1 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/del/DelRequestTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/del/DelRequestTest.java
@@ -36,9 +36,9 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.ResponseCarryingException;
 import org.apache.directory.shared.ldap.message.DeleteRequest;
-import org.apache.directory.shared.ldap.message.DeleteRequestImpl;
-import org.apache.directory.shared.ldap.message.DeleteResponseImpl;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.DeleteResponseImpl;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
@@ -57,7 +57,7 @@
 public class DelRequestTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new LdapEncoder();
 
 
     /**
@@ -105,7 +105,7 @@
         assertEquals( "cn=testModify,ou=users,ou=system", delRequest.getName().toString() );
 
         // Check the length
-        DeleteRequest internalDeleteRequest = new DeleteRequestImpl( delRequest.getMessageId() );
+        DeleteRequest internalDeleteRequest = new org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl( delRequest.getMessageId() );
         internalDeleteRequest.setName( delRequest.getName() );
 
         // Check the encoding
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/del/DelResponseTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/del/DelResponseTest.java
index b2d9c4b..c23b2c3 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/del/DelResponseTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/del/DelResponseTest.java
@@ -35,7 +35,7 @@
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.message.DeleteResponse;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
@@ -53,7 +53,7 @@
 public class DelResponseTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/ExtendedRequestTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/ExtendedRequestTest.java
index 01e7e11..262ae8b 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/ExtendedRequestTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/ExtendedRequestTest.java
@@ -35,7 +35,7 @@
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.message.ExtendedRequest;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
 import org.junit.Test;
@@ -52,7 +52,7 @@
 public class ExtendedRequestTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/ExtendedResponseTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/ExtendedResponseTest.java
index b3f3f7c..f4cec4e 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/ExtendedResponseTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/extended/ExtendedResponseTest.java
@@ -35,7 +35,7 @@
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.message.ExtendedResponse;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/intermediate/IntermediateResponseTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/intermediate/IntermediateResponseTest.java
index 910fa48..db0e8f0 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/intermediate/IntermediateResponseTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/intermediate/IntermediateResponseTest.java
@@ -35,7 +35,7 @@
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.message.IntermediateResponse;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
 import org.junit.Test;
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modify/ModifyRequestTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modify/ModifyRequestTest.java
index b71c76c..c39000b 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modify/ModifyRequestTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modify/ModifyRequestTest.java
@@ -39,10 +39,9 @@
 import org.apache.directory.shared.ldap.entry.EntryAttribute;
 import org.apache.directory.shared.ldap.entry.Modification;
 import org.apache.directory.shared.ldap.exception.LdapException;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.ModifyRequest;
-import org.apache.directory.shared.ldap.message.ModifyResponseImpl;
+import org.apache.directory.shared.ldap.codec.message.ModifyResponseImpl;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
@@ -60,7 +59,7 @@
 public class ModifyRequestTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
@@ -990,8 +989,8 @@
         {
             assertTrue( de instanceof ResponseCarryingException );
             Message response = ( ( ResponseCarryingException ) de ).getResponse();
-            assertTrue( response instanceof ModifyResponseImpl );
-            assertEquals( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, ( ( ModifyResponseImpl ) response ).getLdapResult()
+            assertTrue( response instanceof org.apache.directory.shared.ldap.codec.message.ModifyResponseImpl);
+            assertEquals( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, ( (org.apache.directory.shared.ldap.codec.message.ModifyResponseImpl) response ).getLdapResult()
                 .getResultCode() );
             return;
         }
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modify/ModifyResponseTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modify/ModifyResponseTest.java
index 73c5d21..98e5aeb 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modify/ModifyResponseTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modify/ModifyResponseTest.java
@@ -34,7 +34,7 @@
 import org.apache.directory.shared.asn1.ber.Asn1Decoder;
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.ModifyResponse;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
@@ -53,7 +53,7 @@
 public class ModifyResponseTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modifyDn/ModifyDNRequestTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modifyDn/ModifyDNRequestTest.java
index bb1fdc9..29f7f32 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modifyDn/ModifyDNRequestTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modifyDn/ModifyDNRequestTest.java
@@ -35,10 +35,10 @@
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.codec.ResponseCarryingException;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.ModifyDnRequest;
-import org.apache.directory.shared.ldap.message.ModifyDnResponseImpl;
+import org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
@@ -177,7 +177,7 @@
         {
             assertTrue( de instanceof ResponseCarryingException );
             Message response = ( ( ResponseCarryingException ) de ).getResponse();
-            assertTrue( response instanceof ModifyDnResponseImpl );
+            assertTrue( response instanceof org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl);
             assertEquals( ResultCodeEnum.INVALID_DN_SYNTAX, ( ( ModifyDnResponseImpl ) response ).getLdapResult()
                 .getResultCode() );
             return;
@@ -230,7 +230,7 @@
         {
             assertTrue( de instanceof ResponseCarryingException );
             Message response = ( ( ResponseCarryingException ) de ).getResponse();
-            assertTrue( response instanceof ModifyDnResponseImpl );
+            assertTrue( response instanceof org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl);
             assertEquals( ResultCodeEnum.INVALID_DN_SYNTAX, ( ( ModifyDnResponseImpl ) response ).getLdapResult()
                 .getResultCode() );
             return;
@@ -284,7 +284,7 @@
             assertTrue( de instanceof ResponseCarryingException );
             Message response = ( ( ResponseCarryingException ) de ).getResponse();
             assertTrue( response instanceof ModifyDnResponseImpl );
-            assertEquals( ResultCodeEnum.INVALID_DN_SYNTAX, ( ( ModifyDnResponseImpl ) response ).getLdapResult()
+            assertEquals( ResultCodeEnum.INVALID_DN_SYNTAX, ( (org.apache.directory.shared.ldap.codec.message.ModifyDnResponseImpl) response ).getLdapResult()
                 .getResultCode() );
             return;
         }
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modifyDn/ModifyDNResponseTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modifyDn/ModifyDNResponseTest.java
index 3565529..b7268a8 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modifyDn/ModifyDNResponseTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/modifyDn/ModifyDNResponseTest.java
@@ -34,7 +34,6 @@
 import org.apache.directory.shared.asn1.ber.Asn1Decoder;
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.ModifyDnResponse;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.control.Control;
@@ -53,7 +52,7 @@
 public class ModifyDNResponseTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestMatchingRuleAssertionTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestMatchingRuleAssertionTest.java
index 1e96afc..168482e 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestMatchingRuleAssertionTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestMatchingRuleAssertionTest.java
@@ -42,9 +42,8 @@
 import org.apache.directory.shared.ldap.constants.SchemaConstants;
 import org.apache.directory.shared.ldap.filter.SearchScope;
 import org.apache.directory.shared.ldap.message.AliasDerefMode;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
 import org.apache.directory.shared.ldap.schema.normalizers.DeepTrimToLowerNormalizer;
 import org.apache.directory.shared.ldap.schema.normalizers.OidNormalizer;
 import org.apache.directory.shared.util.Strings;
@@ -63,7 +62,7 @@
 public class SearchRequestMatchingRuleAssertionTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
     static Map<String, OidNormalizer> oids = new HashMap<String, OidNormalizer>();
 
@@ -407,7 +406,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // Extended
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         ExtensibleMatchFilter extensibleMatchFilter = ( ExtensibleMatchFilter ) filter;
         assertNotNull( extensibleMatchFilter );
 
@@ -707,7 +706,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // Extended
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         ExtensibleMatchFilter extensibleMatchFilter = ( ExtensibleMatchFilter ) filter;
         assertNotNull( extensibleMatchFilter );
 
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestSubstringTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestSubstringTest.java
index 8a5a50d..97a484b 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestSubstringTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestSubstringTest.java
@@ -40,9 +40,9 @@
 import org.apache.directory.shared.ldap.constants.SchemaConstants;
 import org.apache.directory.shared.ldap.filter.SearchScope;
 import org.apache.directory.shared.ldap.message.AliasDerefMode;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.ldap.schema.normalizers.DeepTrimToLowerNormalizer;
 import org.apache.directory.shared.ldap.schema.normalizers.OidNormalizer;
@@ -62,7 +62,7 @@
 public class SearchRequestSubstringTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
     static Map<String, OidNormalizer> oids = new HashMap<String, OidNormalizer>();
 
@@ -321,7 +321,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // (objectclass=t*)
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         SubstringFilter substringFilter = ( SubstringFilter ) filter;
         assertNotNull( substringFilter );
 
@@ -449,7 +449,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // (objectclass=t*)
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         SubstringFilter substringFilter = ( SubstringFilter ) filter;
         assertNotNull( substringFilter );
 
@@ -571,7 +571,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // (objectclass=t*)
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         SubstringFilter substringFilter = ( SubstringFilter ) filter;
         assertNotNull( substringFilter );
 
@@ -941,7 +941,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // (objectclass=t*)
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         SubstringFilter substringFilter = ( SubstringFilter ) filter;
         assertNotNull( substringFilter );
 
@@ -1064,7 +1064,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // (objectclass=t*)
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         SubstringFilter substringFilter = ( SubstringFilter ) filter;
         assertNotNull( substringFilter );
 
@@ -1329,7 +1329,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // (objectclass=t*)
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         SubstringFilter substringFilter = ( SubstringFilter ) filter;
         assertNotNull( substringFilter );
 
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestTest.java
index 521b40b..fb55a95 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchRequestTest.java
@@ -46,12 +46,12 @@
 import org.apache.directory.shared.ldap.constants.SchemaConstants;
 import org.apache.directory.shared.ldap.filter.SearchScope;
 import org.apache.directory.shared.ldap.message.AliasDerefMode;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.SearchRequest;
-import org.apache.directory.shared.ldap.message.SearchRequestImpl;
-import org.apache.directory.shared.ldap.message.SearchResultDoneImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.SearchResultDoneImpl;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.ldap.schema.normalizers.DeepTrimToLowerNormalizer;
 import org.apache.directory.shared.ldap.schema.normalizers.OidNormalizer;
@@ -72,7 +72,7 @@
 public class SearchRequestTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
     static Map<String, OidNormalizer> oids = new HashMap<String, OidNormalizer>();
 
@@ -685,7 +685,7 @@
         assertEquals( false, searchRequest.getTypesOnly() );
 
         // (objectClass = *)
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         PresentFilter presentFilter = ( PresentFilter ) filter;
         assertNotNull( presentFilter );
         assertEquals( "objectClass", presentFilter.getAttributeDescription() );
@@ -875,7 +875,7 @@
         assertEquals( false, searchRequest.getTypesOnly() );
 
         // (objectClass = *)
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         PresentFilter presentFilter = ( PresentFilter ) filter;
         assertNotNull( presentFilter );
         assertEquals( "objectClass", presentFilter.getAttributeDescription() );
@@ -1420,7 +1420,7 @@
         assertEquals( 0, searchRequest.getTimeLimit() );
         assertEquals( false, searchRequest.getTypesOnly() );
 
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         assertTrue( filter instanceof PresentFilter );
         assertEquals( "objectClass", ( ( PresentFilter ) filter ).getAttributeDescription() );
 
@@ -2722,7 +2722,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // >=
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         AttributeValueAssertionFilter greaterThanFilter = ( AttributeValueAssertionFilter ) filter;
         assertNotNull( greaterThanFilter );
 
@@ -2814,7 +2814,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // >=
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         AttributeValueAssertionFilter greaterThanFilter = ( AttributeValueAssertionFilter ) filter;
         assertNotNull( greaterThanFilter );
 
@@ -3772,7 +3772,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // (&(...
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         AndFilter andFilter = ( AndFilter ) filter;
         assertNotNull( andFilter );
 
@@ -3908,7 +3908,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // (&(...
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         AndFilter andFilter = ( AndFilter ) filter;
         assertNotNull( andFilter );
 
@@ -4054,7 +4054,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // (&(...
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         AndFilter andFilter = ( AndFilter ) filter;
         assertNotNull( andFilter );
 
@@ -4197,7 +4197,7 @@
         assertEquals( true, searchRequest.getTypesOnly() );
 
         // (&(...
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         AndFilter andFilter = ( AndFilter ) filter;
         assertNotNull( andFilter );
 
@@ -4598,7 +4598,7 @@
         assertEquals( 0, searchRequest.getTimeLimit() );
         assertEquals( false, searchRequest.getTypesOnly() );
 
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         PresentFilter presentFilter = ( PresentFilter ) filter;
         assertNotNull( presentFilter );
         assertEquals( "objectClass", presentFilter.getAttributeDescription() );
@@ -4777,7 +4777,7 @@
         assertEquals( false, searchRequest.getTypesOnly() );
 
         // (&(...
-        Filter filter = ( ( SearchRequestImpl ) searchRequest ).getCurrentFilter();
+        Filter filter = ( (org.apache.directory.shared.ldap.codec.message.SearchRequestImpl) searchRequest ).getCurrentFilter();
         AndFilter andFilter = ( AndFilter ) filter;
         assertNotNull( andFilter );
 
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultDoneTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultDoneTest.java
index 0e3eab1..06ea0c7 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultDoneTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultDoneTest.java
@@ -34,7 +34,6 @@
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.asn1.DecoderException;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.SearchResultDone;
 import org.apache.directory.shared.ldap.message.control.Control;
@@ -53,7 +52,7 @@
 public class SearchResultDoneTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new org.apache.directory.shared.ldap.codec.message.LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultEntryTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultEntryTest.java
index 62c2a95..1006e3c 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultEntryTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultEntryTest.java
@@ -38,7 +38,7 @@
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
 import org.apache.directory.shared.ldap.entry.Entry;
 import org.apache.directory.shared.ldap.entry.EntryAttribute;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.SearchResultEntry;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
@@ -56,7 +56,7 @@
 public class SearchResultEntryTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new LdapEncoder();
 
 
     /**
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultReferenceTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultReferenceTest.java
index 52c2de3..28a999d 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultReferenceTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/search/SearchResultReferenceTest.java
@@ -37,7 +37,7 @@
 import org.apache.directory.shared.asn1.ber.Asn1Decoder;
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.Referral;
 import org.apache.directory.shared.ldap.message.SearchResultReference;
 import org.apache.directory.shared.ldap.message.control.Control;
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/unbind/UnBindRequestTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/unbind/UnBindRequestTest.java
index c234839..766272c 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/codec/unbind/UnBindRequestTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/codec/unbind/UnBindRequestTest.java
@@ -34,9 +34,9 @@
 import org.apache.directory.shared.asn1.ber.Asn1Container;
 import org.apache.directory.shared.asn1.EncoderException;
 import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
-import org.apache.directory.shared.ldap.message.LdapEncoder;
+import org.apache.directory.shared.ldap.codec.message.LdapEncoder;
 import org.apache.directory.shared.ldap.message.UnbindRequest;
-import org.apache.directory.shared.ldap.message.UnbindRequestImpl;
+import org.apache.directory.shared.ldap.codec.message.UnbindRequestImpl;
 import org.apache.directory.shared.ldap.message.control.Control;
 import org.apache.directory.shared.util.Strings;
 import org.junit.Test;
@@ -51,7 +51,7 @@
 public class UnBindRequestTest
 {
     /** The encoder instance */
-    LdapEncoder encoder = new LdapEncoder();
+    org.apache.directory.shared.ldap.codec.message.LdapEncoder encoder = new LdapEncoder();
 
 
     /**