You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2018/12/10 00:32:41 UTC

[directory-ldap-api] branch master updated: o Added the EndTransacytionResponse reverse encoding o Decoding controls when processing their values

This is an automated email from the ASF dual-hosted git repository.

elecharny pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/directory-ldap-api.git


The following commit(s) were added to refs/heads/master by this push:
     new 3994466  o Added the EndTransacytionResponse reverse encoding o Decoding controls when processing their values
3994466 is described below

commit 39944664af4ed014e32b98384384572c80cd0de1
Author: elecharny <el...@emmanuels-mbp>
AuthorDate: Mon Dec 10 01:32:39 2018 +0100

    o Added the EndTransacytionResponse reverse encoding
    o Decoding controls when processing their values
---
 .../endTransaction/EndTransactionFactory.java      |  95 ++++++++
 .../endTransaction/controls/ControlsContainer.java |  26 ++-
 .../controls/actions/AddControl.java               |   3 +
 .../controls/actions/StoreControlValue.java        |  11 +-
 .../api/ldap/extras/AbstractCodecServiceTest.java  |   3 +-
 .../endTransaction/EndTransactionResponseTest.java | 253 +++++++++++++--------
 6 files changed, 297 insertions(+), 94 deletions(-)

diff --git a/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/EndTransactionFactory.java b/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/EndTransactionFactory.java
index 16b63b1..4540b80 100644
--- a/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/EndTransactionFactory.java
+++ b/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/EndTransactionFactory.java
@@ -20,10 +20,14 @@
 package org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction;
 
 
+import java.util.Iterator;
+
 import org.apache.directory.api.asn1.DecoderException;
 import org.apache.directory.api.asn1.ber.tlv.BerValue;
+import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
 import org.apache.directory.api.asn1.util.Asn1Buffer;
 import org.apache.directory.api.ldap.codec.api.AbstractExtendedOperationFactory;
+import org.apache.directory.api.ldap.codec.api.ControlFactory;
 import org.apache.directory.api.ldap.codec.api.ExtendedOperationFactory;
 import org.apache.directory.api.ldap.codec.api.LdapApiService;
 import org.apache.directory.api.ldap.codec.decorators.ExtendedResponseDecorator;
@@ -31,6 +35,8 @@ import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransacti
 import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionRequestImpl;
 import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionResponse;
 import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionResponseImpl;
+import org.apache.directory.api.ldap.extras.extended.endTransaction.UpdateControls;
+import org.apache.directory.api.ldap.model.message.Control;
 import org.apache.directory.api.ldap.model.message.ExtendedRequest;
 import org.apache.directory.api.ldap.model.message.ExtendedResponse;
 
@@ -158,4 +164,93 @@ public class EndTransactionFactory extends AbstractExtendedOperationFactory
         // The sequence
         BerValue.encodeSequence( buffer, start );
     }
+    
+    
+    private void encodeControls( Asn1Buffer buffer, Iterator<Control> controls )
+    {
+        if ( controls.hasNext() )
+        {
+            Control control = controls.next();
+            
+            encodeControls( buffer, controls );
+
+            int start = buffer.getPos();
+            
+            // The control value, if any
+            ControlFactory<?> controlFactory = codec.getResponseControlFactories().get( control.getOid() );
+            
+            if ( controlFactory != null )
+            {
+                controlFactory.encodeValue( buffer, control );
+                
+                // The value sequence
+                BerValue.encodeSequence( buffer, UniversalTag.OCTET_STRING.getValue(), start );
+            }
+            
+            // The control criticality of TRUE
+            if ( control.isCritical() )
+            {
+                BerValue.encodeBoolean( buffer, true );
+            }
+            
+            // The control oid
+            BerValue.encodeOctetString( buffer, control.getOid() );
+            
+            // The control sequence
+            BerValue.encodeSequence( buffer, start );
+        }
+    } 
+    
+    
+    private void encodeUpdatedControls( Asn1Buffer buffer, Iterator<UpdateControls> updateControls )
+    {
+        if ( updateControls.hasNext() )
+        {
+            UpdateControls updateControl = updateControls.next();
+            
+            encodeUpdatedControls( buffer, updateControls );
+
+            int start = buffer.getPos();
+            
+            // The controls
+            encodeControls( buffer, updateControl.getControls().iterator() );
+            
+            // The controls sequence
+            BerValue.encodeSequence( buffer, start );
+            
+            // The messageID
+            BerValue.encodeInteger( buffer, updateControl.getMessageId() );
+
+            // The sequence
+            BerValue.encodeSequence( buffer, start );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void encodeValue( Asn1Buffer buffer, ExtendedResponse extendedResponse )
+    {
+        int start  = buffer.getPos();
+        EndTransactionResponse endTransactionResponse = ( EndTransactionResponse ) extendedResponse;
+        
+        // The controls
+        if ( endTransactionResponse.getUpdateControls().size() > 0 )
+        {
+            encodeUpdatedControls( buffer, endTransactionResponse.getUpdateControls().iterator() );
+            
+            BerValue.encodeSequence( buffer, start );
+        }
+        
+        // The messageID flag, if false
+        if ( endTransactionResponse.getMessageId() >= 0 )
+        {
+            BerValue.encodeInteger( buffer, endTransactionResponse.getMessageId() );
+        }
+        
+        // The sequence
+        BerValue.encodeSequence( buffer, start );
+    }
 }
diff --git a/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/ControlsContainer.java b/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/ControlsContainer.java
index 3d9d748..30ddd71 100644
--- a/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/ControlsContainer.java
+++ b/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/ControlsContainer.java
@@ -24,8 +24,9 @@ import java.util.List;
 
 import org.apache.directory.api.asn1.ber.AbstractContainer;
 import org.apache.directory.api.ldap.codec.api.CodecControl;
+import org.apache.directory.api.ldap.codec.api.ControlFactory;
 import org.apache.directory.api.ldap.codec.api.LdapApiService;
-import org.apache.directory.api.ldap.codec.osgi.DefaultLdapCodecService;
+import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
 import org.apache.directory.api.ldap.model.message.Control;
 
 /**
@@ -40,6 +41,9 @@ public class ControlsContainer extends AbstractContainer
     
     /** The current control */
     private CodecControl<?> currentControl;
+    
+    /** The control factory */
+    private ControlFactory<?> factory;
 
     /** The codec service */
     private final LdapApiService codec;
@@ -52,7 +56,7 @@ public class ControlsContainer extends AbstractContainer
         super();
         setGrammar( ControlsGrammar.getInstance() );
         setTransition( ControlsStates.START_STATE );
-        this.codec = new DefaultLdapCodecService();
+        this.codec = LdapApiServiceFactory.getSingleton();
     }
 
 
@@ -101,4 +105,22 @@ public class ControlsContainer extends AbstractContainer
     {
         controls.add( control );
     }
+
+
+    /**
+     * @return the factory
+     */
+    public ControlFactory<?> getFactory()
+    {
+        return factory;
+    }
+
+
+    /**
+     * @param factory the factory to set
+     */
+    public void setFactory( ControlFactory<?> factory )
+    {
+        this.factory = factory;
+    }
 }
diff --git a/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/actions/AddControl.java b/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/actions/AddControl.java
index 9711a2b..a1b9186 100644
--- a/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/actions/AddControl.java
+++ b/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/actions/AddControl.java
@@ -26,6 +26,7 @@ import org.apache.directory.api.asn1.ber.tlv.TLV;
 import org.apache.directory.api.asn1.util.Oid;
 import org.apache.directory.api.i18n.I18n;
 import org.apache.directory.api.ldap.codec.api.CodecControl;
+import org.apache.directory.api.ldap.codec.api.ControlFactory;
 import org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction.controls.ControlsContainer;
 import org.apache.directory.api.util.Strings;
 import org.slf4j.Logger;
@@ -88,6 +89,8 @@ public class AddControl extends GrammarAction<ControlsContainer>
             throw new DecoderException( msg );
         }
 
+        ControlFactory<?> factory = container.getLdapCodecService().getResponseControlFactories().get( oidValue );
+        container.setFactory( factory );
         CodecControl<?> control = container.getLdapCodecService().newResponseControl( oidValue );
 
         container.setCurrentControl( control );
diff --git a/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/actions/StoreControlValue.java b/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/actions/StoreControlValue.java
index d668dfa..8439ef7 100644
--- a/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/actions/StoreControlValue.java
+++ b/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/controls/actions/StoreControlValue.java
@@ -20,6 +20,7 @@
 package org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction.controls.actions;
 
 
+import org.apache.directory.api.asn1.DecoderException;
 import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
 import org.apache.directory.api.asn1.ber.tlv.BerValue;
 import org.apache.directory.api.asn1.ber.tlv.TLV;
@@ -77,7 +78,15 @@ public class StoreControlValue extends GrammarAction<ControlsContainer>
         }
         else
         {
-            control.setValue( value.getData() );
+            try
+            {
+                control.decode( value.getData() );
+            }
+            catch ( DecoderException e )
+            {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
         }
 
         // We can have an END transition
diff --git a/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/AbstractCodecServiceTest.java b/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/AbstractCodecServiceTest.java
index 7ee5f06..6d55c98 100644
--- a/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/AbstractCodecServiceTest.java
+++ b/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/AbstractCodecServiceTest.java
@@ -1,6 +1,7 @@
 package org.apache.directory.api.ldap.extras;
 
 
+import org.apache.directory.api.ldap.codec.api.LdapApiService;
 import org.apache.directory.api.ldap.codec.osgi.DefaultLdapCodecService;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -13,7 +14,7 @@ import org.junit.BeforeClass;
  */
 public abstract class AbstractCodecServiceTest
 {
-    protected static DefaultLdapCodecService codec;
+    protected static LdapApiService codec;
 
 
     /**
diff --git a/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/EndTransactionResponseTest.java b/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/EndTransactionResponseTest.java
index 57339bc..2bb000f 100644
--- a/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/EndTransactionResponseTest.java
+++ b/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/extended/ads_impl/endTransaction/EndTransactionResponseTest.java
@@ -20,6 +20,7 @@
 package org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction;
 
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -32,11 +33,22 @@ import java.nio.ByteBuffer;
 import org.apache.directory.api.asn1.DecoderException;
 import org.apache.directory.api.asn1.EncoderException;
 import org.apache.directory.api.asn1.ber.Asn1Decoder;
-import org.apache.directory.api.ldap.codec.api.CodecControl;
+import org.apache.directory.api.asn1.util.Asn1Buffer;
+import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
+import org.apache.directory.api.ldap.extras.AbstractCodecServiceTest;
+import org.apache.directory.api.ldap.extras.controls.syncrepl.syncDone.SyncDoneValue;
+import org.apache.directory.api.ldap.extras.controls.syncrepl.syncState.SyncStateTypeEnum;
+import org.apache.directory.api.ldap.extras.controls.syncrepl.syncState.SyncStateValue;
+import org.apache.directory.api.ldap.extras.controls.syncrepl_impl.SyncDoneValueFactory;
+import org.apache.directory.api.ldap.extras.controls.syncrepl_impl.SyncStateValueFactory;
 import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionResponse;
 import org.apache.directory.api.ldap.extras.extended.endTransaction.UpdateControls;
 import org.apache.directory.api.ldap.model.message.Control;
+import org.apache.directory.api.ldap.model.message.controls.PagedResults;
+import org.apache.directory.api.ldap.model.message.controls.SortResponse;
+import org.apache.directory.api.ldap.model.message.controls.SortResultCode;
 import org.apache.directory.api.util.Strings;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -51,8 +63,22 @@ import com.mycila.junit.concurrent.ConcurrentJunitRunner;
  */
 @RunWith(ConcurrentJunitRunner.class)
 @Concurrency()
-public class EndTransactionResponseTest
+public class EndTransactionResponseTest extends AbstractCodecServiceTest
 {
+    static
+    {
+        LdapApiServiceFactory.initialize( codec );
+    }
+    
+    @Before
+    public void init()
+    {
+        codec = LdapApiServiceFactory.getSingleton();
+        codec.registerResponseControl( new SyncDoneValueFactory( codec ) );
+        codec.registerResponseControl( new SyncStateValueFactory( codec ) );
+    }
+    
+    
     /**
      * Test the decoding of a EndTransactionResponse with nothing in it
      */
@@ -62,7 +88,8 @@ public class EndTransactionResponseTest
         Asn1Decoder decoder = new Asn1Decoder();
         ByteBuffer bb = ByteBuffer.allocate( 0x02 );
         bb.put( new byte[]
-            { 0x30, 0x00, // EndTransactionResponse ::= SEQUENCE {
+            { 
+                0x30, 0x00, // EndTransactionResponse ::= SEQUENCE {
             } );
         
         bb.flip();
@@ -82,23 +109,15 @@ public class EndTransactionResponseTest
         Asn1Decoder decoder = new Asn1Decoder();
         ByteBuffer bb = ByteBuffer.allocate( 0x05 );
         bb.put( new byte[]
-            { 0x30, 0x03,              // EndTransactionResponse ::= SEQUENCE {
-                0x02, 0x01, 0x04       // MessageId
-        } );
+            { 
+                0x30, 0x03,              // EndTransactionResponse ::= SEQUENCE {
+                  0x02, 0x01, 0x04       // MessageId
+            } );
 
-        String decodedPdu = Strings.dumpBytes( bb.array() );
         bb.flip();
         EndTransactionResponseContainer container = new EndTransactionResponseContainer();
 
-        try
-        {
-            decoder.decode( bb, container );
-        }
-        catch ( DecoderException de )
-        {
-            de.printStackTrace();
-            fail( de.getMessage() );
-        }
+        decoder.decode( bb, container );
         
         EndTransactionResponse endTransactionResponse = container.getEndTransactionResponse();
         assertEquals( 4, endTransactionResponse.getFailedMessageId() );
@@ -110,9 +129,7 @@ public class EndTransactionResponseTest
         // Check the encoding
         ByteBuffer bb1 = ( ( EndTransactionResponseDecorator ) endTransactionResponse ).encodeInternal();
 
-        String encodedPdu = Strings.dumpBytes( bb1.array() );
-
-        assertEquals( encodedPdu, decodedPdu );
+        assertArrayEquals( bb.array(), bb1.array() );
     }
 
 
@@ -123,62 +140,95 @@ public class EndTransactionResponseTest
     public void testEndTransactionResponseUpdateControls() throws DecoderException, EncoderException
     {
         Asn1Decoder decoder = new Asn1Decoder();
-        ByteBuffer bb = ByteBuffer.allocate( 0xAC );
+        ByteBuffer bb = ByteBuffer.allocate( 0x12D );
         bb.put( new byte[]
-            { 0x30, (byte)0x81, (byte)0xA9,         // EndTransactionResponse ::= SEQUENCE {
-                0x30, (byte)0x81, (byte)0xA6,       // UpdateControls
-                  0x30, 0x5F,                       // updateControl
-                    0x02, 0x01, 0x01,               // messageID
-                    0x30, 0x5A,                     // controls 
-                      0x30, 0x1A,                   // Control ::= SEQUENCE {
-                        0x04, 0x0D,                 // controlType LDAPOID,
-                          '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '1',
-                        0x01, 0x01, ( byte ) 0xFF,  // criticality BOOLEAN DEFAULT FALSE, 
-                        0x04, 0x06,                 // controlValue OCTET STRING OPTIONAL }
-                          'a', 'b', 'c', 'd', 'e', 'f',
-                      0x30, 0x17,                   // Control ::= SEQUENCE {
-                        0x04, 0x0D,                 // controlType LDAPOID,
-                          '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '2',
-                        0x04, 0x06,                 // controlValue OCTET STRING OPTIONAL }
-                          'g', 'h', 'i', 'j', 'k', 'l',
-                      0x30, 0x12,                   // Control ::= SEQUENCE {
-                        0x04, 0x0D,                 // controlType LDAPOID,
-                          '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '3',
-                        0x01, 0x01, ( byte ) 0xFF,  // criticality BOOLEAN DEFAULT FALSE}
-                      0x30, 0x0F,                   // Control ::= SEQUENCE {
-                        0x04, 0x0D,                 // controlType LDAPOID}
-                          '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '4',
-                  0x30, 0x43,                       // updateControl
-                    0x02, 0x01, 0x02,               // messageID
-                    0x30, 0x3E,                     // controls 
-                      0x30, 0x17,                   // Control ::= SEQUENCE {
-                        0x04, 0x0D,                 // controlType LDAPOID,
-                          '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '2',
-                        0x04, 0x06,                 // controlValue OCTET STRING OPTIONAL }
-                          'g', 'h', 'i', 'j', 'k', 'l',
-                      0x30, 0x12,                   // Control ::= SEQUENCE {
-                        0x04, 0x0D,                 // controlType LDAPOID,
-                          '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '3',
-                        0x01, 0x01, ( byte ) 0xFF,  // criticality BOOLEAN DEFAULT FALSE}
-                      0x30, 0x0F,                   // Control ::= SEQUENCE {
-                        0x04, 0x0D,                 // controlType LDAPOID}
-                          '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '4' 
-
+            { 
+                0x30, (byte)0x82, 0x01, 0x29,         // EndTransactionResponse ::= SEQUENCE {
+                  0x30, (byte)0x82, 0x01, 0x25,       // UpdateControls
+                    0x30, (byte)0x81, (byte)0xA5,     // updateControl
+                      0x02, 0x01, 0x01,               // messageID
+                      0x30, (byte)0x81, (byte)0x9F,   // controls 
+                        0x30, 0x26,                   // Control ::= SEQUENCE {
+                          0x04, 0x16,                 // controlType LDAPOID,
+                                                      // PagedResults
+                            '1', '.', '2', '.', '8', '4', '0', '.', 
+                            '1', '1', '3', '5', '5', '6', '.', '1', '.', '4', '.', '3', '1', '9',
+                          0x01, 0x01, ( byte ) 0xFF,  // criticality BOOLEAN DEFAULT FALSE, 
+                          0x04, 0x09,                 // controlValue OCTET STRING OPTIONAL }
+                            0x30, 0x07,
+                              0x02, 0x01, 0x01,
+                              0x04, 0x02,
+                                'a', 'b',
+                        0x30, 0x23,                   // Control ::= SEQUENCE {
+                          0x04, 0x16,                 // controlType LDAPOID,
+                                                      // SortResponse
+                            '1', '.', '2', '.', '8', '4', '0', '.', 
+                            '1', '1', '3', '5', '5', '6', '.', '1', '.', '4', '.', '4', '7', '4',
+                          0x04, 0x09,                 // controlValue OCTET STRING OPTIONAL }
+                            0x30, 0x07,
+                              0x0A, 0x01, 0x08,
+                              (byte)0x80, 0x02,
+                                'c', 'n',
+                        0x30, 0x27,                   // Control ::= SEQUENCE {
+                          0x04, 0x18,                 // controlType LDAPOID,
+                                                      // SyncDoneValue
+                            '1', '.', '3', '.', '6', '.', '1', '.', '4', '.', '1', '.', 
+                            '4', '2', '0', '3', '.', '1', '.', '9', '.', '1', '.', '3',
+                          0x01, 0x01, ( byte ) 0xFF,  // criticality BOOLEAN DEFAULT FALSE}
+                          0x04, 0x08,
+                            0x30, 0x06,
+                              0x04, 0x04,
+                               't', 't', 't', 't',
+                        0x30, 0x27,                   // Control ::= SEQUENCE {
+                          0x04, 0x18,                 // controlType LDAPOID}
+                                                      // SyncStateValue
+                            '1', '.', '3', '.', '6', '.', '1', '.', '4', '.', 
+                            '1', '.', '4', '2', '0', '3', '.', '1', '.', '9', '.', '1', '.', '2',
+                          0x04, 0x0B,                 // ControlValue  OCTET STRING OPTIONAL }
+                            0x30, 0x09,
+                              0x0A, 0x01, 0x01,       // Add
+                              0x04, 0x04,
+                                'a', 'b', 'c', 'd',   // EntryUUID
+                    0x30, 0x7B,                       // updateControl
+                      0x02, 0x01, 0x02,               // messageID
+                      0x30, 0x76,                     // controls 
+                        0x30, 0x26,                   // Control ::= SEQUENCE {
+                          0x04, 0x16,                 // controlType LDAPOID,
+                                                      // PagedResults
+                            '1', '.', '2', '.', '8', '4', '0', '.', 
+                            '1', '1', '3', '5', '5', '6', '.', '1', '.', '4', '.', '3', '1', '9',
+                          0x01, 0x01, ( byte ) 0xFF,  // criticality BOOLEAN DEFAULT FALSE, 
+                          0x04, 0x09,                 // controlValue OCTET STRING OPTIONAL }
+                            0x30, 0x07,
+                              0x02, 0x01, 0x01,
+                              0x04, 0x02,
+                                'a', 'b',
+                        0x30, 0x23,                   // Control ::= SEQUENCE {
+                          0x04, 0x16,                 // controlType LDAPOID,
+                                                      // SortResponse
+                            '1', '.', '2', '.', '8', '4', '0', '.', 
+                            '1', '1', '3', '5', '5', '6', '.', '1', '.', '4', '.', '4', '7', '4',
+                          0x04, 0x09,                 // controlValue OCTET STRING OPTIONAL }
+                            0x30, 0x07,
+                              0x0A, 0x01, 0x08,
+                              (byte)0x80, 0x02,
+                                'c', 'n',
+                        0x30, 0x27,                   // Control ::= SEQUENCE {
+                          0x04, 0x18,                 // controlType LDAPOID,
+                                                      // SyncDoneValue
+                            '1', '.', '3', '.', '6', '.', '1', '.', '4', '.', '1', '.', 
+                            '4', '2', '0', '3', '.', '1', '.', '9', '.', '1', '.', '3',
+                          0x01, 0x01, ( byte ) 0xFF,  // criticality BOOLEAN DEFAULT FALSE}
+                          0x04, 0x08,
+                            0x30, 0x06,
+                              0x04, 0x04,
+                               't', 't', 't', 't',
         } );
 
-        String decodedPdu = Strings.dumpBytes( bb.array() );
         bb.flip();
         EndTransactionResponseContainer container = new EndTransactionResponseContainer();
 
-        try
-        {
-            decoder.decode( bb, container );
-        }
-        catch ( DecoderException de )
-        {
-            de.printStackTrace();
-            fail( de.getMessage() );
-        }
+        decoder.decode( bb, container );
         
         EndTransactionResponse endTransactionResponse = container.getEndTransactionResponse();
         assertEquals( -1, endTransactionResponse.getFailedMessageId() );
@@ -193,24 +243,36 @@ public class EndTransactionResponseTest
         {
             switch ( control.getOid() )
             {
-                case "1.3.6.1.5.5.1" :
+                case "1.2.840.113556.1.4.319" :
                     assertTrue( control.isCritical() );
-                    assertEquals( "abcdef", Strings.utf8ToString( ( ( CodecControl<?> ) control ).getValue() ) );
+                    assertTrue( control instanceof PagedResults );
+                    PagedResults pagedResults = ( PagedResults ) control;
+                    assertEquals( 1, pagedResults.getSize() );
+                    assertEquals( "ab", Strings.utf8ToString( pagedResults.getCookie() ) );
                     break;
                     
-                case "1.3.6.1.5.5.2" :
+                case "1.2.840.113556.1.4.474" :
                     assertFalse( control.isCritical() );
-                    assertEquals( "ghijkl", Strings.utf8ToString( ( ( CodecControl<?> ) control ).getValue() ) );
+                    assertTrue( control instanceof SortResponse );
+                    SortResponse sortResponse = ( SortResponse ) control;
+                    assertEquals( SortResultCode.STRONGAUTHREQUIRED, sortResponse.getSortResult() );
+                    assertEquals( "cn", sortResponse.getAttributeName() );
                     break;
                     
-                case "1.3.6.1.5.5.3" :
+                case "1.3.6.1.4.1.4203.1.9.1.3" :
                     assertTrue( control.isCritical() );
-                    assertNull( ( ( CodecControl<?> ) control ).getValue() );
+                    assertTrue( control instanceof SyncDoneValue );
+                    SyncDoneValue syncDoneValue = ( SyncDoneValue ) control;
+                    assertEquals( "tttt", Strings.utf8ToString( syncDoneValue.getCookie() ) );
                     break;
                     
-                case "1.3.6.1.5.5.4" :
+                case "1.3.6.1.4.1.4203.1.9.1.2" :
                     assertFalse( control.isCritical() );
-                    assertNull( ( ( CodecControl<?> ) control ).getValue() );
+                    assertTrue( control instanceof SyncStateValue );
+                    SyncStateValue syncStateValue = ( SyncStateValue ) control;
+                    assertEquals( SyncStateTypeEnum.ADD, syncStateValue.getSyncStateType() );
+                    assertEquals( "abcd", Strings.utf8ToString( syncStateValue.getEntryUUID() ) );
+                    assertNull( syncStateValue.getCookie() );
                     break;
                     
                 default :
@@ -228,19 +290,26 @@ public class EndTransactionResponseTest
         {
             switch ( control.getOid() )
             {
-                case "1.3.6.1.5.5.2" :
-                    assertFalse( control.isCritical() );
-                    assertEquals( "ghijkl", Strings.utf8ToString( ( ( CodecControl<?> ) control ).getValue() ) );
-                    break;
-                    
-                case "1.3.6.1.5.5.3" :
+                case "1.2.840.113556.1.4.319" :
                     assertTrue( control.isCritical() );
-                    assertNull( ( ( CodecControl<?> ) control ).getValue() );
+                    assertTrue( control instanceof PagedResults );
+                    PagedResults pagedResults = ( PagedResults ) control;
+                    assertEquals( 1, pagedResults.getSize() );
+                    assertEquals( "ab", Strings.utf8ToString( pagedResults.getCookie() ) );
                     break;
                     
-                case "1.3.6.1.5.5.4" :
+                case "1.2.840.113556.1.4.474" :
                     assertFalse( control.isCritical() );
-                    assertNull( ( ( CodecControl<?> ) control ).getValue() );
+                    assertTrue( control instanceof SortResponse );
+                    SortResponse sortResponse = ( SortResponse ) control;
+                    assertEquals( SortResultCode.STRONGAUTHREQUIRED, sortResponse.getSortResult() );
+                    assertEquals( "cn", sortResponse.getAttributeName() );
+                    break;
+                    
+                case "1.3.6.1.4.1.4203.1.9.1.3" :
+                    assertTrue( control.isCritical() );
+                    SyncDoneValue syncDoneValue = ( SyncDoneValue ) control;
+                    assertEquals( "tttt", Strings.utf8ToString( syncDoneValue.getCookie() ) );
                     break;
                     
                 default :
@@ -250,13 +319,17 @@ public class EndTransactionResponseTest
         }
 
         // Check the length
-        assertEquals( 0xAC, ( ( EndTransactionResponseDecorator ) endTransactionResponse ).computeLengthInternal() );
+        assertEquals( 0x12D, ( ( EndTransactionResponseDecorator ) endTransactionResponse ).computeLengthInternal() );
 
         // Check the encoding
         ByteBuffer bb1 = ( ( EndTransactionResponseDecorator ) endTransactionResponse ).encodeInternal();
 
-        String encodedPdu = Strings.dumpBytes( bb1.array() );
-
-        assertEquals( encodedPdu, decodedPdu );
+        assertArrayEquals( bb.array(), bb1.array() );
+        
+        // Check the reverse decoding
+        Asn1Buffer asn1Buffer = new Asn1Buffer();
+        EndTransactionFactory factory = new EndTransactionFactory( codec );
+        factory.encodeValue( asn1Buffer, endTransactionResponse );
+        assertArrayEquals( bb.array(), asn1Buffer.getBytes().array() );
     }
 }