directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1031354 [2/4] - in /directory/apacheds/trunk/kerberos-codec: ./ .settings/ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/directory/ src/main/java/org/apache/directory/shared/ src/main/j...
Date Thu, 04 Nov 2010 23:48:50 GMT
Added: directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/codec/KerberosMessageGrammar.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/codec/KerberosMessageGrammar.java?rev=1031354&view=auto
==============================================================================
--- directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/codec/KerberosMessageGrammar.java (added)
+++ directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/codec/KerberosMessageGrammar.java Thu Nov  4 23:48:49 2010
@@ -0,0 +1,6681 @@
+/*
+ *  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.kerberos.codec;
+
+
+import org.apache.directory.shared.asn1.ber.Asn1Container;
+import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar;
+import org.apache.directory.shared.asn1.ber.grammar.Grammar;
+import org.apache.directory.shared.asn1.ber.grammar.GrammarAction;
+import org.apache.directory.shared.asn1.ber.grammar.GrammarTransition;
+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.codec.DecoderException;
+import org.apache.directory.shared.asn1.util.IntegerDecoder;
+import org.apache.directory.shared.asn1.util.IntegerDecoderException;
+import org.apache.directory.shared.i18n.I18n;
+import org.apache.directory.shared.kerberos.KerberosConstants;
+import org.apache.directory.shared.kerberos.messages.Ticket;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This class implements the KerberosMessage message. All the actions are declared
+ * in this class. As it is a singleton, these declaration are only done once. If
+ * an action is to be added or modified, this is where the work is to be done !
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public final class KerberosMessageGrammar extends AbstractGrammar
+{
+    /** The logger */
+    static final Logger LOG = LoggerFactory.getLogger( KerberosMessageGrammar.class );
+
+    /** A speedup for logger */
+    static final boolean IS_DEBUG = LOG.isDebugEnabled();
+
+    /** The instance of grammar. KerberosMessageGrammar is a singleton */
+    private static Grammar instance = new KerberosMessageGrammar();
+
+
+    /**
+     * Creates a new KerberosMessageGrammar object.
+     */
+    private KerberosMessageGrammar()
+    {
+        setName( KerberosMessageGrammar.class.getName() );
+
+        // Create the transitions table
+        super.transitions = new GrammarTransition[KerberosStatesEnum.LAST_KERBEROS_STATE.ordinal()][256];
+
+        // ============================================================================================
+        // Transition from START to Ticket
+        // ============================================================================================
+        // This is the starting state :
+        // Ticket          ::= [APPLICATION 1] ... 
+        super.transitions[KerberosStatesEnum.START_STATE.ordinal()][KerberosConstants.TICKET_TAG] = new GrammarTransition(
+            KerberosStatesEnum.START_STATE, KerberosStatesEnum.TICKET_STATE, KerberosConstants.TICKET_TAG,
+            new GrammarAction( "Kerberos Ticket initialization" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    KerberosMessageContainer kerberosMessageContainer = ( KerberosMessageContainer ) container;
+
+                    TLV tlv = kerberosMessageContainer.getCurrentTLV();
+
+                    // The Length should not be null
+                    if ( tlv.getLength() == 0 )
+                    {
+                        LOG.error( I18n.err( I18n.ERR_04066 ) );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( I18n.err( I18n.ERR_04067 ) );
+                    }
+                    
+                    // Create the Ticket now
+                    Ticket ticket = new Ticket();
+                    
+                    kerberosMessageContainer.setMessage( ticket );
+                }
+            } );
+
+        // ============================================================================================
+        // Transition from Ticket to Ticket-SEQ
+        // ============================================================================================
+        // Ticket          ::= [APPLICATION 1] SEQUENCE { 
+        super.transitions[KerberosStatesEnum.TICKET_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition(
+            KerberosStatesEnum.TICKET_STATE, KerberosStatesEnum.TICKET_SEQ_STATE, UniversalTag.SEQUENCE.getValue(),
+            new GrammarAction( "Kerberos Ticket sequence" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    KerberosMessageContainer kerberosMessageContainer = ( KerberosMessageContainer ) container;
+
+                    TLV tlv = kerberosMessageContainer.getCurrentTLV();
+
+                    // The Length should not be null
+                    if ( tlv.getLength() == 0 )
+                    {
+                        LOG.error( I18n.err( I18n.ERR_04066 ) );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( I18n.err( I18n.ERR_04067 ) );
+                    }
+                }
+            } );
+
+        // ============================================================================================
+        // Transition from Ticket-SEQ to tkt-vno tag
+        // ============================================================================================
+        // Ticket          ::= [APPLICATION 1] SEQUENCE { 
+        //         tkt-vno         [0] 
+        super.transitions[KerberosStatesEnum.TICKET_SEQ_STATE.ordinal()][KerberosConstants.TICKET_TKT_VNO_TAG] = new GrammarTransition(
+            KerberosStatesEnum.TICKET_SEQ_STATE, KerberosStatesEnum.TICKET_VNO_TAG_STATE, KerberosConstants.TICKET_TKT_VNO_TAG,
+            new GrammarAction( "Kerberos Ticket tktvno tag" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    KerberosMessageContainer kerberosMessageContainer = ( KerberosMessageContainer ) container;
+
+                    TLV tlv = kerberosMessageContainer.getCurrentTLV();
+
+                    // The Length should not be null
+                    if ( tlv.getLength() == 0 )
+                    {
+                        LOG.error( I18n.err( I18n.ERR_04066 ) );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( I18n.err( I18n.ERR_04067 ) );
+                    }
+                }
+            } );
+
+        // ============================================================================================
+        // Transition from tkt-vno tag to tkt-vno 
+        // ============================================================================================
+        // Ticket          ::= [APPLICATION 1] SEQUENCE { 
+        //         tkt-vno         [0] INTEGER (5),
+        super.transitions[KerberosStatesEnum.TICKET_VNO_TAG_STATE.ordinal()][UniversalTag.INTEGER.getValue()] = new GrammarTransition(
+            KerberosStatesEnum.TICKET_VNO_TAG_STATE, KerberosStatesEnum.TICKET_VNO_STATE, UniversalTag.INTEGER.getValue(),
+            new GrammarAction( "Kerberos Ticket tktvno value" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    KerberosMessageContainer kerberosMessageContainer = ( KerberosMessageContainer ) container;
+
+                    TLV tlv = kerberosMessageContainer.getCurrentTLV();
+
+                    // The Length should not be null
+                    if ( tlv.getLength() == 0 )
+                    {
+                        LOG.error( I18n.err( I18n.ERR_04066 ) );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( I18n.err( I18n.ERR_04067 ) );
+                    }
+                    
+                    // The value should be an integer an equal to 5
+                    Value value = tlv.getValue();
+                    Ticket ticket = kerberosMessageContainer.getTicket();
+
+                    try
+                    {
+                        int tktvno = IntegerDecoder.parse( value, 5, 5 );
+
+                        ticket.setTktVno( tktvno );
+
+                        if ( IS_DEBUG )
+                        {
+                            LOG.debug( "TktVno : " + tktvno );
+                        }
+                    }
+                    catch ( IntegerDecoderException ide )
+                    {
+                        LOG.error( I18n.err( I18n.ERR_04070, StringTools.dumpBytes( value.getData() ), ide
+                            .getLocalizedMessage() ) );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( ide.getMessage() );
+                    }
+                }
+            } );
+
+        // ============================================================================================
+        // Transition from tkt-vno to realm tag
+        // ============================================================================================
+        // Ticket          ::= [APPLICATION 1] SEQUENCE { 
+        //         tkt-vno         [0] INTEGER (5), 
+        //         realm           [1]
+        super.transitions[KerberosStatesEnum.TICKET_VNO_STATE.ordinal()][KerberosConstants.TICKET_REALM_TAG] = new GrammarTransition(
+            KerberosStatesEnum.TICKET_VNO_STATE, KerberosStatesEnum.TICKET_REALM_TAG_STATE, KerberosConstants.TICKET_REALM_TAG,
+            new GrammarAction( "Kerberos Ticket realm tag" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    KerberosMessageContainer kerberosMessageContainer = ( KerberosMessageContainer ) container;
+
+                    TLV tlv = kerberosMessageContainer.getCurrentTLV();
+
+                    // The Length should not be null
+                    if ( tlv.getLength() == 0 )
+                    {
+                        LOG.error( I18n.err( I18n.ERR_04066 ) );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( I18n.err( I18n.ERR_04067 ) );
+                    }
+                }
+            } );
+
+        // ============================================================================================
+        // Transition from Ticket-SEQ to tkt-vno 
+        // ============================================================================================
+        // Ticket          ::= [APPLICATION 1] SEQUENCE { 
+        //         tkt-vno         [0] INTEGER (5),
+        //         realm           [1] Realm,
+        super.transitions[KerberosStatesEnum.TICKET_REALM_TAG_STATE.ordinal()][UniversalTag.GENERAL_STRING.getValue()] = new GrammarTransition(
+            KerberosStatesEnum.TICKET_REALM_TAG_STATE, KerberosStatesEnum.TICKET_REALM_STATE, UniversalTag.GENERAL_STRING.getValue(),
+            new GrammarAction( "Kerberos Ticket realm value" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    KerberosMessageContainer kerberosMessageContainer = ( KerberosMessageContainer ) container;
+
+                    TLV tlv = kerberosMessageContainer.getCurrentTLV();
+
+                    // The Length should not be null
+                    if ( tlv.getLength() == 0 )
+                    {
+                        LOG.error( I18n.err( I18n.ERR_04066 ) );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( I18n.err( I18n.ERR_04067 ) );
+                    }
+                    
+                    // The value is the realm
+                    Value value = tlv.getValue();
+                    String realm = StringTools.utf8ToString( value.getData() );
+                    Ticket ticket = kerberosMessageContainer.getTicket();
+
+                    ticket.setRealm( realm );
+                    
+                    if ( IS_DEBUG )
+                    {
+                        LOG.debug( "Realm : " + realm );
+                    }
+                }
+            } );
+
+        /*
+        // --------------------------------------------------------------------------------------------
+        // Transition from LdapMessage to Message ID
+        // --------------------------------------------------------------------------------------------
+        // LDAPMessage --> ... MessageId ...
+        //
+        // Checks that MessageId is in [0 .. 2147483647] and store the value in
+        // the LdapMessage Object
+        //
+        // (2147483647 = Integer.MAX_VALUE)
+        // The next state will be MESSAGE_ID_STATE
+        //
+        // The message ID will be temporarely stored in the container, because we can't store it
+        // into an object.
+        super.transitions[LdapStatesEnum.LDAP_MESSAGE_STATE.ordinal()][UniversalTag.INTEGER.getValue()] = new GrammarTransition(
+            LdapStatesEnum.LDAP_MESSAGE_STATE, LdapStatesEnum.MESSAGE_ID_STATE, UniversalTag.INTEGER.getValue(),
+            new GrammarAction( "Store MessageId" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    // The current TLV should be a integer
+                    // We get it and store it in MessageId
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    // The Length should not be null
+                    if ( tlv.getLength() == 0 )
+                    {
+                        LOG.error( I18n.err( I18n.ERR_04068 ) );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( I18n.err( I18n.ERR_04069 ) );
+                    }
+
+                    Value value = tlv.getValue();
+
+                    try
+                    {
+                        int messageId = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
+
+                        ldapMessageContainer.setMessageId( messageId );
+
+                        if ( IS_DEBUG )
+                        {
+                            LOG.debug( "Ldap Message Id has been decoded : " + messageId );
+                        }
+                    }
+                    catch ( IntegerDecoderException ide )
+                    {
+                        LOG.error( I18n.err( I18n.ERR_04070, StringTools.dumpBytes( value.getData() ), ide
+                            .getLocalizedMessage() ) );
+
+                        // This will generate a PROTOCOL_ERROR                        
+                        throw new DecoderException( ide.getMessage() );
+                    }
+                }
+            } );
+
+        // ********************************************************************************************
+        // We have a ProtocolOp :
+        // If the Tag is 0x42, then it's an UnBindRequest.
+        // If the Tag is 0x4A, then it's a DelRequest.
+        // If the Tag is 0x50, then it's an AbandonRequest.
+        // If the Tag is 0x60, then it's a BindRequest.
+        // If the Tag is 0x61, then it's a BindResponse.
+        // If the Tag is 0x63, then it's a SearchRequest.
+        // If the Tag is 0x64, then it's a SearchResultEntry.
+        // If the Tag is 0x65, then it's a SearchResultDone
+        // If the Tag is 0x66, then it's a ModifyRequest
+        // If the Tag is 0x67, then it's a ModifyResponse.
+        // If the Tag is 0x68, then it's an AddRequest.
+        // If the Tag is 0x69, then it's an AddResponse.
+        // If the Tag is 0x6B, then it's a DelResponse.
+        // If the Tag is 0x6C, then it's a ModifyDNRequest.
+        // If the Tag is 0x6D, then it's a ModifyDNResponse.
+        // If the Tag is 0x6E, then it's a CompareRequest
+        // If the Tag is 0x6F, then it's a CompareResponse.
+        // If the Tag is 0x73, then it's a SearchResultReference.
+        // If the Tag is 0x77, then it's an ExtendedRequest.
+        // If the Tag is 0x78, then it's an ExtendedResponse.
+        //
+        // We create the associated object in this transition, and store it into the container.
+        // ********************************************************************************************
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Message ID to UnBindRequest Message.
+        // --------------------------------------------------------------------------------------------
+        // LdapMessage ::= ... UnBindRequest ...
+        // unbindRequest ::= [APPLICATION 2] NULL
+        // We have to switch to the UnBindRequest grammar
+        super.transitions[LdapStatesEnum.MESSAGE_ID_STATE.ordinal()][LdapConstants.UNBIND_REQUEST_TAG] = new GrammarTransition(
+            LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.UNBIND_REQUEST_STATE, LdapConstants.UNBIND_REQUEST_TAG,
+            new GrammarAction( "Unbind Request initialization" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    // Create the UnbindRequest LdapMessage instance and store it in the container
+                    UnbindRequest unbindRequest = new UnbindRequestImpl( ldapMessageContainer.getMessageId() );
+                    ldapMessageContainer.setMessage( unbindRequest );
+
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+                    int expectedLength = tlv.getLength();
+
+                    // The Length should be null
+                    if ( expectedLength != 0 )
+                    {
+                        LOG.error( I18n.err( I18n.ERR_04071, Integer.valueOf( expectedLength ) ) );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( I18n.err( I18n.ERR_04072 ) );
+                    }
+
+                    // We can quit now
+                    ldapMessageContainer.setGrammarEndAllowed( true );
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // transition from UnBindRequest Message to Controls.
+        // --------------------------------------------------------------------------------------------
+        //         unbindRequest   UnbindRequest,
+        //         ... },
+        //     controls       [0] Controls OPTIONAL }
+        //
+        super.transitions[LdapStatesEnum.UNBIND_REQUEST_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.UNBIND_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Message ID to DelRequest Message.
+        // --------------------------------------------------------------------------------------------
+        // LdapMessage ::= ... DelRequest ...
+        // delRequest ::= [APPLICATION 10] LDAPDN
+        //
+        // We store the DN to bve deleted into the DelRequest object
+        super.transitions[LdapStatesEnum.MESSAGE_ID_STATE.ordinal()][LdapConstants.DEL_REQUEST_TAG] = new GrammarTransition(
+            LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.DEL_REQUEST_STATE, LdapConstants.DEL_REQUEST_TAG,
+            new GrammarAction( "Init del Request" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    // Create the DeleteRequest LdapMessage instance and store it in the container
+                    DeleteRequest delRequest = new DeleteRequestImpl( ldapMessageContainer.getMessageId() );
+                    ldapMessageContainer.setMessage( delRequest );
+
+                    // And store the DN into it
+                    // Get the Value and store it in the DelRequest
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    // We have to handle the special case of a 0 length matched
+                    // DN
+                    DN entry = null;
+
+                    if ( tlv.getLength() == 0 )
+                    {
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( I18n.err( I18n.ERR_04073 ) );
+                    }
+                    else
+                    {
+                        byte[] dnBytes = tlv.getValue().getData();
+                        String dnStr = StringTools.utf8ToString( dnBytes );
+
+                        try
+                        {
+                            entry = new DN( dnStr );
+                        }
+                        catch ( LdapInvalidDnException ine )
+                        {
+                            String msg = I18n.err( I18n.ERR_04074, dnStr, StringTools.dumpBytes( dnBytes ), ine
+                                .getLocalizedMessage() );
+                            LOG.error( msg );
+
+                            DeleteResponseImpl response = new DeleteResponseImpl( delRequest.getMessageId() );
+                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
+                                DN.EMPTY_DN, ine );
+                        }
+
+                        delRequest.setName( entry );
+                    }
+
+                    // We can have an END transition
+                    ldapMessageContainer.setGrammarEndAllowed( true );
+
+                    if ( IS_DEBUG )
+                    {
+                        LOG.debug( "Deleting DN {}", entry );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // transition from DelRequest Message to Controls.
+        // --------------------------------------------------------------------------------------------
+        //         delRequest   DelRequest,
+        //         ... },
+        //     controls       [0] Controls OPTIONAL }
+        //
+        super.transitions[LdapStatesEnum.DEL_REQUEST_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.DEL_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Message ID to AbandonRequest Message.
+        // --------------------------------------------------------------------------------------------
+        // LdapMessage ::= ... AbandonRequest ...
+        // AbandonRequest ::= [APPLICATION 16] MessageID
+        //
+        // Create the AbandonRequest object, and store the ID in it
+        super.transitions[LdapStatesEnum.MESSAGE_ID_STATE.ordinal()][LdapConstants.ABANDON_REQUEST_TAG] = new GrammarTransition(
+            LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.ABANDON_REQUEST_STATE, LdapConstants.ABANDON_REQUEST_TAG,
+            new GrammarAction( "Init Abandon Request" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    // Create the AbandonRequest LdapMessage instance and store it in the container
+                    AbandonRequest abandonRequest = new AbandonRequestImpl( ldapMessageContainer.getMessageId() );
+                    ldapMessageContainer.setMessage( abandonRequest );
+
+                    // The current TLV should be a integer
+                    // We get it and store it in MessageId
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    Value value = tlv.getValue();
+
+                    if ( ( value == null ) || ( value.getData() == null ) )
+                    {
+                        String msg = I18n.err( I18n.ERR_04075 );
+                        LOG.error( msg );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( msg );
+                    }
+
+                    try
+                    {
+                        int abandonnedMessageId = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
+
+                        abandonRequest.setAbandoned( abandonnedMessageId );
+
+                        if ( IS_DEBUG )
+                        {
+                            LOG
+                                .debug( "AbandonMessage Id has been decoded : {}", Integer
+                                    .valueOf( abandonnedMessageId ) );
+                        }
+
+                        ldapMessageContainer.setGrammarEndAllowed( true );
+
+                        return;
+                    }
+                    catch ( IntegerDecoderException ide )
+                    {
+                        LOG.error( I18n
+                            .err( I18n.ERR_04076, StringTools.dumpBytes( value.getData() ), ide.getMessage() ) );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( ide.getMessage() );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // transition from AbandonRequest Message to Controls.
+        // --------------------------------------------------------------------------------------------
+        //         abandonRequest   AbandonRequest,
+        //         ... },
+        //     controls       [0] Controls OPTIONAL }
+        //
+        super.transitions[LdapStatesEnum.ABANDON_REQUEST_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.ABANDON_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Message ID to BindRequest Message.
+        // --------------------------------------------------------------------------------------------
+        // LdapMessage ::= ... BindRequest ...
+        // BindRequest ::= [APPLICATION 0] SEQUENCE { ...
+        //
+        // We have to allocate a BindRequest
+        super.transitions[LdapStatesEnum.MESSAGE_ID_STATE.ordinal()][LdapConstants.BIND_REQUEST_TAG] = new GrammarTransition(
+            LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.BIND_REQUEST_STATE, LdapConstants.BIND_REQUEST_TAG,
+            new GrammarAction( "Init BindRequest" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    // Create the BindRequest LdapMessage instance and store it in the container
+                    BindRequest bindRequest = new BindRequestImpl( ldapMessageContainer.getMessageId() );
+                    ldapMessageContainer.setMessage( bindRequest );
+
+                    // We will check that the request is not null
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    if ( tlv.getLength() == 0 )
+                    {
+                        String msg = I18n.err( I18n.ERR_04077 );
+                        LOG.error( msg );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( msg );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from BindRequest to version
+        // --------------------------------------------------------------------------------------------
+        // BindRequest ::= [APPLICATION 0] SEQUENCE {
+        //     version                 INTEGER (1 ..  127),
+        //     ....
+        //
+        // The Ldap version is parsed and stored into the BindRequest object
+        super.transitions[LdapStatesEnum.BIND_REQUEST_STATE.ordinal()][UniversalTag.INTEGER.getValue()] = new GrammarTransition(
+            LdapStatesEnum.BIND_REQUEST_STATE, LdapStatesEnum.VERSION_STATE, UniversalTag.INTEGER.getValue(),
+            new GrammarAction( "Store version" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+                    BindRequest bindRequestMessage = ldapMessageContainer.getBindRequest();
+
+                    // The current TLV should be a integer between 1 and 127
+                    // We get it and store it in Version
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    Value value = tlv.getValue();
+
+                    try
+                    {
+                        int version = IntegerDecoder.parse( value, 1, 127 );
+
+                        if ( IS_DEBUG )
+                        {
+                            LOG.debug( "Ldap version ", Integer.valueOf( version ) );
+                        }
+
+                        bindRequestMessage.setVersion3( version == 3 );
+                    }
+                    catch ( IntegerDecoderException ide )
+                    {
+                        LOG.error( I18n
+                            .err( I18n.ERR_04078, StringTools.dumpBytes( value.getData() ), ide.getMessage() ) );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( ide.getMessage() );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from version to name
+        // --------------------------------------------------------------------------------------------
+        // BindRequest ::= [APPLICATION 0] SEQUENCE {
+        //     ....
+        //     name                    LDAPDN,
+        //     ....
+        //
+        // The Ldap version is parsed and stored into the BindRequest object
+        super.transitions[LdapStatesEnum.VERSION_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.VERSION_STATE, LdapStatesEnum.NAME_STATE, UniversalTag.OCTET_STRING.getValue(), new GrammarAction(
+                "Store Bind Name value" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+                    BindRequest bindRequestMessage = ldapMessageContainer.getBindRequest();
+
+                    // Get the Value and store it in the BindRequest
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    // We have to handle the special case of a 0 length name
+                    if ( tlv.getLength() == 0 )
+                    {
+                        bindRequestMessage.setName( DN.EMPTY_DN );
+                    }
+                    else
+                    {
+                        byte[] dnBytes = tlv.getValue().getData();
+                        String dnStr = StringTools.utf8ToString( dnBytes );
+
+                        try
+                        {
+                            DN dn = new DN( dnStr );
+                            bindRequestMessage.setName( dn );
+                        }
+                        catch ( LdapInvalidDnException ine )
+                        {
+                            String msg = "Incorrect DN given : " + dnStr + " (" + StringTools.dumpBytes( dnBytes )
+                                + ") is invalid";
+                            LOG.error( "{} : {}", msg, ine.getMessage() );
+
+                            BindResponseImpl response = new BindResponseImpl( bindRequestMessage.getMessageId() );
+
+                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
+                                DN.EMPTY_DN, ine );
+                        }
+                    }
+
+                    if ( IS_DEBUG )
+                    {
+                        LOG.debug( " The Bind name is {}", bindRequestMessage.getName() );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from name to Simple Authentication
+        // --------------------------------------------------------------------------------------------
+        // BindRequest ::= [APPLICATION 0] SEQUENCE {
+        //     ....
+        //     authentication          AuthenticationChoice }
+        //
+        // AuthenticationChoice ::= CHOICE {
+        //     simple                  [0] OCTET STRING,
+        //     ...
+        //
+        // We have to create an Authentication Object to store the credentials.
+        super.transitions[LdapStatesEnum.NAME_STATE.ordinal()][LdapConstants.BIND_REQUEST_SIMPLE_TAG] = new GrammarTransition(
+            LdapStatesEnum.NAME_STATE, LdapStatesEnum.SIMPLE_STATE, LdapConstants.BIND_REQUEST_SIMPLE_TAG,
+            new GrammarAction( "Store Bind Simple Authentication value" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    BindRequest bindRequestMessage = ldapMessageContainer.getBindRequest();
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    // Allocate the Authentication Object
+                    bindRequestMessage.setSimple( true );
+
+                    // We have to handle the special case of a 0 length simple
+                    if ( tlv.getLength() == 0 )
+                    {
+                        bindRequestMessage.setCredentials( StringTools.EMPTY_BYTES );
+                    }
+                    else
+                    {
+                        bindRequestMessage.setCredentials( tlv.getValue().getData() );
+                    }
+
+                    // We can have an END transition
+                    ldapMessageContainer.setGrammarEndAllowed( true );
+
+                    if ( IS_DEBUG )
+                    {
+                        LOG.debug( "The simple authentication is : {}", StringTools.dumpBytes( bindRequestMessage
+                            .getCredentials() ) );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // transition from Simple Authentication to Controls.
+        // --------------------------------------------------------------------------------------------
+        //         bindRequest   BindRequest,
+        //         ... },
+        //     controls       [0] Controls OPTIONAL }
+        //
+        super.transitions[LdapStatesEnum.SIMPLE_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.SIMPLE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from name to SASL Authentication
+        // --------------------------------------------------------------------------------------------
+        // BindRequest ::= [APPLICATION 0] SEQUENCE {
+        //     ....
+        //     authentication          AuthenticationChoice }
+        //
+        // AuthenticationChoice ::= CHOICE {
+        //     ...
+        //     sasl                  [3] SaslCredentials }
+        //     ...
+        //
+        // We have to create an Authentication Object to store the credentials.
+        super.transitions[LdapStatesEnum.NAME_STATE.ordinal()][LdapConstants.BIND_REQUEST_SASL_TAG] = new GrammarTransition(
+            LdapStatesEnum.NAME_STATE, LdapStatesEnum.SASL_STATE, LdapConstants.BIND_REQUEST_SASL_TAG,
+            new GrammarAction( "Initialize Bind SASL Authentication" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+                    BindRequest bindRequestMessage = ldapMessageContainer.getBindRequest();
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    // We will check that the sasl is not null
+                    if ( tlv.getLength() == 0 )
+                    {
+                        String msg = I18n.err( I18n.ERR_04079 );
+                        LOG.error( msg );
+
+                        BindResponseImpl response = new BindResponseImpl( bindRequestMessage.getMessageId() );
+
+                        throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_CREDENTIALS,
+                            bindRequestMessage.getName(), null );
+                    }
+
+                    bindRequestMessage.setSimple( false );
+
+                    if ( IS_DEBUG )
+                    {
+                        LOG.debug( "The SaslCredential has been created" );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from SASL Authentication to Mechanism
+        // --------------------------------------------------------------------------------------------
+        // SaslCredentials ::= SEQUENCE {
+        //     mechanism   LDAPSTRING,
+        //     ...
+        //
+        // We have to store the mechanism.
+        super.transitions[LdapStatesEnum.SASL_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.SASL_STATE, LdapStatesEnum.MECHANISM_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new GrammarAction( "Store SASL mechanism" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+                    BindRequest bindRequestMessage = ldapMessageContainer.getBindRequest();
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    // We have to handle the special case of a 0 length
+                    // mechanism
+                    if ( tlv.getLength() == 0 )
+                    {
+                        bindRequestMessage.setSaslMechanism( "" );
+                    }
+                    else
+                    {
+                        bindRequestMessage.setSaslMechanism( StringTools.utf8ToString( tlv.getValue().getData() ) );
+                    }
+
+                    // We can have an END transition
+                    ldapMessageContainer.setGrammarEndAllowed( true );
+
+                    if ( IS_DEBUG )
+                    {
+                        LOG.debug( "The mechanism is : {}", bindRequestMessage.getSaslMechanism() );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Mechanism to Credentials
+        // --------------------------------------------------------------------------------------------
+        // SaslCredentials ::= SEQUENCE {
+        //     ...
+        //     credentials OCTET STRING OPTIONAL }
+        //
+        // We have to store the mechanism.
+        super.transitions[LdapStatesEnum.MECHANISM_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.MECHANISM_STATE, LdapStatesEnum.CREDENTIALS_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new GrammarAction( "Store SASL credentials" )
+            {
+                public void action( Asn1Container container )
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    BindRequest bindRequestMessage = ldapMessageContainer.getBindRequest();
+
+                    // Get the Value and store it in the BindRequest
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    // We have to handle the special case of a 0 length
+                    // credentials
+                    if ( tlv.getLength() == 0 )
+                    {
+                        bindRequestMessage.setCredentials( StringTools.EMPTY_BYTES );
+                    }
+                    else
+                    {
+                        bindRequestMessage.setCredentials( tlv.getValue().getData() );
+                    }
+
+                    // We can have an END transition
+                    ldapMessageContainer.setGrammarEndAllowed( true );
+
+                    if ( IS_DEBUG )
+                    {
+                        LOG.debug( "The credentials are : {}", StringTools.dumpBytes( bindRequestMessage
+                            .getCredentials() ) );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // transition from from Mechanism to Controls.
+        // --------------------------------------------------------------------------------------------
+        //         bindRequest   BindRequest,
+        //         ... },
+        //     controls       [0] Controls OPTIONAL }
+        //
+        super.transitions[LdapStatesEnum.MECHANISM_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.MECHANISM_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // transition from credentials to Controls.
+        // --------------------------------------------------------------------------------------------
+        //         bindRequest   BindRequest,
+        //         ... },
+        //     controls       [0] Controls OPTIONAL }
+        //
+        super.transitions[LdapStatesEnum.CREDENTIALS_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.CREDENTIALS_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from MessageId to BindResponse message 
+        // --------------------------------------------------------------------------------------------
+        // LdapMessage ::= ... BindResponse ...
+        // BindResponse ::= [APPLICATION 1] SEQUENCE { ...
+        // We have to switch to the BindResponse grammar
+        super.transitions[LdapStatesEnum.MESSAGE_ID_STATE.ordinal()][LdapConstants.BIND_RESPONSE_TAG] = new GrammarTransition(
+            LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.BIND_RESPONSE_STATE, LdapConstants.BIND_RESPONSE_TAG,
+            new GrammarAction( "Init BindReponse" )
+            {
+                public void action( Asn1Container container )
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    // Now, we can allocate the BindResponse Object
+                    BindResponse bindResponse = new BindResponseImpl( ldapMessageContainer.getMessageId() );
+                    ldapMessageContainer.setMessage( bindResponse );
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from BindResponse message to Result Code BR 
+        // --------------------------------------------------------------------------------------------
+        // BindResponse ::= [APPLICATION 1] SEQUENCE {
+        //     COMPONENTS OF LDAPResult,
+        //     ...
+        //
+        // LDAPResult ::= SEQUENCE {
+        //     resultCode ENUMERATED { 
+        //         ...
+        // 
+        // Stores the result code into the Bind Response object
+        super.transitions[LdapStatesEnum.BIND_RESPONSE_STATE.ordinal()][UniversalTag.ENUMERATED.getValue()] = new GrammarTransition(
+            LdapStatesEnum.BIND_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_BR_STATE, UniversalTag.ENUMERATED.getValue(),
+            new ResultCodeAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Result Code BR to Matched DN BR 
+        // --------------------------------------------------------------------------------------------
+        // LDAPResult ::= SEQUENCE {
+        //     ...
+        //     matchedDN LDAPDN,
+        //     ...
+        //
+        // Stores the matched DN
+        super.transitions[LdapStatesEnum.RESULT_CODE_BR_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.RESULT_CODE_BR_STATE, LdapStatesEnum.MATCHED_DN_BR_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new MatchedDNAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Matched DN BR to Error Message BR 
+        // --------------------------------------------------------------------------------------------
+        // LDAPResult ::= SEQUENCE {
+        //     ...
+        //     errorMessage LDAPString,
+        //     ...
+        //
+        // Stores the error message
+        super.transitions[LdapStatesEnum.MATCHED_DN_BR_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.MATCHED_DN_BR_STATE, LdapStatesEnum.ERROR_MESSAGE_BR_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new ErrorMessageAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Error Message BR to Server SASL credentials 
+        // --------------------------------------------------------------------------------------------
+        // BindResponse ::= APPLICATION 1] SEQUENCE {
+        //     ...
+        //     serverSaslCreds [7] OCTET STRING OPTIONAL }
+        //
+        // Stores the sasl credentials 
+        super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE.ordinal()][LdapConstants.SERVER_SASL_CREDENTIAL_TAG] = new GrammarTransition(
+            LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE,
+            LdapConstants.SERVER_SASL_CREDENTIAL_TAG, new ServerSASLCredsAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Error Message BR to Referrals BR 
+        // --------------------------------------------------------------------------------------------
+        // LDAPResult ::= SEQUENCE {
+        //     ...
+        //     referral   [3] Referral OPTIONNAL }
+        //
+        // Initialiaze the referrals list 
+        super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE.ordinal()][LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG] = new GrammarTransition(
+            LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.REFERRALS_BR_STATE,
+            LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, new InitReferralsAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Referrals BR to Referral BR 
+        // --------------------------------------------------------------------------------------------
+        // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
+        // URI ::= LDAPString
+        //
+        // Add a first Referral
+        super.transitions[LdapStatesEnum.REFERRALS_BR_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.REFERRALS_BR_STATE, LdapStatesEnum.REFERRAL_BR_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new ReferralAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Referral BR to Referral BR 
+        // --------------------------------------------------------------------------------------------
+        // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
+        // URI ::= LDAPString
+        //
+        // Adda new Referral
+        super.transitions[LdapStatesEnum.REFERRAL_BR_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.REFERRAL_BR_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new ReferralAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Referral BR to Server SASL Credentials 
+        // --------------------------------------------------------------------------------------------
+        // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
+        // URI ::= LDAPString
+        //
+        // Adda new Referral
+        super.transitions[LdapStatesEnum.REFERRAL_BR_STATE.ordinal()][LdapConstants.SERVER_SASL_CREDENTIAL_TAG] = new GrammarTransition(
+            LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE,
+            LdapConstants.SERVER_SASL_CREDENTIAL_TAG, new ServerSASLCredsAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Referral BR to Controls 
+        // --------------------------------------------------------------------------------------------
+        //         bindResponse   BindResponse,
+        //         ... },
+        //     controls       [0] Controls OPTIONAL }
+        //
+        // Adda new Referral
+        super.transitions[LdapStatesEnum.REFERRAL_BR_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Error Message BR to controls 
+        // --------------------------------------------------------------------------------------------
+        //         bindResponse   BindResponse,
+        //         ... },
+        //     controls       [0] Controls OPTIONAL }
+        //
+        //  
+        super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Server SASL credentials to Controls 
+        // --------------------------------------------------------------------------------------------
+        //         bindResponse   BindResponse,
+        //         ... },
+        //     controls       [0] Controls OPTIONAL }
+        //
+        super.transitions[LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Result Code to Matched DN 
+        // --------------------------------------------------------------------------------------------
+        // LDAPResult ::= SEQUENCE {
+        //     ...
+        //     matchedDN LDAPDN,
+        //     ...
+        //
+        // Stores the matched DN
+        super.transitions[LdapStatesEnum.RESULT_CODE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.RESULT_CODE_STATE, LdapStatesEnum.MATCHED_DN_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new MatchedDNAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Matched DN to Error Message 
+        // --------------------------------------------------------------------------------------------
+        // LDAPResult ::= SEQUENCE {
+        //     ...
+        //     errorMessage LDAPString,
+        //     ...
+        //
+        // Stores the error message
+        super.transitions[LdapStatesEnum.MATCHED_DN_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.MATCHED_DN_STATE, LdapStatesEnum.ERROR_MESSAGE_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new ErrorMessageAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Error Message to Referrals
+        // --------------------------------------------------------------------------------------------
+        // LDAPResult ::= SEQUENCE {
+        //     ...
+        //     referral   [3] Referral OPTIONNAL }
+        //
+        // Initialiaze the referrals list 
+        super.transitions[LdapStatesEnum.ERROR_MESSAGE_STATE.ordinal()][LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG] = new GrammarTransition(
+            LdapStatesEnum.ERROR_MESSAGE_STATE, LdapStatesEnum.REFERRALS_STATE,
+            LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, new GrammarAction( "Init referrals list" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    // If we hae a Referrals sequence, then it should not be empty
+                    // sasl credentials
+                    if ( tlv.getLength() == 0 )
+                    {
+                        String msg = I18n.err( I18n.ERR_04080 );
+                        LOG.error( msg );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( msg );
+                    }
+
+                    Message response = ldapMessageContainer.getMessage();
+                    LdapResult ldapResult = ( ( ResultResponse ) response ).getLdapResult();
+
+                    Referral referral = new ReferralImpl();
+
+                    ldapResult.setReferral( referral );
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Referrals to Referral 
+        // --------------------------------------------------------------------------------------------
+        // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
+        // URI ::= LDAPString
+        //
+        // Add a first Referral
+        super.transitions[LdapStatesEnum.REFERRALS_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.REFERRALS_STATE, LdapStatesEnum.REFERRAL_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new ReferralAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Referral to Referral 
+        // --------------------------------------------------------------------------------------------
+        // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
+        // URI ::= LDAPString
+        //
+        // Adda new Referral
+        super.transitions[LdapStatesEnum.REFERRAL_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.REFERRAL_STATE, LdapStatesEnum.REFERRAL_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new ReferralAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Referral to Controls 
+        // --------------------------------------------------------------------------------------------
+        //         xxxResponse   xxxResponse,
+        //         ... },
+        //     controls       [0] Controls OPTIONAL }
+        //
+        // Adda new Referral
+        super.transitions[LdapStatesEnum.REFERRAL_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.REFERRAL_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Error Message to controls 
+        // --------------------------------------------------------------------------------------------
+        //         xxxResponse   xxxResponse,
+        //         ... },
+        //     controls       [0] Controls OPTIONAL }
+        //
+        //  
+        super.transitions[LdapStatesEnum.ERROR_MESSAGE_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.ERROR_MESSAGE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from MessageId to SearchResultEntry Message.
+        // --------------------------------------------------------------------------------------------
+        // LdapMessage ::= ... SearchResultEntry ...
+        // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+        //
+        // Initialize the searchResultEntry object
+        super.transitions[LdapStatesEnum.MESSAGE_ID_STATE.ordinal()][LdapConstants.SEARCH_RESULT_ENTRY_TAG] = new GrammarTransition(
+            LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE,
+            LdapConstants.SEARCH_RESULT_ENTRY_TAG, new GrammarAction( "Init SearchResultEntry" )
+            {
+                public void action( Asn1Container container )
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    // Now, we can allocate the SearchResultEntry Object
+                    SearchResultEntry searchResultEntry = new SearchResultEntryImpl( ldapMessageContainer
+                        .getMessageId() );
+                    ldapMessageContainer.setMessage( searchResultEntry );
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from SearchResultEntry Message to ObjectName
+        // --------------------------------------------------------------------------------------------
+        // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+        // objectName LDAPDN,
+        // ...
+        //
+        // Store the object name.
+        super.transitions[LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE, LdapStatesEnum.OBJECT_NAME_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new GrammarAction( "Store search result entry object name Value" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+                    SearchResultEntry searchResultEntry = ldapMessageContainer.getSearchResultEntry();
+
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    DN objectName = DN.EMPTY_DN;
+
+                    // Store the value.
+                    if ( tlv.getLength() == 0 )
+                    {
+                        searchResultEntry.setObjectName( objectName );
+                    }
+                    else
+                    {
+                        byte[] dnBytes = tlv.getValue().getData();
+                        String dnStr = StringTools.utf8ToString( dnBytes );
+
+                        try
+                        {
+                            objectName = new DN( dnStr );
+                        }
+                        catch ( LdapInvalidDnException ine )
+                        {
+                            // This is for the client side. We will never decode LdapResult on the server
+                            String msg = "The DN " + StringTools.dumpBytes( dnBytes ) + "is invalid : "
+                                + ine.getMessage();
+                            LOG.error( "{} : {}", msg, ine.getMessage() );
+                            throw new DecoderException( msg, ine );
+                        }
+
+                        searchResultEntry.setObjectName( objectName );
+                    }
+
+                    if ( IS_DEBUG )
+                    {
+                        LOG.debug( "Search Result Entry DN found : {}", searchResultEntry.getObjectName() );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from ObjectName to AttributesSR
+        // --------------------------------------------------------------------------------------------
+        // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+        // ...
+        // attributes PartialAttributeList }
+        //
+        // PartialAttributeList ::= *SEQUENCE* OF SEQUENCE {
+        // ...
+        //
+        // We may have no attributes. Just allows the grammar to end
+        super.transitions[LdapStatesEnum.OBJECT_NAME_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition(
+            LdapStatesEnum.OBJECT_NAME_STATE, LdapStatesEnum.ATTRIBUTES_SR_STATE, UniversalTag.SEQUENCE.getValue(),
+            new GrammarAction( "Pop and end allowed" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    container.setGrammarEndAllowed( true );
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from AttributesSR to PartialAttributesList
+        // --------------------------------------------------------------------------------------------
+        // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+        // ...
+        // attributes PartialAttributeList }
+        //
+        // PartialAttributeList ::= SEQUENCE OF *SEQUENCE* {
+        // ...
+        //
+        // nothing to do
+        super.transitions[LdapStatesEnum.ATTRIBUTES_SR_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition(
+            LdapStatesEnum.ATTRIBUTES_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE,
+            UniversalTag.SEQUENCE.getValue(), null );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from AttributesSR to Controls
+        // --------------------------------------------------------------------------------------------
+        //     searchResultEntry SearchResultEntry,
+        //     ... },
+        // controls   [0] Controls OPTIONAL }
+        //
+        // Initialize the controls
+        super.transitions[LdapStatesEnum.ATTRIBUTES_SR_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.ATTRIBUTES_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from PartialAttributesList to typeSR
+        // --------------------------------------------------------------------------------------------
+        // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+        // ...
+        // attributes PartialAttributeList }
+        //
+        // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+        //     type  AttributeDescription,
+        //     ...
+        //
+        // Store the attribute's name.
+        super.transitions[LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE, LdapStatesEnum.TYPE_SR_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new GrammarAction( "Store search result entry object name Value" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+                    SearchResultEntry searchResultEntry = ldapMessageContainer.getSearchResultEntry();
+
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    String type = "";
+
+                    // Store the name
+                    if ( tlv.getLength() == 0 )
+                    {
+                        // The type can't be null
+                        String msg = I18n.err( I18n.ERR_04081 );
+                        LOG.error( msg );
+                        throw new DecoderException( msg );
+                    }
+                    else
+                    {
+                        type = StringTools.getType( tlv.getValue().getData() );
+
+                        try
+                        {
+                            searchResultEntry.addAttribute( type );
+                        }
+                        catch ( LdapException ine )
+                        {
+                            // This is for the client side. We will never decode LdapResult on the server
+                            String msg = "The Attribute type " + type + "is invalid : " + ine.getMessage();
+                            LOG.error( "{} : {}", msg, ine.getMessage() );
+                            throw new DecoderException( msg, ine );
+                        }
+                    }
+
+                    if ( IS_DEBUG )
+                    {
+                        LOG.debug( "Attribute type : {}", type );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from typeSR to ValsSR
+        // --------------------------------------------------------------------------------------------
+        // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+        // ...
+        // attributes PartialAttributeList }
+        //
+        // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+        //     ...
+        //     vals SET OF AttributeValue }
+        //
+        // We may have no value. Just allows the grammar to end
+        super.transitions[LdapStatesEnum.TYPE_SR_STATE.ordinal()][UniversalTag.SET.getValue()] = new GrammarTransition(
+            LdapStatesEnum.TYPE_SR_STATE, LdapStatesEnum.VALS_SR_STATE, UniversalTag.SET.getValue(), new GrammarAction(
+                "Grammar end allowed" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+                    container.setGrammarEndAllowed( true );
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from ValsSR to AttributeValueSR
+        // --------------------------------------------------------------------------------------------
+        // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+        //     ...
+        //     vals SET OF AttributeValue }
+        //
+        // AttributeValue ::= OCTET STRING
+        // 
+        // Store the attribute value
+        super.transitions[LdapStatesEnum.VALS_SR_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new SearchResultAttributeValueAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from ValsSR to PartialAttributesList
+        // --------------------------------------------------------------------------------------------
+        // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+        //     ...
+        //     vals SET OF AttributeValue }
+        // 
+        // Loop when we don't have any attribute value. Nothing to do
+        super.transitions[LdapStatesEnum.VALS_SR_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition(
+            LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE, UniversalTag.SEQUENCE.getValue(), null );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from ValsSR to Controls
+        // --------------------------------------------------------------------------------------------
+        //     searchResultEntry SearchResultEntry,
+        //     ... },
+        // controls   [0] Controls OPTIONAL }
+        //
+        // Initialize the controls
+        super.transitions[LdapStatesEnum.VALS_SR_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from AttributeValueSR to AttributeValueSR 
+        // --------------------------------------------------------------------------------------------
+        // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+        //     ...
+        //     vals SET OF AttributeValue }
+        //
+        // AttributeValue ::= OCTET STRING
+        // 
+        // Store the attribute value
+        super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE,
+            UniversalTag.OCTET_STRING.getValue(), new SearchResultAttributeValueAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from AttributeValueSR to PartialAttributesList
+        // --------------------------------------------------------------------------------------------
+        // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+        //     ...
+        //     vals SET OF AttributeValue }
+        // 
+        // Loop when we don't have any attribute value. Nothing to do
+        super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition(
+            LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE,
+            UniversalTag.SEQUENCE.getValue(), null );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from AttributeValueSR to Controls
+        // --------------------------------------------------------------------------------------------
+        //     searchResultEntry SearchResultEntry,
+        //     ... },
+        // controls   [0] Controls OPTIONAL }
+        //
+        // Initialize the controls
+        super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE.ordinal()][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
+            LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+            new ControlsInitAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // SearchResultDone Message.
+        // --------------------------------------------------------------------------------------------
+        // LdapMessage ::= ... SearchResultDone ...
+        // SearchResultDone ::= [APPLICATION 5] SEQUENCE { ...
+        // 
+        super.transitions[LdapStatesEnum.MESSAGE_ID_STATE.ordinal()][LdapConstants.SEARCH_RESULT_DONE_TAG] = new GrammarTransition(
+            LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_RESULT_DONE_STATE,
+            LdapConstants.SEARCH_RESULT_DONE_TAG, new GrammarAction( "Init search Result Done" )
+            {
+                public void action( Asn1Container container )
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    // Now, we can allocate the SearchResultDone Object
+                    SearchResultDone searchResultDone = new SearchResultDoneImpl( ldapMessageContainer.getMessageId() );
+                    ldapMessageContainer.setMessage( searchResultDone );
+
+                    LOG.debug( "Search Result Done found" );
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // SearchResultDone Message.
+        // --------------------------------------------------------------------------------------------
+        // LdapMessage ::= ... SearchResultDone ...
+        // SearchResultDone ::= [APPLICATION 5] LDAPResult
+        //
+        // LDAPResult ::= SEQUENCE {
+        //     resultCode    ENUMERATED {
+        //         ...
+        // 
+        // Stores the result code
+        super.transitions[LdapStatesEnum.SEARCH_RESULT_DONE_STATE.ordinal()][UniversalTag.ENUMERATED.getValue()] = new GrammarTransition(
+            LdapStatesEnum.SEARCH_RESULT_DONE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED.getValue(),
+            new ResultCodeAction() );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Message ID to ModifyRequest Message
+        // --------------------------------------------------------------------------------------------
+        // LdapMessage ::= ... ModifyRequest ...
+        // ModifyRequest ::= [APPLICATION 6] SEQUENCE { ...
+        //
+        // Creates the Modify Request object
+        super.transitions[LdapStatesEnum.MESSAGE_ID_STATE.ordinal()][LdapConstants.MODIFY_REQUEST_TAG] = new GrammarTransition(
+            LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.MODIFY_REQUEST_STATE, LdapConstants.MODIFY_REQUEST_TAG,
+            new GrammarAction( "Init ModifyRequest" )
+            {
+                public void action( Asn1Container container )
+                {
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+                    // Now, we can allocate the ModifyRequest Object
+                    ModifyRequest modifyRequest = new ModifyRequestImpl( ldapMessageContainer.getMessageId() );
+                    ldapMessageContainer.setMessage( modifyRequest );
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from ModifyRequest Message to Object
+        // --------------------------------------------------------------------------------------------
+        // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+        //     object    LDAPDN,
+        //     ...
+        //
+        // Stores the object DN
+        super.transitions[LdapStatesEnum.MODIFY_REQUEST_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.MODIFY_REQUEST_STATE, LdapStatesEnum.OBJECT_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new GrammarAction( "Store Modify request object Value" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+                    ModifyRequest modifyRequest = ldapMessageContainer.getModifyRequest();
+
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    DN object = DN.EMPTY_DN;
+
+                    // Store the value.
+                    if ( tlv.getLength() == 0 )
+                    {
+                        modifyRequest.setName( object );
+                    }
+                    else
+                    {
+                        byte[] dnBytes = tlv.getValue().getData();
+                        String dnStr = StringTools.utf8ToString( dnBytes );
+
+                        try
+                        {
+                            object = new DN( dnStr );
+                        }
+                        catch ( LdapInvalidDnException ine )
+                        {
+                            String msg = "Invalid DN given : " + dnStr + " (" + StringTools.dumpBytes( dnBytes )
+                                + ") is invalid";
+                            LOG.error( "{} : {}", msg, ine.getMessage() );
+
+                            ModifyResponseImpl response = new ModifyResponseImpl( modifyRequest.getMessageId() );
+                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
+                                DN.EMPTY_DN, ine );
+                        }
+
+                        modifyRequest.setName( object );
+                    }
+
+                    if ( IS_DEBUG )
+                    {
+                        LOG.debug( "Modification of DN {}", modifyRequest.getName() );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from Object to modifications
+        // --------------------------------------------------------------------------------------------
+        // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+        //     ...
+        //     modification *SEQUENCE OF* SEQUENCE {
+        //     ...
+        //
+        // Initialize the modifications list
+        super.transitions[LdapStatesEnum.OBJECT_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition(
+            LdapStatesEnum.OBJECT_STATE, LdapStatesEnum.MODIFICATIONS_STATE, UniversalTag.SEQUENCE.getValue(), null );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from modifications to modification sequence
+        // --------------------------------------------------------------------------------------------
+        // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+        //     ...
+        //     modification SEQUENCE OF *SEQUENCE* {
+        //     ...
+        //
+        // Nothing to do
+        super.transitions[LdapStatesEnum.MODIFICATIONS_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition(
+            LdapStatesEnum.MODIFICATIONS_STATE, LdapStatesEnum.MODIFICATIONS_SEQ_STATE, UniversalTag.SEQUENCE.getValue(), null );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from modification sequence to operation
+        // --------------------------------------------------------------------------------------------
+        // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+        //     ...
+        //     modification SEQUENCE OF SEQUENCE {
+        //         operation  ENUMERATED {
+        //             ...
+        //
+        // Store operation type
+        super.transitions[LdapStatesEnum.MODIFICATIONS_SEQ_STATE.ordinal()][UniversalTag.ENUMERATED.getValue()] = new GrammarTransition(
+            LdapStatesEnum.MODIFICATIONS_SEQ_STATE, LdapStatesEnum.OPERATION_STATE, UniversalTag.ENUMERATED.getValue(),
+            new GrammarAction( "Store operation type" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+                    ModifyRequest modifyRequest = ldapMessageContainer.getModifyRequest();
+
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    // Decode the operation type
+                    int operation = 0;
+
+                    try
+                    {
+                        operation = IntegerDecoder.parse( tlv.getValue(), 0, 2 );
+                    }
+                    catch ( IntegerDecoderException ide )
+                    {
+                        String msg = I18n.err( I18n.ERR_04082, StringTools.dumpBytes( tlv.getValue().getData() ) );
+                        LOG.error( msg );
+
+                        // This will generate a PROTOCOL_ERROR
+                        throw new DecoderException( msg );
+                    }
+
+                    // Store the current operation.
+                    ( ( ModifyRequestImpl ) modifyRequest ).setCurrentOperation( operation );
+
+                    if ( IS_DEBUG )
+                    {
+                        switch ( operation )
+                        {
+                            case LdapConstants.OPERATION_ADD:
+                                LOG.debug( "Modification operation : ADD" );
+                                break;
+
+                            case LdapConstants.OPERATION_DELETE:
+                                LOG.debug( "Modification operation : DELETE" );
+                                break;
+
+                            case LdapConstants.OPERATION_REPLACE:
+                                LOG.debug( "Modification operation : REPLACE" );
+                                break;
+                        }
+                    }
+
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from operation to modification
+        // --------------------------------------------------------------------------------------------
+        // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+        //     ...
+        //     modification SEQUENCE OF SEQUENCE {
+        //             ...
+        //         modification   AttributeTypeAndValues }
+        //
+        // AttributeTypeAndValues ::= SEQUENCE {
+        //     ...
+        //
+        // Nothing to do
+        super.transitions[LdapStatesEnum.OPERATION_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition(
+            LdapStatesEnum.OPERATION_STATE, LdapStatesEnum.MODIFICATION_STATE, UniversalTag.SEQUENCE.getValue(), null );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from modification to TypeMod
+        // --------------------------------------------------------------------------------------------
+        // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+        //     ...
+        //     modification SEQUENCE OF SEQUENCE {
+        //             ...
+        //         modification   AttributeTypeAndValues }
+        //
+        // AttributeTypeAndValues ::= SEQUENCE {
+        //     type AttributeDescription,
+        //     ...
+        //
+        // Stores the type
+        super.transitions[LdapStatesEnum.MODIFICATION_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
+            LdapStatesEnum.MODIFICATION_STATE, LdapStatesEnum.TYPE_MOD_STATE, UniversalTag.OCTET_STRING.getValue(),
+            new GrammarAction( "Store type" )
+            {
+                public void action( Asn1Container container ) throws DecoderException
+                {
+
+                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+                    ModifyRequest modifyRequest = ldapMessageContainer.getModifyRequest();
+
+                    TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+                    // Store the value. It can't be null
+                    String type = null;
+
+                    if ( tlv.getLength() == 0 )
+                    {
+                        String msg = I18n.err( I18n.ERR_04083 );
+                        LOG.error( msg );
+
+                        ModifyResponseImpl response = new ModifyResponseImpl( modifyRequest.getMessageId() );
+                        throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
+                            modifyRequest.getName(), null );
+                    }
+                    else
+                    {
+                        type = StringTools.getType( tlv.getValue().getData() );
+                        ( ( ModifyRequestImpl ) modifyRequest ).addAttributeTypeAndValues( type );
+                    }
+
+                    if ( IS_DEBUG )
+                    {
+                        LOG.debug( "Modifying type : {}", type );
+                    }
+                }
+            } );
+
+        // --------------------------------------------------------------------------------------------
+        // Transition from TypeMod to vals
+        // --------------------------------------------------------------------------------------------
+        // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+        //     ...
+        //     modification SEQUENCE OF SEQUENCE {
+        //             ...
+        //         modification   AttributeTypeAndValues }
+        //
+        // AttributeTypeAndValues ::= SEQUENCE {
+        //     ...
+        //     vals SET OF AttributeValue }

[... 4971 lines stripped ...]


Mime
View raw message