001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    package org.apache.directory.shared.ldap.codec;
021    
022    
023    import org.apache.directory.shared.ldap.exception.LdapException;
024    
025    import org.apache.directory.shared.asn1.ber.IAsn1Container;
026    import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar;
027    import org.apache.directory.shared.asn1.ber.grammar.GrammarAction;
028    import org.apache.directory.shared.asn1.ber.grammar.GrammarTransition;
029    import org.apache.directory.shared.asn1.ber.grammar.IAction;
030    import org.apache.directory.shared.asn1.ber.grammar.IGrammar;
031    import org.apache.directory.shared.asn1.ber.tlv.TLV;
032    import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
033    import org.apache.directory.shared.asn1.ber.tlv.Value;
034    import org.apache.directory.shared.asn1.codec.DecoderException;
035    import org.apache.directory.shared.asn1.primitives.OID;
036    import org.apache.directory.shared.asn1.util.BooleanDecoder;
037    import org.apache.directory.shared.asn1.util.BooleanDecoderException;
038    import org.apache.directory.shared.asn1.util.IntegerDecoder;
039    import org.apache.directory.shared.asn1.util.IntegerDecoderException;
040    import org.apache.directory.shared.asn1.util.LongDecoder;
041    import org.apache.directory.shared.asn1.util.LongDecoderException;
042    import org.apache.directory.shared.i18n.I18n;
043    import org.apache.directory.shared.ldap.codec.abandon.AbandonRequestCodec;
044    import org.apache.directory.shared.ldap.codec.actions.AttributeDescAction;
045    import org.apache.directory.shared.ldap.codec.actions.ControlValueAction;
046    import org.apache.directory.shared.ldap.codec.actions.ControlsInitAction;
047    import org.apache.directory.shared.ldap.codec.actions.ErrorMessageAction;
048    import org.apache.directory.shared.ldap.codec.actions.InitAndFilterAction;
049    import org.apache.directory.shared.ldap.codec.actions.InitApproxMatchFilterAction;
050    import org.apache.directory.shared.ldap.codec.actions.InitAssertionValueFilterAction;
051    import org.apache.directory.shared.ldap.codec.actions.InitAttributeDescFilterAction;
052    import org.apache.directory.shared.ldap.codec.actions.InitAttributeDescListAction;
053    import org.apache.directory.shared.ldap.codec.actions.InitEqualityMatchFilterAction;
054    import org.apache.directory.shared.ldap.codec.actions.InitExtensibleMatchFilterAction;
055    import org.apache.directory.shared.ldap.codec.actions.InitGreaterOrEqualFilterAction;
056    import org.apache.directory.shared.ldap.codec.actions.InitLessOrEqualFilterAction;
057    import org.apache.directory.shared.ldap.codec.actions.InitNotFilterAction;
058    import org.apache.directory.shared.ldap.codec.actions.InitOrFilterAction;
059    import org.apache.directory.shared.ldap.codec.actions.InitPresentFilterAction;
060    import org.apache.directory.shared.ldap.codec.actions.InitReferralsAction;
061    import org.apache.directory.shared.ldap.codec.actions.InitSubstringsFilterAction;
062    import org.apache.directory.shared.ldap.codec.actions.MatchedDNAction;
063    import org.apache.directory.shared.ldap.codec.actions.ModifyAttributeValueAction;
064    import org.apache.directory.shared.ldap.codec.actions.ReferralAction;
065    import org.apache.directory.shared.ldap.codec.actions.ResponseAction;
066    import org.apache.directory.shared.ldap.codec.actions.ResponseNameAction;
067    import org.apache.directory.shared.ldap.codec.actions.ResultCodeAction;
068    import org.apache.directory.shared.ldap.codec.actions.SearchResultAttributeValueAction;
069    import org.apache.directory.shared.ldap.codec.actions.ServerSASLCredsAction;
070    import org.apache.directory.shared.ldap.codec.actions.StoreAnyAction;
071    import org.apache.directory.shared.ldap.codec.actions.StoreFinalAction;
072    import org.apache.directory.shared.ldap.codec.actions.StoreMatchValueAction;
073    import org.apache.directory.shared.ldap.codec.actions.StoreReferenceAction;
074    import org.apache.directory.shared.ldap.codec.actions.StoreTypeMatchingRuleAction;
075    import org.apache.directory.shared.ldap.codec.actions.ValueAction;
076    import org.apache.directory.shared.ldap.codec.add.AddRequestCodec;
077    import org.apache.directory.shared.ldap.codec.add.AddResponseCodec;
078    import org.apache.directory.shared.ldap.codec.bind.BindRequestCodec;
079    import org.apache.directory.shared.ldap.codec.bind.BindResponseCodec;
080    import org.apache.directory.shared.ldap.codec.bind.SaslCredentials;
081    import org.apache.directory.shared.ldap.codec.bind.SimpleAuthentication;
082    import org.apache.directory.shared.ldap.codec.compare.CompareRequestCodec;
083    import org.apache.directory.shared.ldap.codec.compare.CompareResponseCodec;
084    import org.apache.directory.shared.ldap.codec.controls.ControlImpl;
085    import org.apache.directory.shared.ldap.codec.del.DelRequestCodec;
086    import org.apache.directory.shared.ldap.codec.del.DelResponseCodec;
087    import org.apache.directory.shared.ldap.codec.extended.ExtendedRequestCodec;
088    import org.apache.directory.shared.ldap.codec.extended.ExtendedResponseCodec;
089    import org.apache.directory.shared.ldap.codec.intermediate.IntermediateResponseCodec;
090    import org.apache.directory.shared.ldap.codec.modify.ModifyRequestCodec;
091    import org.apache.directory.shared.ldap.codec.modify.ModifyResponseCodec;
092    import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNRequestCodec;
093    import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNResponseCodec;
094    import org.apache.directory.shared.ldap.codec.search.ExtensibleMatchFilter;
095    import org.apache.directory.shared.ldap.codec.search.SearchRequestCodec;
096    import org.apache.directory.shared.ldap.codec.search.SearchResultDoneCodec;
097    import org.apache.directory.shared.ldap.codec.search.SearchResultEntryCodec;
098    import org.apache.directory.shared.ldap.codec.search.SearchResultReferenceCodec;
099    import org.apache.directory.shared.ldap.codec.search.SubstringFilter;
100    import org.apache.directory.shared.ldap.codec.unbind.UnBindRequestCodec;
101    import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
102    import org.apache.directory.shared.ldap.filter.SearchScope;
103    import org.apache.directory.shared.ldap.message.AddResponseImpl;
104    import org.apache.directory.shared.ldap.message.BindResponseImpl;
105    import org.apache.directory.shared.ldap.message.CompareResponseImpl;
106    import org.apache.directory.shared.ldap.message.DeleteResponseImpl;
107    import org.apache.directory.shared.ldap.message.ModifyDnResponseImpl;
108    import org.apache.directory.shared.ldap.message.ModifyResponseImpl;
109    import org.apache.directory.shared.ldap.message.ResultCodeEnum;
110    import org.apache.directory.shared.ldap.message.SearchResponseDoneImpl;
111    import org.apache.directory.shared.ldap.message.control.Control;
112    import org.apache.directory.shared.ldap.name.DN;
113    import org.apache.directory.shared.ldap.name.RDN;
114    import org.apache.directory.shared.ldap.util.StringTools;
115    import org.slf4j.Logger;
116    import org.slf4j.LoggerFactory;
117    
118    
119    /**
120     * This class implements the LdapMessage message. All the actions are declared
121     * in this class. As it is a singleton, these declaration are only done once. If
122     * an action is to be added or modified, this is where the work is to be done !
123     * 
124     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
125     * @version $Rev: 923524 $, $Date: 2010-03-16 01:31:36 +0100 (Tue, 16 Mar 2010) $, 
126     */
127    public class LdapMessageGrammar extends AbstractGrammar
128    {
129        // ~ Static fields/initializers
130        // -----------------------------------------------------------------
131    
132        /** The logger */
133        static final Logger log = LoggerFactory.getLogger( LdapMessageGrammar.class );
134    
135        /** A speedup for logger */
136        static final boolean IS_DEBUG = log.isDebugEnabled();
137    
138        /** The instance of grammar. LdapMessageGrammar is a singleton */
139        private static IGrammar instance = new LdapMessageGrammar();
140    
141    
142        // ~ Constructors
143        // -------------------------------------------------------------------------------
144    
145        /**
146         * Creates a new LdapMessageGrammar object.
147         */
148        private LdapMessageGrammar()
149        {
150    
151            name = LdapMessageGrammar.class.getName();
152            statesEnum = LdapStatesEnum.getInstance();
153    
154            // Create the transitions table
155            super.transitions = new GrammarTransition[LdapStatesEnum.LAST_LDAP_STATE][256];
156    
157            // ============================================================================================
158            // Transition from START to LdapMessage
159            // ============================================================================================
160            // This is the starting state :
161            // LDAPMessage --> SEQUENCE { ... 
162            //
163            // We have a LDAPMessage, and the tag must be 0x30. 
164            //
165            // The next state will be LDAP_MESSAGE_STATE
166            //
167            // We will just check that the length is not null
168            super.transitions[LdapStatesEnum.START_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
169                LdapStatesEnum.START_STATE, LdapStatesEnum.LDAP_MESSAGE_STATE, UniversalTag.SEQUENCE_TAG,
170                new GrammarAction( "LdapMessage initialization" )
171                {
172                    public void action( IAsn1Container container ) throws DecoderException
173                    {
174    
175                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
176    
177                        TLV tlv = ldapMessageContainer.getCurrentTLV();
178    
179                        // The Length should not be null
180                        if ( tlv.getLength() == 0 )
181                        {
182                            log.error( I18n.err( I18n.ERR_04066 ) );
183    
184                            // This will generate a PROTOCOL_ERROR
185                            throw new DecoderException( I18n.err( I18n.ERR_04067 ) );
186                        }
187    
188                        return;
189                    }
190                } );
191    
192            // --------------------------------------------------------------------------------------------
193            // Transition from LdapMessage to Message ID
194            // --------------------------------------------------------------------------------------------
195            // LDAPMessage --> ... MessageId ...
196            //
197            // Checks that MessageId is in [0 .. 2147483647] and store the value in
198            // the LdapMessage Object
199            //
200            // (2147483647 = Integer.MAX_VALUE)
201            // The next state will be MESSAGE_ID_STATE
202            //
203            // The message ID will be temporarely stored in the container, because we can't store it
204            // into an object.
205            super.transitions[LdapStatesEnum.LDAP_MESSAGE_STATE][UniversalTag.INTEGER_TAG] = new GrammarTransition(
206                LdapStatesEnum.LDAP_MESSAGE_STATE, LdapStatesEnum.MESSAGE_ID_STATE, UniversalTag.INTEGER_TAG,
207                new GrammarAction( "Store MessageId" )
208                {
209                    public void action( IAsn1Container container ) throws DecoderException
210                    {
211                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
212    
213                        // The current TLV should be a integer
214                        // We get it and store it in MessageId
215                        TLV tlv = ldapMessageContainer.getCurrentTLV();
216    
217                        // The Length should not be null
218                        if ( tlv.getLength() == 0 )
219                        {
220                            log.error( I18n.err( I18n.ERR_04068 ) );
221    
222                            // This will generate a PROTOCOL_ERROR
223                            throw new DecoderException( I18n.err( I18n.ERR_04069 ) );
224                        }
225    
226                        Value value = tlv.getValue();
227    
228                        try
229                        {
230                            int messageId = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
231    
232                            ldapMessageContainer.setMessageId( messageId );
233    
234                            if ( IS_DEBUG )
235                            {
236                                log.debug( "Ldap Message Id has been decoded : " + messageId );
237                            }
238                        }
239                        catch ( IntegerDecoderException ide )
240                        {
241                            log.error( I18n.err( I18n.ERR_04070, StringTools.dumpBytes( value.getData() ), 
242                                            ide.getLocalizedMessage() ) );
243    
244                            // This will generate a PROTOCOL_ERROR                        
245                            throw new DecoderException( ide.getMessage() );
246                        }
247    
248                        return;
249                    }
250                } );
251    
252            // ********************************************************************************************
253            // We have a ProtocolOp :
254            // If the Tag is 0x42, then it's an UnBindRequest.
255            // If the Tag is 0x4A, then it's a DelRequest.
256            // If the Tag is 0x50, then it's an AbandonRequest.
257            // If the Tag is 0x60, then it's a BindRequest.
258            // If the Tag is 0x61, then it's a BindResponse.
259            // If the Tag is 0x63, then it's a SearchRequest.
260            // If the Tag is 0x64, then it's a SearchResultEntry.
261            // If the Tag is 0x65, then it's a SearchResultDone
262            // If the Tag is 0x66, then it's a ModifyRequest
263            // If the Tag is 0x67, then it's a ModifyResponse.
264            // If the Tag is 0x68, then it's an AddRequest.
265            // If the Tag is 0x69, then it's an AddResponse.
266            // If the Tag is 0x6B, then it's a DelResponse.
267            // If the Tag is 0x6C, then it's a ModifyDNRequest.
268            // If the Tag is 0x6D, then it's a ModifyDNResponse.
269            // If the Tag is 0x6E, then it's a CompareRequest
270            // If the Tag is 0x6F, then it's a CompareResponse.
271            // If the Tag is 0x73, then it's a SearchResultReference.
272            // If the Tag is 0x77, then it's an ExtendedRequest.
273            // If the Tag is 0x78, then it's an ExtendedResponse.
274            //
275            // We create the associated object in this transition, and store it into the container.
276            // ********************************************************************************************
277    
278            // --------------------------------------------------------------------------------------------
279            // Transition from Message ID to UnBindRequest Message.
280            // --------------------------------------------------------------------------------------------
281            // LdapMessage ::= ... UnBindRequest ...
282            // unbindRequest ::= [APPLICATION 2] NULL
283            // We have to switch to the UnBindRequest grammar
284            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.UNBIND_REQUEST_TAG] = new GrammarTransition(
285                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.UNBIND_REQUEST_STATE, LdapConstants.UNBIND_REQUEST_TAG,
286                new GrammarAction( "Unbind Request initialization" )
287                {
288                    public void action( IAsn1Container container ) throws DecoderException
289                    {
290    
291                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
292                        
293                        // Create the  UnbindRequest LdapMessage instance and store it in the container
294                        UnBindRequestCodec unbindRequest = new UnBindRequestCodec();
295                        unbindRequest.setMessageId( ldapMessageContainer.getMessageId() );
296                        ldapMessageContainer.setLdapMessage( unbindRequest );
297    
298                        TLV tlv = ldapMessageContainer.getCurrentTLV();
299                        int expectedLength = tlv.getLength();
300    
301                        // The Length should be null
302                        if ( expectedLength != 0 )
303                        {
304                            log.error( I18n.err( I18n.ERR_04071, Integer.valueOf( expectedLength ) ) );
305    
306                            // This will generate a PROTOCOL_ERROR
307                            throw new DecoderException( I18n.err( I18n.ERR_04072 ) );
308                        }
309    
310                        
311                        // We can quit now
312                        ldapMessageContainer.grammarEndAllowed( true );
313    
314                        return;
315                    }
316                } );
317    
318            // --------------------------------------------------------------------------------------------
319            // transition from UnBindRequest Message to Controls.
320            // --------------------------------------------------------------------------------------------
321            //         unbindRequest   UnbindRequest,
322            //         ... },
323            //     controls       [0] Controls OPTIONAL }
324            //
325            super.transitions[LdapStatesEnum.UNBIND_REQUEST_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
326                LdapStatesEnum.UNBIND_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
327                new ControlsInitAction() );
328    
329            // --------------------------------------------------------------------------------------------
330            // Transition from Message ID to DelRequest Message.
331            // --------------------------------------------------------------------------------------------
332            // LdapMessage ::= ... DelRequest ...
333            // delRequest ::= [APPLICATION 10] LDAPDN
334            //
335            // We store the DN to bve deleted into the DelRequest object
336            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.DEL_REQUEST_TAG] = new GrammarTransition(
337                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.DEL_REQUEST_STATE, LdapConstants.DEL_REQUEST_TAG,
338                new GrammarAction( "Init del Request" )
339                {
340                    public void action( IAsn1Container container ) throws DecoderException
341                    {
342                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
343    
344                        // Create the DeleteRequest LdapMessage instance and store it in the container
345                        DelRequestCodec delRequest = new DelRequestCodec();
346                        delRequest.setMessageId( ldapMessageContainer.getMessageId() );
347                        ldapMessageContainer.setLdapMessage( delRequest );
348    
349                        // And store the DN into it
350                        // Get the Value and store it in the DelRequest
351                        TLV tlv = ldapMessageContainer.getCurrentTLV();
352    
353                        // We have to handle the special case of a 0 length matched
354                        // DN
355                        DN entry = null;
356    
357                        if ( tlv.getLength() == 0 )
358                        {
359                            // This will generate a PROTOCOL_ERROR
360                            throw new DecoderException( I18n.err( I18n.ERR_04073 ) );
361                        }
362                        else
363                        {
364                            byte[] dnBytes = tlv.getValue().getData();
365                            String dnStr = StringTools.utf8ToString( dnBytes );
366    
367                            try
368                            {
369                                entry = new DN( dnStr );
370                            }
371                            catch ( LdapInvalidDnException ine )
372                            {
373                                String msg = I18n.err( I18n.ERR_04074, dnStr, StringTools.dumpBytes( dnBytes ),
374                                            ine.getLocalizedMessage() );
375                                log.error( msg );
376    
377                                DeleteResponseImpl response = new DeleteResponseImpl( delRequest.getMessageId() );
378                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
379                                    DN.EMPTY_DN, ine );
380                            }
381    
382                            delRequest.setEntry( entry );
383                        }
384    
385                        // We can have an END transition
386                        ldapMessageContainer.grammarEndAllowed( true );
387    
388                        if ( IS_DEBUG )
389                        {
390                            log.debug( "Deleting DN {}", entry );
391                        }
392                    }
393                } );
394    
395            // --------------------------------------------------------------------------------------------
396            // transition from DelRequest Message to Controls.
397            // --------------------------------------------------------------------------------------------
398            //         delRequest   DelRequest,
399            //         ... },
400            //     controls       [0] Controls OPTIONAL }
401            //
402            super.transitions[LdapStatesEnum.DEL_REQUEST_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
403                LdapStatesEnum.DEL_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
404                new ControlsInitAction() );
405    
406            // --------------------------------------------------------------------------------------------
407            // Transition from Message ID to AbandonRequest Message.
408            // --------------------------------------------------------------------------------------------
409            // LdapMessage ::= ... AbandonRequest ...
410            // AbandonRequest ::= [APPLICATION 16] MessageID
411            //
412            // Create the AbandonRequest object, and store the ID in it
413            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.ABANDON_REQUEST_TAG] = new GrammarTransition(
414                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.ABANDON_REQUEST_STATE, LdapConstants.ABANDON_REQUEST_TAG,
415                new GrammarAction( "Init Abandon Request" )
416                {
417                    public void action( IAsn1Container container ) throws DecoderException
418                    {
419                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
420    
421                        // Create the AbandonRequest LdapMessage instance and store it in the container
422                        AbandonRequestCodec abandonRequest = new AbandonRequestCodec();
423                        abandonRequest.setMessageId( ldapMessageContainer.getMessageId() );
424                        ldapMessageContainer.setLdapMessage( abandonRequest );
425    
426                        // The current TLV should be a integer
427                        // We get it and store it in MessageId
428                        TLV tlv = ldapMessageContainer.getCurrentTLV();
429    
430                        Value value = tlv.getValue();
431    
432                        if ( ( value == null ) || ( value.getData() == null ) )
433                        {
434                            String msg = I18n.err( I18n.ERR_04075 );
435                            log.error( msg );
436    
437                            // This will generate a PROTOCOL_ERROR
438                            throw new DecoderException( msg );
439                        }
440    
441                        try
442                        {
443                            int abandonnedMessageId = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
444    
445                            abandonRequest.setAbandonedMessageId( abandonnedMessageId );
446    
447                            if ( IS_DEBUG )
448                            {
449                                log
450                                    .debug( "AbandonMessage Id has been decoded : {}", Integer
451                                        .valueOf( abandonnedMessageId ) );
452                            }
453    
454                            ldapMessageContainer.grammarEndAllowed( true );
455    
456                            return;
457                        }
458                        catch ( IntegerDecoderException ide )
459                        {
460                            log.error( I18n.err( I18n.ERR_04076, StringTools.dumpBytes( value.getData() ), ide.getMessage() ) );
461    
462                            // This will generate a PROTOCOL_ERROR
463                            throw new DecoderException( ide.getMessage() );
464                        }
465                    }
466                } );
467    
468            // --------------------------------------------------------------------------------------------
469            // transition from AbandonRequest Message to Controls.
470            // --------------------------------------------------------------------------------------------
471            //         abandonRequest   AbandonRequest,
472            //         ... },
473            //     controls       [0] Controls OPTIONAL }
474            //
475            super.transitions[LdapStatesEnum.ABANDON_REQUEST_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
476                LdapStatesEnum.ABANDON_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
477                new ControlsInitAction() );
478    
479            // --------------------------------------------------------------------------------------------
480            // Transition from Message ID to BindRequest Message.
481            // --------------------------------------------------------------------------------------------
482            // LdapMessage ::= ... BindRequest ...
483            // BindRequest ::= [APPLICATION 0] SEQUENCE { ...
484            //
485            // We have to allocate a BindRequest
486            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.BIND_REQUEST_TAG] = new GrammarTransition(
487                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.BIND_REQUEST_STATE, LdapConstants.BIND_REQUEST_TAG,
488                new GrammarAction( "Init BindRequest" )
489                {
490                    public void action( IAsn1Container container ) throws DecoderException
491                    {
492                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
493    
494                        // Create the BindRequest LdapMessage instance and store it in the container
495                        BindRequestCodec bindRequest = new BindRequestCodec();
496                        bindRequest.setMessageId( ldapMessageContainer.getMessageId() );
497                        ldapMessageContainer.setLdapMessage( bindRequest );
498    
499                        // We will check that the request is not null
500                        TLV tlv = ldapMessageContainer.getCurrentTLV();
501    
502                        if ( tlv.getLength() == 0 )
503                        {
504                            String msg = I18n.err( I18n.ERR_04077 );
505                            log.error( msg );
506    
507                            // This will generate a PROTOCOL_ERROR
508                            throw new DecoderException( msg );
509                        }
510                    }
511                } );
512    
513            // --------------------------------------------------------------------------------------------
514            // Transition from BindRequest to version
515            // --------------------------------------------------------------------------------------------
516            // BindRequest ::= [APPLICATION 0] SEQUENCE {
517            //     version                 INTEGER (1 ..  127),
518            //     ....
519            //
520            // The Ldap version is parsed and stored into the BindRequest object
521            super.transitions[LdapStatesEnum.BIND_REQUEST_STATE][UniversalTag.INTEGER_TAG] = new GrammarTransition(
522                LdapStatesEnum.BIND_REQUEST_STATE, LdapStatesEnum.VERSION_STATE, UniversalTag.INTEGER_TAG,
523                new GrammarAction( "Store version" )
524                {
525                    public void action( IAsn1Container container ) throws DecoderException
526                    {
527    
528                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
529                        BindRequestCodec bindRequestMessage = ldapMessageContainer.getBindRequest();
530    
531                        // The current TLV should be a integer between 1 and 127
532                        // We get it and store it in Version
533                        TLV tlv = ldapMessageContainer.getCurrentTLV();
534    
535                        Value value = tlv.getValue();
536    
537                        try
538                        {
539                            int version = IntegerDecoder.parse( value, 1, 127 );
540    
541                            if ( IS_DEBUG )
542                            {
543                                log.debug( "Ldap version ", Integer.valueOf( version ) );
544                            }
545    
546                            bindRequestMessage.setVersion( version );
547                        }
548                        catch ( IntegerDecoderException ide )
549                        {
550                            log.error( I18n.err( I18n.ERR_04078, StringTools.dumpBytes( value.getData() ), ide.getMessage() ) );
551    
552                            // This will generate a PROTOCOL_ERROR
553                            throw new DecoderException( ide.getMessage() );
554                        }
555    
556                        return;
557                    }
558                } );
559    
560            // --------------------------------------------------------------------------------------------
561            // Transition from version to name
562            // --------------------------------------------------------------------------------------------
563            // BindRequest ::= [APPLICATION 0] SEQUENCE {
564            //     ....
565            //     name                    LDAPDN,
566            //     ....
567            //
568            // The Ldap version is parsed and stored into the BindRequest object
569            super.transitions[LdapStatesEnum.VERSION_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
570                LdapStatesEnum.VERSION_STATE, LdapStatesEnum.NAME_STATE, UniversalTag.OCTET_STRING_TAG, new GrammarAction(
571                    "Store Bind Name value" )
572                {
573                    public void action( IAsn1Container container ) throws DecoderException
574                    {
575                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
576                        BindRequestCodec bindRequestMessage = ldapMessageContainer.getBindRequest();
577    
578                        // Get the Value and store it in the BindRequest
579                        TLV tlv = ldapMessageContainer.getCurrentTLV();
580    
581                        // We have to handle the special case of a 0 length name
582                        if ( tlv.getLength() == 0 )
583                        {
584                            bindRequestMessage.setName( DN.EMPTY_DN );
585                        }
586                        else
587                        {
588                            byte[] dnBytes = tlv.getValue().getData();
589                            String dnStr = StringTools.utf8ToString( dnBytes );
590    
591                            try
592                            {
593                                DN dn = new DN( dnStr );
594                                bindRequestMessage.setName( dn );
595                            }
596                            catch ( LdapInvalidDnException ine )
597                            {
598                                String msg = "Incorrect DN given : " + dnStr + " ("
599                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
600                                log.error( "{} : {}", msg, ine.getMessage() );
601    
602                                BindResponseImpl response = new BindResponseImpl( bindRequestMessage.getMessageId() );
603    
604                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
605                                    DN.EMPTY_DN, ine );
606                            }
607                        }
608    
609                        if ( IS_DEBUG )
610                        {
611                            log.debug( " The Bind name is {}", bindRequestMessage.getName() );
612                        }
613    
614                        return;
615                    }
616                } );
617    
618            // --------------------------------------------------------------------------------------------
619            // Transition from name to Simple Authentication
620            // --------------------------------------------------------------------------------------------
621            // BindRequest ::= [APPLICATION 0] SEQUENCE {
622            //     ....
623            //     authentication          AuthenticationChoice }
624            //
625            // AuthenticationChoice ::= CHOICE {
626            //     simple                  [0] OCTET STRING,
627            //     ...
628            //
629            // We have to create an Authentication Object to store the credentials.
630            super.transitions[LdapStatesEnum.NAME_STATE][LdapConstants.BIND_REQUEST_SIMPLE_TAG] = new GrammarTransition(
631                LdapStatesEnum.NAME_STATE, LdapStatesEnum.SIMPLE_STATE, LdapConstants.BIND_REQUEST_SIMPLE_TAG,
632                new GrammarAction( "Store Bind Simple Authentication value" )
633                {
634                    public void action( IAsn1Container container ) throws DecoderException
635                    {
636                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
637    
638                        BindRequestCodec bindRequestMessage = ldapMessageContainer.getBindRequest();
639                        TLV tlv = ldapMessageContainer.getCurrentTLV();
640    
641                        // Allocate the Authentication Object
642                        SimpleAuthentication authentication = null;
643    
644                        authentication = new SimpleAuthentication();
645    
646                        authentication.setParent( bindRequestMessage );
647    
648                        bindRequestMessage.setAuthentication( authentication );
649    
650                        // We have to handle the special case of a 0 length simple
651                        if ( tlv.getLength() == 0 )
652                        {
653                            authentication.setSimple( StringTools.EMPTY_BYTES );
654                        }
655                        else
656                        {
657                            authentication.setSimple( tlv.getValue().getData() );
658                        }
659    
660                        // We can have an END transition
661                        ldapMessageContainer.grammarEndAllowed( true );
662    
663                        if ( IS_DEBUG )
664                        {
665                            log.debug( "The simple authentication is : {}", authentication.getSimple() );
666                        }
667                    }
668                } );
669    
670            // --------------------------------------------------------------------------------------------
671            // transition from Simple Authentication to Controls.
672            // --------------------------------------------------------------------------------------------
673            //         bindRequest   BindRequest,
674            //         ... },
675            //     controls       [0] Controls OPTIONAL }
676            //
677            super.transitions[LdapStatesEnum.SIMPLE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
678                LdapStatesEnum.SIMPLE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
679                new ControlsInitAction() );
680    
681            // --------------------------------------------------------------------------------------------
682            // Transition from name to SASL Authentication
683            // --------------------------------------------------------------------------------------------
684            // BindRequest ::= [APPLICATION 0] SEQUENCE {
685            //     ....
686            //     authentication          AuthenticationChoice }
687            //
688            // AuthenticationChoice ::= CHOICE {
689            //     ...
690            //     sasl                  [3] SaslCredentials }
691            //     ...
692            //
693            // We have to create an Authentication Object to store the credentials.
694            super.transitions[LdapStatesEnum.NAME_STATE][LdapConstants.BIND_REQUEST_SASL_TAG] = new GrammarTransition(
695                LdapStatesEnum.NAME_STATE, LdapStatesEnum.SASL_STATE, LdapConstants.BIND_REQUEST_SASL_TAG,
696                new GrammarAction( "Initialize Bind SASL Authentication" )
697                {
698                    public void action( IAsn1Container container ) throws DecoderException
699                    {
700                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
701                        BindRequestCodec bindRequestMessage = ldapMessageContainer.getBindRequest();
702                        TLV tlv = ldapMessageContainer.getCurrentTLV();
703    
704                        // We will check that the sasl is not null
705                        if ( tlv.getLength() == 0 )
706                        {
707                            String msg = I18n.err( I18n.ERR_04079 );
708                            log.error( msg );
709    
710                            BindResponseImpl response = new BindResponseImpl( bindRequestMessage.getMessageId() );
711    
712                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_CREDENTIALS,
713                                bindRequestMessage.getName(), null );
714                        }
715    
716                        // Create the SaslCredentials Object
717                        SaslCredentials authentication = new SaslCredentials();
718    
719                        authentication.setParent( bindRequestMessage );
720    
721                        bindRequestMessage.setAuthentication( authentication );
722    
723                        if ( IS_DEBUG )
724                        {
725                            log.debug( "The SaslCredential has been created" );
726                        }
727    
728                        return;
729                    }
730                } );
731    
732            // --------------------------------------------------------------------------------------------
733            // Transition from SASL Authentication to Mechanism
734            // --------------------------------------------------------------------------------------------
735            // SaslCredentials ::= SEQUENCE {
736            //     mechanism   LDAPSTRING,
737            //     ...
738            //
739            // We have to store the mechanism.
740            super.transitions[LdapStatesEnum.SASL_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
741                LdapStatesEnum.SASL_STATE, LdapStatesEnum.MECHANISM_STATE, UniversalTag.OCTET_STRING_TAG,
742                new GrammarAction( "Store SASL mechanism" )
743                {
744                    public void action( IAsn1Container container ) throws DecoderException
745                    {
746                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
747                        BindRequestCodec bindRequestMessage = ldapMessageContainer.getBindRequest();
748                        TLV tlv = ldapMessageContainer.getCurrentTLV();
749    
750                        // Get the SaslCredentials Object
751                        SaslCredentials authentication = bindRequestMessage.getSaslAuthentication();
752    
753                        // We have to handle the special case of a 0 length
754                        // mechanism
755                        if ( tlv.getLength() == 0 )
756                        {
757                            authentication.setMechanism( "" );
758                        }
759                        else
760                        {
761                            authentication.setMechanism( StringTools.utf8ToString( tlv.getValue().getData() ) );
762                        }
763    
764                        // We can have an END transition
765                        ldapMessageContainer.grammarEndAllowed( true );
766    
767                        if ( IS_DEBUG )
768                        {
769                            log.debug( "The mechanism is : {}", authentication.getMechanism() );
770                        }
771    
772                        return;
773                    }
774                } );
775    
776            // --------------------------------------------------------------------------------------------
777            // Transition from Mechanism to Credentials
778            // --------------------------------------------------------------------------------------------
779            // SaslCredentials ::= SEQUENCE {
780            //     ...
781            //     credentials OCTET STRING OPTIONAL }
782            //
783            // We have to store the mechanism.
784            super.transitions[LdapStatesEnum.MECHANISM_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
785                LdapStatesEnum.MECHANISM_STATE, LdapStatesEnum.CREDENTIALS_STATE, UniversalTag.OCTET_STRING_TAG,
786                new GrammarAction( "Store SASL credentials" )
787                {
788                    public void action( IAsn1Container container )
789                    {
790                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
791    
792                        BindRequestCodec bindRequestMessage = ldapMessageContainer.getBindRequest();
793    
794                        // Get the Value and store it in the BindRequest
795                        TLV tlv = ldapMessageContainer.getCurrentTLV();
796    
797                        SaslCredentials credentials = bindRequestMessage.getSaslAuthentication();
798    
799                        // We have to handle the special case of a 0 length
800                        // credentials
801                        if ( tlv.getLength() == 0 )
802                        {
803                            credentials.setCredentials( StringTools.EMPTY_BYTES );
804                        }
805                        else
806                        {
807                            credentials.setCredentials( tlv.getValue().getData() );
808                        }
809    
810                        // We can have an END transition
811                        ldapMessageContainer.grammarEndAllowed( true );
812                        if ( IS_DEBUG )
813                        {
814                            log.debug( "The credentials are : {}", credentials.getCredentials() );
815                        }
816    
817                        return;
818                    }
819                } );
820    
821            // --------------------------------------------------------------------------------------------
822            // transition from from Mechanism to Controls.
823            // --------------------------------------------------------------------------------------------
824            //         bindRequest   BindRequest,
825            //         ... },
826            //     controls       [0] Controls OPTIONAL }
827            //
828            super.transitions[LdapStatesEnum.MECHANISM_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
829                LdapStatesEnum.MECHANISM_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
830                new ControlsInitAction() );
831    
832            // --------------------------------------------------------------------------------------------
833            // transition from credentials to Controls.
834            // --------------------------------------------------------------------------------------------
835            //         bindRequest   BindRequest,
836            //         ... },
837            //     controls       [0] Controls OPTIONAL }
838            //
839            super.transitions[LdapStatesEnum.CREDENTIALS_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
840                LdapStatesEnum.CREDENTIALS_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
841                new ControlsInitAction() );
842    
843            // --------------------------------------------------------------------------------------------
844            // Transition from MessageId to BindResponse message 
845            // --------------------------------------------------------------------------------------------
846            // LdapMessage ::= ... BindResponse ...
847            // BindResponse ::= [APPLICATION 1] SEQUENCE { ...
848            // We have to switch to the BindResponse grammar
849            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.BIND_RESPONSE_TAG] = new GrammarTransition(
850                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.BIND_RESPONSE_STATE, LdapConstants.BIND_RESPONSE_TAG,
851                new GrammarAction( "Init BindReponse" )
852                {
853                    public void action( IAsn1Container container )
854                    {
855                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
856    
857                        // Now, we can allocate the BindResponse Object
858                        BindResponseCodec bindResponse = new BindResponseCodec();
859                        bindResponse.setMessageId( ldapMessageContainer.getMessageId() );
860                        ldapMessageContainer.setLdapMessage( bindResponse );
861                    }
862                } );
863    
864            // --------------------------------------------------------------------------------------------
865            // Transition from BindResponse message to Result Code BR 
866            // --------------------------------------------------------------------------------------------
867            // BindResponse ::= [APPLICATION 1] SEQUENCE {
868            //     COMPONENTS OF LDAPResult,
869            //     ...
870            //
871            // LDAPResult ::= SEQUENCE {
872            //     resultCode ENUMERATED { 
873            //         ...
874            // 
875            // Stores the result code into the Bind Response object
876            super.transitions[LdapStatesEnum.BIND_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
877                LdapStatesEnum.BIND_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_BR_STATE, UniversalTag.ENUMERATED_TAG,
878                new ResultCodeAction() );
879    
880            // --------------------------------------------------------------------------------------------
881            // Transition from Result Code BR to Matched DN BR 
882            // --------------------------------------------------------------------------------------------
883            // LDAPResult ::= SEQUENCE {
884            //     ...
885            //     matchedDN LDAPDN,
886            //     ...
887            //
888            // Stores the matched DN
889            super.transitions[LdapStatesEnum.RESULT_CODE_BR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
890                LdapStatesEnum.RESULT_CODE_BR_STATE, LdapStatesEnum.MATCHED_DN_BR_STATE, UniversalTag.OCTET_STRING_TAG,
891                new MatchedDNAction() );
892    
893            // --------------------------------------------------------------------------------------------
894            // Transition from Matched DN BR to Error Message BR 
895            // --------------------------------------------------------------------------------------------
896            // LDAPResult ::= SEQUENCE {
897            //     ...
898            //     errorMessage LDAPString,
899            //     ...
900            //
901            // Stores the error message
902            super.transitions[LdapStatesEnum.MATCHED_DN_BR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
903                LdapStatesEnum.MATCHED_DN_BR_STATE, LdapStatesEnum.ERROR_MESSAGE_BR_STATE, UniversalTag.OCTET_STRING_TAG,
904                new ErrorMessageAction() );
905    
906            // --------------------------------------------------------------------------------------------
907            // Transition from Error Message BR to Server SASL credentials 
908            // --------------------------------------------------------------------------------------------
909            // BindResponse ::= APPLICATION 1] SEQUENCE {
910            //     ...
911            //     serverSaslCreds [7] OCTET STRING OPTIONAL }
912            //
913            // Stores the sasl credentials 
914            super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE][LdapConstants.SERVER_SASL_CREDENTIAL_TAG] = new GrammarTransition(
915                LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE,
916                LdapConstants.SERVER_SASL_CREDENTIAL_TAG, new ServerSASLCredsAction() );
917    
918            // --------------------------------------------------------------------------------------------
919            // Transition from Error Message BR to Referrals BR 
920            // --------------------------------------------------------------------------------------------
921            // LDAPResult ::= SEQUENCE {
922            //     ...
923            //     referral   [3] Referral OPTIONNAL }
924            //
925            // Initialiaze the referrals list 
926            super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE][LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG] = 
927                new GrammarTransition(
928                LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.REFERRALS_BR_STATE,
929                LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, new InitReferralsAction() );
930    
931            // --------------------------------------------------------------------------------------------
932            // Transition from Referrals BR to Referral BR 
933            // --------------------------------------------------------------------------------------------
934            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
935            // URI ::= LDAPString
936            //
937            // Add a first Referral
938            super.transitions[LdapStatesEnum.REFERRALS_BR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
939                LdapStatesEnum.REFERRALS_BR_STATE, LdapStatesEnum.REFERRAL_BR_STATE, UniversalTag.OCTET_STRING_TAG,
940                new ReferralAction() );
941    
942            // --------------------------------------------------------------------------------------------
943            // Transition from Referral BR to Referral BR 
944            // --------------------------------------------------------------------------------------------
945            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
946            // URI ::= LDAPString
947            //
948            // Adda new Referral
949            super.transitions[LdapStatesEnum.REFERRAL_BR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
950                LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.REFERRAL_BR_STATE, UniversalTag.OCTET_STRING_TAG,
951                new ReferralAction() );
952    
953            // --------------------------------------------------------------------------------------------
954            // Transition from Referral BR to Server SASL Credentials 
955            // --------------------------------------------------------------------------------------------
956            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
957            // URI ::= LDAPString
958            //
959            // Adda new Referral
960            super.transitions[LdapStatesEnum.REFERRAL_BR_STATE][LdapConstants.SERVER_SASL_CREDENTIAL_TAG] = new GrammarTransition(
961                LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE,
962                LdapConstants.SERVER_SASL_CREDENTIAL_TAG, new ServerSASLCredsAction() );
963    
964            // --------------------------------------------------------------------------------------------
965            // Transition from Referral BR to Controls 
966            // --------------------------------------------------------------------------------------------
967            //         bindResponse   BindResponse,
968            //         ... },
969            //     controls       [0] Controls OPTIONAL }
970            //
971            // Adda new Referral
972            super.transitions[LdapStatesEnum.REFERRAL_BR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
973                LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
974                new ControlsInitAction() );
975    
976            // --------------------------------------------------------------------------------------------
977            // Transition from Error Message BR to controls 
978            // --------------------------------------------------------------------------------------------
979            //         bindResponse   BindResponse,
980            //         ... },
981            //     controls       [0] Controls OPTIONAL }
982            //
983            //  
984            super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
985                LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
986                new ControlsInitAction() );
987    
988            // --------------------------------------------------------------------------------------------
989            // Transition from Server SASL credentials to Controls 
990            // --------------------------------------------------------------------------------------------
991            //         bindResponse   BindResponse,
992            //         ... },
993            //     controls       [0] Controls OPTIONAL }
994            //
995            super.transitions[LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
996                LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
997                new ControlsInitAction() );
998    
999            // --------------------------------------------------------------------------------------------
1000            // Transition from Result Code to Matched DN 
1001            // --------------------------------------------------------------------------------------------
1002            // LDAPResult ::= SEQUENCE {
1003            //     ...
1004            //     matchedDN LDAPDN,
1005            //     ...
1006            //
1007            // Stores the matched DN
1008            super.transitions[LdapStatesEnum.RESULT_CODE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1009                LdapStatesEnum.RESULT_CODE_STATE, LdapStatesEnum.MATCHED_DN_STATE, UniversalTag.OCTET_STRING_TAG,
1010                new MatchedDNAction() );
1011    
1012            // --------------------------------------------------------------------------------------------
1013            // Transition from Matched DN to Error Message 
1014            // --------------------------------------------------------------------------------------------
1015            // LDAPResult ::= SEQUENCE {
1016            //     ...
1017            //     errorMessage LDAPString,
1018            //     ...
1019            //
1020            // Stores the error message
1021            super.transitions[LdapStatesEnum.MATCHED_DN_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1022                LdapStatesEnum.MATCHED_DN_STATE, LdapStatesEnum.ERROR_MESSAGE_STATE, UniversalTag.OCTET_STRING_TAG,
1023                new ErrorMessageAction() );
1024    
1025            // --------------------------------------------------------------------------------------------
1026            // Transition from Error Message to Referrals
1027            // --------------------------------------------------------------------------------------------
1028            // LDAPResult ::= SEQUENCE {
1029            //     ...
1030            //     referral   [3] Referral OPTIONNAL }
1031            //
1032            // Initialiaze the referrals list 
1033            super.transitions[LdapStatesEnum.ERROR_MESSAGE_STATE][LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG] = 
1034                new GrammarTransition(
1035                LdapStatesEnum.ERROR_MESSAGE_STATE, LdapStatesEnum.REFERRALS_STATE,
1036                LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, new GrammarAction( "Init referrals list" )
1037                {
1038                    public void action( IAsn1Container container ) throws DecoderException
1039                    {
1040                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1041                        LdapResponseCodec response = ldapMessageContainer.getLdapResponse();
1042                        LdapResultCodec ldapResult = response.getLdapResult();
1043    
1044                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1045    
1046                        // If we hae a Referrals sequence, then it should not be empty
1047                        // sasl credentials
1048                        if ( tlv.getLength() == 0 )
1049                        {
1050                            String msg = I18n.err( I18n.ERR_04080 );
1051                            log.error( msg );
1052    
1053                            // This will generate a PROTOCOL_ERROR
1054                            throw new DecoderException( msg );
1055                        }
1056    
1057                        ldapResult.initReferrals();
1058                    }
1059                } );
1060    
1061            // --------------------------------------------------------------------------------------------
1062            // Transition from Referrals to Referral 
1063            // --------------------------------------------------------------------------------------------
1064            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
1065            // URI ::= LDAPString
1066            //
1067            // Add a first Referral
1068            super.transitions[LdapStatesEnum.REFERRALS_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1069                LdapStatesEnum.REFERRALS_STATE, LdapStatesEnum.REFERRAL_STATE, UniversalTag.OCTET_STRING_TAG,
1070                new ReferralAction() );
1071    
1072            // --------------------------------------------------------------------------------------------
1073            // Transition from Referral to Referral 
1074            // --------------------------------------------------------------------------------------------
1075            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
1076            // URI ::= LDAPString
1077            //
1078            // Adda new Referral
1079            super.transitions[LdapStatesEnum.REFERRAL_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1080                LdapStatesEnum.REFERRAL_STATE, LdapStatesEnum.REFERRAL_STATE, UniversalTag.OCTET_STRING_TAG,
1081                new ReferralAction() );
1082    
1083            // --------------------------------------------------------------------------------------------
1084            // Transition from Referral to Controls 
1085            // --------------------------------------------------------------------------------------------
1086            //         xxxResponse   xxxResponse,
1087            //         ... },
1088            //     controls       [0] Controls OPTIONAL }
1089            //
1090            // Adda new Referral
1091            super.transitions[LdapStatesEnum.REFERRAL_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1092                LdapStatesEnum.REFERRAL_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1093                new ControlsInitAction() );
1094    
1095            // --------------------------------------------------------------------------------------------
1096            // Transition from Error Message to controls 
1097            // --------------------------------------------------------------------------------------------
1098            //         xxxResponse   xxxResponse,
1099            //         ... },
1100            //     controls       [0] Controls OPTIONAL }
1101            //
1102            //  
1103            super.transitions[LdapStatesEnum.ERROR_MESSAGE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1104                LdapStatesEnum.ERROR_MESSAGE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1105                new ControlsInitAction() );
1106    
1107            // --------------------------------------------------------------------------------------------
1108            // Transition from MessageId to SearchResultEntry Message.
1109            // --------------------------------------------------------------------------------------------
1110            // LdapMessage ::= ... SearchResultEntry ...
1111            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1112            //
1113            // Initialize the searchResultEntry object
1114            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.SEARCH_RESULT_ENTRY_TAG] = new GrammarTransition(
1115                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE,
1116                LdapConstants.SEARCH_RESULT_ENTRY_TAG, new GrammarAction( "Init SearchResultEntry" )
1117                {
1118                    public void action( IAsn1Container container )
1119                    {
1120                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1121    
1122                        // Now, we can allocate the SearchResultEntry Object
1123                        SearchResultEntryCodec searchResultEntry = new SearchResultEntryCodec();
1124                        searchResultEntry.setMessageId( ldapMessageContainer.getMessageId() );
1125                        ldapMessageContainer.setLdapMessage( searchResultEntry );
1126                    }
1127                } );
1128    
1129            // --------------------------------------------------------------------------------------------
1130            // Transition from SearchResultEntry Message to ObjectName
1131            // --------------------------------------------------------------------------------------------
1132            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1133            // objectName LDAPDN,
1134            // ...
1135            //
1136            // Store the object name.
1137            super.transitions[LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1138                LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE, LdapStatesEnum.OBJECT_NAME_STATE, UniversalTag.OCTET_STRING_TAG,
1139                new GrammarAction( "Store search result entry object name Value" )
1140                {
1141                    public void action( IAsn1Container container ) throws DecoderException
1142                    {
1143    
1144                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1145                        SearchResultEntryCodec searchResultEntry = ldapMessageContainer.getSearchResultEntry();
1146    
1147                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1148    
1149                        DN objectName = DN.EMPTY_DN;
1150    
1151                        // Store the value.
1152                        if ( tlv.getLength() == 0 )
1153                        {
1154                            searchResultEntry.setObjectName( objectName );
1155                        }
1156                        else
1157                        {
1158                            byte[] dnBytes = tlv.getValue().getData();
1159                            String dnStr = StringTools.utf8ToString( dnBytes );
1160    
1161                            try
1162                            {
1163                                objectName = new DN( dnStr );
1164                            }
1165                            catch ( LdapInvalidDnException ine )
1166                            {
1167                                // This is for the client side. We will never decode LdapResult on the server
1168                                String msg = "The DN " + StringTools.dumpBytes( dnBytes ) + "is invalid : "
1169                                    + ine.getMessage();
1170                                log.error( "{} : {}", msg, ine.getMessage() );
1171                                throw new DecoderException( msg, ine );
1172                            }
1173    
1174                            searchResultEntry.setObjectName( objectName );
1175                        }
1176    
1177                        if ( IS_DEBUG )
1178                        {
1179                            log.debug( "Search Result Entry DN found : {}", searchResultEntry.getObjectName() );
1180                        }
1181                    }
1182                } );
1183    
1184            // --------------------------------------------------------------------------------------------
1185            // Transition from ObjectName to AttributesSR
1186            // --------------------------------------------------------------------------------------------
1187            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1188            // ...
1189            // attributes PartialAttributeList }
1190            //
1191            // PartialAttributeList ::= *SEQUENCE* OF SEQUENCE {
1192            // ...
1193            //
1194            // We may have no attributes. Just allows the grammar to end
1195            super.transitions[LdapStatesEnum.OBJECT_NAME_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1196                LdapStatesEnum.OBJECT_NAME_STATE, LdapStatesEnum.ATTRIBUTES_SR_STATE, UniversalTag.SEQUENCE_TAG,
1197                new GrammarAction( "Pop and end allowed" )
1198                {
1199                    public void action( IAsn1Container container ) throws DecoderException
1200                    {
1201                        container.grammarEndAllowed( true );
1202                    }
1203                } );
1204    
1205            // --------------------------------------------------------------------------------------------
1206            // Transition from AttributesSR to PartialAttributesList
1207            // --------------------------------------------------------------------------------------------
1208            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1209            // ...
1210            // attributes PartialAttributeList }
1211            //
1212            // PartialAttributeList ::= SEQUENCE OF *SEQUENCE* {
1213            // ...
1214            //
1215            // nothing to do
1216            super.transitions[LdapStatesEnum.ATTRIBUTES_SR_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1217                LdapStatesEnum.ATTRIBUTES_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE,
1218                UniversalTag.SEQUENCE_TAG, null );
1219    
1220            // --------------------------------------------------------------------------------------------
1221            // Transition from AttributesSR to Controls
1222            // --------------------------------------------------------------------------------------------
1223            //     searchResultEntry SearchResultEntry,
1224            //     ... },
1225            // controls   [0] Controls OPTIONAL }
1226            //
1227            // Initialize the controls
1228            super.transitions[LdapStatesEnum.ATTRIBUTES_SR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1229                LdapStatesEnum.ATTRIBUTES_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1230                new ControlsInitAction() );
1231    
1232            // --------------------------------------------------------------------------------------------
1233            // Transition from PartialAttributesList to typeSR
1234            // --------------------------------------------------------------------------------------------
1235            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1236            // ...
1237            // attributes PartialAttributeList }
1238            //
1239            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1240            //     type  AttributeDescription,
1241            //     ...
1242            //
1243            // Store the attribute's name.
1244            super.transitions[LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1245                LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE, LdapStatesEnum.TYPE_SR_STATE, UniversalTag.OCTET_STRING_TAG,
1246                new GrammarAction( "Store search result entry object name Value" )
1247                {
1248                    public void action( IAsn1Container container ) throws DecoderException
1249                    {
1250                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1251                        SearchResultEntryCodec searchResultEntry = ldapMessageContainer.getSearchResultEntry();
1252    
1253                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1254    
1255                        String type = "";
1256    
1257                        // Store the name
1258                        if ( tlv.getLength() == 0 )
1259                        {
1260                            // The type can't be null
1261                            String msg = I18n.err( I18n.ERR_04081 );
1262                            log.error( msg );
1263                            throw new DecoderException( msg );
1264                        }
1265                        else
1266                        {
1267                            type = StringTools.getType( tlv.getValue().getData() );
1268                            searchResultEntry.addAttributeValues( type );
1269                        }
1270    
1271                        if ( IS_DEBUG )
1272                        {
1273                            log.debug( "Attribute type : {}", type );
1274                        }
1275                    }
1276                } );
1277    
1278            // --------------------------------------------------------------------------------------------
1279            // Transition from typeSR to ValsSR
1280            // --------------------------------------------------------------------------------------------
1281            // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
1282            // ...
1283            // attributes PartialAttributeList }
1284            //
1285            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1286            //     ...
1287            //     vals SET OF AttributeValue }
1288            //
1289            // We may have no value. Just allows the grammar to end
1290            super.transitions[LdapStatesEnum.TYPE_SR_STATE][UniversalTag.SET_TAG] = new GrammarTransition(
1291                LdapStatesEnum.TYPE_SR_STATE, LdapStatesEnum.VALS_SR_STATE, UniversalTag.SET_TAG, new GrammarAction(
1292                    "Grammar end allowed" )
1293                {
1294                    public void action( IAsn1Container container ) throws DecoderException
1295                    {
1296                        container.grammarEndAllowed( true );
1297                    }
1298                } );
1299    
1300            // --------------------------------------------------------------------------------------------
1301            // Transition from ValsSR to AttributeValueSR
1302            // --------------------------------------------------------------------------------------------
1303            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1304            //     ...
1305            //     vals SET OF AttributeValue }
1306            //
1307            // AttributeValue ::= OCTET STRING
1308            // 
1309            // Store the attribute value
1310            super.transitions[LdapStatesEnum.VALS_SR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1311                LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, UniversalTag.OCTET_STRING_TAG,
1312                new SearchResultAttributeValueAction() );
1313    
1314            // --------------------------------------------------------------------------------------------
1315            // Transition from ValsSR to PartialAttributesList
1316            // --------------------------------------------------------------------------------------------
1317            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1318            //     ...
1319            //     vals SET OF AttributeValue }
1320            // 
1321            // Loop when we don't have any attribute value. Nothing to do
1322            super.transitions[LdapStatesEnum.VALS_SR_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1323                LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE, UniversalTag.SEQUENCE_TAG, null );
1324    
1325            // --------------------------------------------------------------------------------------------
1326            // Transition from ValsSR to Controls
1327            // --------------------------------------------------------------------------------------------
1328            //     searchResultEntry SearchResultEntry,
1329            //     ... },
1330            // controls   [0] Controls OPTIONAL }
1331            //
1332            // Initialize the controls
1333            super.transitions[LdapStatesEnum.VALS_SR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1334                LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1335                new ControlsInitAction() );
1336    
1337            // --------------------------------------------------------------------------------------------
1338            // Transition from AttributeValueSR to AttributeValueSR 
1339            // --------------------------------------------------------------------------------------------
1340            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1341            //     ...
1342            //     vals SET OF AttributeValue }
1343            //
1344            // AttributeValue ::= OCTET STRING
1345            // 
1346            // Store the attribute value
1347            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1348                LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE,
1349                UniversalTag.OCTET_STRING_TAG, new SearchResultAttributeValueAction() );
1350    
1351            // --------------------------------------------------------------------------------------------
1352            // Transition from AttributeValueSR to PartialAttributesList
1353            // --------------------------------------------------------------------------------------------
1354            // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
1355            //     ...
1356            //     vals SET OF AttributeValue }
1357            // 
1358            // Loop when we don't have any attribute value. Nothing to do
1359            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1360                LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE,
1361                UniversalTag.SEQUENCE_TAG, null );
1362    
1363            // --------------------------------------------------------------------------------------------
1364            // Transition from AttributeValueSR to Controls
1365            // --------------------------------------------------------------------------------------------
1366            //     searchResultEntry SearchResultEntry,
1367            //     ... },
1368            // controls   [0] Controls OPTIONAL }
1369            //
1370            // Initialize the controls
1371            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1372                LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1373                new ControlsInitAction() );
1374    
1375            // --------------------------------------------------------------------------------------------
1376            // SearchResultDone Message.
1377            // --------------------------------------------------------------------------------------------
1378            // LdapMessage ::= ... SearchResultDone ...
1379            // SearchResultDone ::= [APPLICATION 5] SEQUENCE { ...
1380            // 
1381            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.SEARCH_RESULT_DONE_TAG] = new GrammarTransition(
1382                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_RESULT_DONE_STATE,
1383                LdapConstants.SEARCH_RESULT_DONE_TAG, new GrammarAction( "Init search Result Done" )
1384                {
1385                    public void action( IAsn1Container container )
1386                    {
1387                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1388    
1389                        // Now, we can allocate the SearchResultDone Object
1390                        SearchResultDoneCodec searchResultDone = new SearchResultDoneCodec();
1391                        searchResultDone.setMessageId( ldapMessageContainer.getMessageId() );
1392                        ldapMessageContainer.setLdapMessage( searchResultDone );
1393    
1394                        log.debug( "Search Result Done found" );
1395                    }
1396                } );
1397    
1398            // --------------------------------------------------------------------------------------------
1399            // SearchResultDone Message.
1400            // --------------------------------------------------------------------------------------------
1401            // LdapMessage ::= ... SearchResultDone ...
1402            // SearchResultDone ::= [APPLICATION 5] LDAPResult
1403            //
1404            // LDAPResult ::= SEQUENCE {
1405            //     resultCode    ENUMERATED {
1406            //         ...
1407            // 
1408            // Stores the result code
1409            super.transitions[LdapStatesEnum.SEARCH_RESULT_DONE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
1410                LdapStatesEnum.SEARCH_RESULT_DONE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
1411                new ResultCodeAction() );
1412    
1413            // --------------------------------------------------------------------------------------------
1414            // Transition from Message ID to ModifyRequest Message
1415            // --------------------------------------------------------------------------------------------
1416            // LdapMessage ::= ... ModifyRequest ...
1417            // ModifyRequest ::= [APPLICATION 6] SEQUENCE { ...
1418            //
1419            // Creates the Modify Request object
1420            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.MODIFY_REQUEST_TAG] = new GrammarTransition(
1421                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.MODIFY_REQUEST_STATE, LdapConstants.MODIFY_REQUEST_TAG,
1422                new GrammarAction( "Init ModifyRequest" )
1423                {
1424                    public void action( IAsn1Container container )
1425                    {
1426                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1427                        
1428                        // Now, we can allocate the ModifyRequest Object
1429                        ModifyRequestCodec modifyRequest = new ModifyRequestCodec();
1430                        modifyRequest.setMessageId( ldapMessageContainer.getMessageId() );
1431                        ldapMessageContainer.setLdapMessage( modifyRequest );
1432                    }
1433                } );
1434    
1435            // --------------------------------------------------------------------------------------------
1436            // Transition from ModifyRequest Message to Object
1437            // --------------------------------------------------------------------------------------------
1438            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1439            //     object    LDAPDN,
1440            //     ...
1441            //
1442            // Stores the object DN
1443            super.transitions[LdapStatesEnum.MODIFY_REQUEST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1444                LdapStatesEnum.MODIFY_REQUEST_STATE, LdapStatesEnum.OBJECT_STATE, UniversalTag.OCTET_STRING_TAG,
1445                new GrammarAction( "Store Modify request object Value" )
1446                {
1447                    public void action( IAsn1Container container ) throws DecoderException
1448                    {
1449    
1450                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1451                        ModifyRequestCodec modifyRequest = ldapMessageContainer.getModifyRequest();
1452    
1453                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1454    
1455                        DN object = DN.EMPTY_DN;
1456    
1457                        // Store the value.
1458                        if ( tlv.getLength() == 0 )
1459                        {
1460                            modifyRequest.setObject( object );
1461                        }
1462                        else
1463                        {
1464                            byte[] dnBytes = tlv.getValue().getData();
1465                            String dnStr = StringTools.utf8ToString( dnBytes );
1466    
1467                            try
1468                            {
1469                                object = new DN( dnStr );
1470                            }
1471                            catch ( LdapInvalidDnException ine )
1472                            {
1473                                String msg = "Invalid DN given : " + dnStr + " ("
1474                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
1475                                log.error( "{} : {}", msg, ine.getMessage() );
1476    
1477                                ModifyResponseImpl response = new ModifyResponseImpl( modifyRequest.getMessageId() );
1478                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
1479                                    DN.EMPTY_DN, ine );
1480                            }
1481    
1482                            modifyRequest.setObject( object );
1483                        }
1484    
1485                        if ( IS_DEBUG )
1486                        {
1487                            log.debug( "Modification of DN {}", modifyRequest.getObject() );
1488                        }
1489                    }
1490                } );
1491    
1492            // --------------------------------------------------------------------------------------------
1493            // Transition from Object to modifications
1494            // --------------------------------------------------------------------------------------------
1495            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1496            //     ...
1497            //     modification *SEQUENCE OF* SEQUENCE {
1498            //     ...
1499            //
1500            // Initialize the modifications list
1501            super.transitions[LdapStatesEnum.OBJECT_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1502                LdapStatesEnum.OBJECT_STATE, LdapStatesEnum.MODIFICATIONS_STATE, UniversalTag.SEQUENCE_TAG,
1503                new GrammarAction( "Init modifications array list" )
1504                {
1505                    public void action( IAsn1Container container )
1506                    {
1507    
1508                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1509                        ModifyRequestCodec modifyRequest = ldapMessageContainer.getModifyRequest();
1510    
1511                        modifyRequest.initModifications();
1512                    }
1513                } );
1514    
1515            // --------------------------------------------------------------------------------------------
1516            // Transition from modifications to modification sequence
1517            // --------------------------------------------------------------------------------------------
1518            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1519            //     ...
1520            //     modification SEQUENCE OF *SEQUENCE* {
1521            //     ...
1522            //
1523            // Nothing to do
1524            super.transitions[LdapStatesEnum.MODIFICATIONS_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1525                LdapStatesEnum.MODIFICATIONS_STATE, LdapStatesEnum.MODIFICATIONS_SEQ_STATE, UniversalTag.SEQUENCE_TAG, null );
1526    
1527            // --------------------------------------------------------------------------------------------
1528            // Transition from modification sequence to operation
1529            // --------------------------------------------------------------------------------------------
1530            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1531            //     ...
1532            //     modification SEQUENCE OF SEQUENCE {
1533            //         operation  ENUMERATED {
1534            //             ...
1535            //
1536            // Store operation type
1537            super.transitions[LdapStatesEnum.MODIFICATIONS_SEQ_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
1538                LdapStatesEnum.MODIFICATIONS_SEQ_STATE, LdapStatesEnum.OPERATION_STATE, UniversalTag.ENUMERATED_TAG,
1539                new GrammarAction( "Store operation type" )
1540                {
1541                    public void action( IAsn1Container container ) throws DecoderException
1542                    {
1543    
1544                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1545                        ModifyRequestCodec modifyRequest = ldapMessageContainer.getModifyRequest();
1546    
1547                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1548    
1549                        // Decode the operation type
1550                        int operation = 0;
1551    
1552                        try
1553                        {
1554                            operation = IntegerDecoder.parse( tlv.getValue(), 0, 2 );
1555                        }
1556                        catch ( IntegerDecoderException ide )
1557                        {
1558                            String msg = I18n.err( I18n.ERR_04082, StringTools.dumpBytes( tlv.getValue().getData() ) );
1559                            log.error( msg );
1560    
1561                            // This will generate a PROTOCOL_ERROR
1562                            throw new DecoderException( msg );
1563                        }
1564    
1565                        // Store the current operation.
1566                        modifyRequest.setCurrentOperation( operation );
1567    
1568                        if ( IS_DEBUG )
1569                        {
1570                            switch ( operation )
1571                            {
1572                                case LdapConstants.OPERATION_ADD:
1573                                    log.debug( "Modification operation : ADD" );
1574                                    break;
1575    
1576                                case LdapConstants.OPERATION_DELETE:
1577                                    log.debug( "Modification operation : DELETE" );
1578                                    break;
1579    
1580                                case LdapConstants.OPERATION_REPLACE:
1581                                    log.debug( "Modification operation : REPLACE" );
1582                                    break;
1583                            }
1584                        }
1585    
1586                    }
1587                } );
1588    
1589            // --------------------------------------------------------------------------------------------
1590            // Transition from operation to modification
1591            // --------------------------------------------------------------------------------------------
1592            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1593            //     ...
1594            //     modification SEQUENCE OF SEQUENCE {
1595            //             ...
1596            //         modification   AttributeTypeAndValues }
1597            //
1598            // AttributeTypeAndValues ::= SEQUENCE {
1599            //     ...
1600            //
1601            // Nothing to do
1602            super.transitions[LdapStatesEnum.OPERATION_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1603                LdapStatesEnum.OPERATION_STATE, LdapStatesEnum.MODIFICATION_STATE, UniversalTag.SEQUENCE_TAG, null );
1604    
1605            // --------------------------------------------------------------------------------------------
1606            // Transition from modification to TypeMod
1607            // --------------------------------------------------------------------------------------------
1608            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1609            //     ...
1610            //     modification SEQUENCE OF SEQUENCE {
1611            //             ...
1612            //         modification   AttributeTypeAndValues }
1613            //
1614            // AttributeTypeAndValues ::= SEQUENCE {
1615            //     type AttributeDescription,
1616            //     ...
1617            //
1618            // Stores the type
1619            super.transitions[LdapStatesEnum.MODIFICATION_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1620                LdapStatesEnum.MODIFICATION_STATE, LdapStatesEnum.TYPE_MOD_STATE, UniversalTag.OCTET_STRING_TAG,
1621                new GrammarAction( "Store type" )
1622                {
1623                    public void action( IAsn1Container container ) throws DecoderException
1624                    {
1625    
1626                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1627                        ModifyRequestCodec modifyRequest = ldapMessageContainer.getModifyRequest();
1628    
1629                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1630    
1631                        // Store the value. It can't be null
1632                        String type = null;
1633    
1634                        if ( tlv.getLength() == 0 )
1635                        {
1636                            String msg = I18n.err( I18n.ERR_04083 );
1637                            log.error( msg );
1638    
1639                            ModifyResponseImpl response = new ModifyResponseImpl( modifyRequest.getMessageId() );
1640                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
1641                                modifyRequest.getObject(), null );
1642                        }
1643                        else
1644                        {
1645                            type = StringTools.getType( tlv.getValue().getData() );
1646                            modifyRequest.addAttributeTypeAndValues( type );
1647                        }
1648    
1649                        if ( IS_DEBUG )
1650                        {
1651                            log.debug( "Modifying type : {}", type );
1652                        }
1653                    }
1654                } );
1655    
1656            // --------------------------------------------------------------------------------------------
1657            // Transition from TypeMod to vals
1658            // --------------------------------------------------------------------------------------------
1659            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1660            //     ...
1661            //     modification SEQUENCE OF SEQUENCE {
1662            //             ...
1663            //         modification   AttributeTypeAndValues }
1664            //
1665            // AttributeTypeAndValues ::= SEQUENCE {
1666            //     ...
1667            //     vals SET OF AttributeValue }
1668            //
1669            // Initialize the list of values
1670            super.transitions[LdapStatesEnum.TYPE_MOD_STATE][UniversalTag.SET_TAG] = new GrammarTransition(
1671                LdapStatesEnum.TYPE_MOD_STATE, LdapStatesEnum.VALS_STATE, UniversalTag.SET_TAG, new GrammarAction(
1672                    "Init Attribute vals" )
1673                {
1674                    public void action( IAsn1Container container )
1675                    {
1676    
1677                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1678    
1679                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1680    
1681                        // If the length is null, we store an empty value
1682                        if ( tlv.getLength() == 0 )
1683                        {
1684                            log.debug( "No vals for this attribute" );
1685                        }
1686    
1687                        // We can have an END transition
1688                        ldapMessageContainer.grammarEndAllowed( true );
1689    
1690                        log.debug( "Some vals are to be decoded" );
1691                    }
1692                } );
1693    
1694            // --------------------------------------------------------------------------------------------
1695            // Transition from vals to Attribute Value
1696            // --------------------------------------------------------------------------------------------
1697            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1698            //     ...
1699            //     modification SEQUENCE OF SEQUENCE {
1700            //             ...
1701            //         modification   AttributeTypeAndValues }
1702            //
1703            // AttributeTypeAndValues ::= SEQUENCE {
1704            //     ...
1705            //     vals SET OF AttributeValue }
1706            //
1707            // AttributeValue ::= OCTET STRING
1708            //
1709            // Stores a value
1710            super.transitions[LdapStatesEnum.VALS_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1711                LdapStatesEnum.VALS_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_STATE, UniversalTag.OCTET_STRING_TAG,
1712                new ModifyAttributeValueAction() );
1713    
1714            // --------------------------------------------------------------------------------------------
1715            // Transition from vals to ModificationsSeq
1716            // --------------------------------------------------------------------------------------------
1717            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1718            //     ...
1719            //     modification SEQUENCE OF *SEQUENCE* {
1720            //             ...
1721            //         modification   AttributeTypeAndValues }
1722            //
1723            // AttributeTypeAndValues ::= SEQUENCE {
1724            //     ...
1725            //     vals SET OF AttributeValue }
1726            //
1727            // AttributeValue ::= OCTET STRING
1728            //
1729            // Nothing to do
1730            super.transitions[LdapStatesEnum.VALS_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1731                LdapStatesEnum.VALS_STATE, LdapStatesEnum.MODIFICATIONS_SEQ_STATE, UniversalTag.SEQUENCE_TAG, null );
1732    
1733            // --------------------------------------------------------------------------------------------
1734            // Transition from vals to Controls
1735            // --------------------------------------------------------------------------------------------
1736            //     modifyRequest ModifyRequest,
1737            //     ... },
1738            // controls   [0] Controls OPTIONAL }
1739            //
1740            // Nothing to do
1741            super.transitions[LdapStatesEnum.VALS_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1742                LdapStatesEnum.VALS_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1743                new ControlsInitAction() );
1744    
1745            // --------------------------------------------------------------------------------------------
1746            // Transition from Attribute Value to Attribute Value
1747            // --------------------------------------------------------------------------------------------
1748            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1749            //     ...
1750            //     modification SEQUENCE OF SEQUENCE {
1751            //             ...
1752            //         modification   AttributeTypeAndValues }
1753            //
1754            // AttributeTypeAndValues ::= SEQUENCE {
1755            //     ...
1756            //     vals SET OF AttributeValue }
1757            //
1758            // AttributeValue ::= OCTET STRING
1759            //
1760            // Stores a value
1761            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1762                LdapStatesEnum.ATTRIBUTE_VALUE_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_STATE, UniversalTag.OCTET_STRING_TAG,
1763                new ModifyAttributeValueAction() );
1764    
1765            // --------------------------------------------------------------------------------------------
1766            // Transition from Attribute Value to ModificationsSeq
1767            // --------------------------------------------------------------------------------------------
1768            // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
1769            //     ...
1770            //     modification SEQUENCE OF *SEQUENCE* {
1771            //             ...
1772            //         modification   AttributeTypeAndValues }
1773            //
1774            // AttributeTypeAndValues ::= SEQUENCE {
1775            //     ...
1776            //     vals SET OF AttributeValue }
1777            //
1778            // AttributeValue ::= OCTET STRING
1779            //
1780            // Nothing to do
1781            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1782                LdapStatesEnum.ATTRIBUTE_VALUE_STATE, LdapStatesEnum.MODIFICATIONS_SEQ_STATE, UniversalTag.SEQUENCE_TAG,
1783                null );
1784    
1785            // --------------------------------------------------------------------------------------------
1786            // Transition from Attribute Value to Controls
1787            // --------------------------------------------------------------------------------------------
1788            //     modifyRequest ModifyRequest,
1789            //     ... },
1790            // controls   [0] Controls OPTIONAL }
1791            //
1792            // Nothing to do
1793            super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
1794                LdapStatesEnum.ATTRIBUTE_VALUE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
1795                new ControlsInitAction() );
1796    
1797            // --------------------------------------------------------------------------------------------
1798            // ModifyResponse Message.
1799            // --------------------------------------------------------------------------------------------
1800            // LdapMessage ::= ... ModifyResponse ...
1801            // ModifyResponse ::= [APPLICATION 7] SEQUENCE { ...
1802            // We have to switch to the ModifyResponse grammar
1803            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.MODIFY_RESPONSE_TAG] = new GrammarTransition(
1804                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.MODIFY_RESPONSE_STATE, LdapConstants.MODIFY_RESPONSE_TAG,
1805                new GrammarAction( "Init ModifyResponse" )
1806                {
1807                    public void action( IAsn1Container container )
1808                    {
1809                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1810    
1811                        // Now, we can allocate the ModifyResponse Object
1812                        ModifyResponseCodec modifyResponse = new ModifyResponseCodec();
1813                        modifyResponse.setMessageId( ldapMessageContainer.getMessageId() );
1814                        ldapMessageContainer.setLdapMessage( modifyResponse );
1815    
1816                        log.debug( "Modify response" );
1817                    }
1818                } );
1819    
1820            // --------------------------------------------------------------------------------------------
1821            // ModifyResponse Message.
1822            // --------------------------------------------------------------------------------------------
1823            // LdapMessage ::= ... ModifyResponse ...
1824            // ModifyResponse ::= [APPLICATION 7] LDAPResult
1825            //
1826            // LDAPResult ::= SEQUENCE {
1827            //     resultCode    ENUMERATED {
1828            //         ...
1829            // 
1830            // Stores the result code
1831            super.transitions[LdapStatesEnum.MODIFY_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
1832                LdapStatesEnum.MODIFY_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
1833                new ResultCodeAction() );
1834    
1835            // --------------------------------------------------------------------------------------------
1836            // AddRequest Message.
1837            // --------------------------------------------------------------------------------------------
1838            // LdapMessage ::= ... AddRequest ...
1839            // AddRequest ::= [APPLICATION 8] SEQUENCE { ...
1840            //
1841            // Initialize the AddRequest object
1842            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.ADD_REQUEST_TAG] = new GrammarTransition(
1843                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.ADD_REQUEST_STATE, LdapConstants.ADD_REQUEST_TAG,
1844                new GrammarAction( "Init addRequest" )
1845                {
1846                    public void action( IAsn1Container container ) throws DecoderException
1847                    {
1848    
1849                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1850                        
1851                        // Now, we can allocate the AddRequest Object
1852                        AddRequestCodec addRequest = new AddRequestCodec();
1853                        addRequest.setMessageId( ldapMessageContainer.getMessageId() );
1854                        ldapMessageContainer.setLdapMessage( addRequest );
1855    
1856                        // We will check that the request is not null
1857                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1858    
1859                        if ( tlv.getLength() == 0 )
1860                        {
1861                            String msg = I18n.err( I18n.ERR_04084 );
1862                            log.error( msg );
1863    
1864                            // Will generate a PROTOCOL_ERROR
1865                            throw new DecoderException( msg );
1866                        }
1867                    }
1868                } );
1869    
1870            // --------------------------------------------------------------------------------------------
1871            // Transition from Add Request to Entry
1872            // --------------------------------------------------------------------------------------------
1873            // AddRequest ::= [APPLICATION 8] SEQUENCE {
1874            //     entry           LDAPDN,
1875            //     ...
1876            //
1877            // Stores the DN
1878            super.transitions[LdapStatesEnum.ADD_REQUEST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1879                LdapStatesEnum.ADD_REQUEST_STATE, LdapStatesEnum.ENTRY_STATE, UniversalTag.OCTET_STRING_TAG,
1880                new GrammarAction( "Store add request object Value" )
1881                {
1882                    public void action( IAsn1Container container ) throws DecoderException
1883                    {
1884    
1885                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1886                        AddRequestCodec addRequest = ldapMessageContainer.getAddRequest();
1887    
1888                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1889    
1890                        // Store the entry. It can't be null
1891                        if ( tlv.getLength() == 0 )
1892                        {
1893                            String msg = I18n.err( I18n.ERR_04085 );
1894                            log.error( msg );
1895    
1896                            AddResponseImpl response = new AddResponseImpl( addRequest.getMessageId() );
1897    
1898                            // I guess that trying to add an entry which DN is empty is a naming violation...
1899                            // Not 100% sure though ...
1900                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.NAMING_VIOLATION,
1901                                DN.EMPTY_DN, null );
1902                        }
1903                        else
1904                        {
1905                            DN entryDn = null;
1906                            byte[] dnBytes = tlv.getValue().getData();
1907                            String dnStr = StringTools.utf8ToString( dnBytes );
1908    
1909                            try
1910                            {
1911                                entryDn = new DN( dnStr );
1912                            }
1913                            catch ( LdapInvalidDnException ine )
1914                            {
1915                                String msg = "Invalid DN given : " + dnStr + " ("
1916                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
1917                                log.error( "{} : {}", msg, ine.getMessage() );
1918    
1919                                AddResponseImpl response = new AddResponseImpl( addRequest.getMessageId() );
1920                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
1921                                    DN.EMPTY_DN, ine );
1922                            }
1923    
1924                            addRequest.setEntryDn( entryDn );
1925                        }
1926    
1927                        log.debug( "Adding an entry with DN : {}", addRequest.getEntry() );
1928                    }
1929                } );
1930    
1931            // --------------------------------------------------------------------------------------------
1932            // Transition from Entry to Attributes
1933            // --------------------------------------------------------------------------------------------
1934            // AddRequest ::= [APPLICATION 8] SEQUENCE {
1935            //     ...
1936            //    attributes AttributeList }
1937            //
1938            // AttributeList ::= SEQUENCE OF ... 
1939            //
1940            // Initialize the attribute list
1941            super.transitions[LdapStatesEnum.ENTRY_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1942                LdapStatesEnum.ENTRY_STATE, LdapStatesEnum.ATTRIBUTES_STATE, UniversalTag.SEQUENCE_TAG, null );
1943    
1944            // --------------------------------------------------------------------------------------------
1945            // Transition from Attributes to Attribute
1946            // --------------------------------------------------------------------------------------------
1947            // AttributeList ::= SEQUENCE OF SEQUENCE {
1948            //
1949            // We don't do anything in this transition. The attribute will be created when we met the type
1950            super.transitions[LdapStatesEnum.ATTRIBUTES_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
1951                LdapStatesEnum.ATTRIBUTES_STATE, LdapStatesEnum.ATTRIBUTE_STATE, UniversalTag.SEQUENCE_TAG, null );
1952    
1953            // --------------------------------------------------------------------------------------------
1954            // Transition from Attribute to type
1955            // --------------------------------------------------------------------------------------------
1956            // AttributeList ::= SEQUENCE OF SEQUENCE {
1957            //     type    AttributeDescription,
1958            //     ...
1959            //
1960            // AttributeDescription LDAPString
1961            //
1962            // We store the type in the current attribute
1963            super.transitions[LdapStatesEnum.ATTRIBUTE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
1964                LdapStatesEnum.ATTRIBUTE_STATE, LdapStatesEnum.TYPE_STATE, UniversalTag.OCTET_STRING_TAG,
1965                new GrammarAction( "Store attribute type" )
1966                {
1967                    public void action( IAsn1Container container ) throws DecoderException
1968                    {
1969    
1970                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
1971                        AddRequestCodec addRequest = ldapMessageContainer.getAddRequest();
1972    
1973                        TLV tlv = ldapMessageContainer.getCurrentTLV();
1974    
1975                        // Store the type. It can't be null.
1976                        if ( tlv.getLength() == 0 )
1977                        {
1978                            String msg = I18n.err( I18n.ERR_04086 );
1979                            log.error( msg );
1980    
1981                            AddResponseImpl response = new AddResponseImpl( addRequest.getMessageId() );
1982    
1983                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
1984                                addRequest.getEntry().getDn(), null );
1985                        }
1986    
1987                        String type = StringTools.getType( tlv.getValue().getData() );
1988    
1989                        try
1990                        {
1991                            addRequest.addAttributeType( type );
1992                        }
1993                        catch ( LdapException ne )
1994                        {
1995                            String msg = I18n.err( I18n.ERR_04087 );
1996                            log.error( msg );
1997    
1998                            AddResponseImpl response = new AddResponseImpl( addRequest.getMessageId() );
1999                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
2000                                addRequest.getEntry().getDn(), ne );
2001                        }
2002    
2003                        if ( IS_DEBUG )
2004                        {
2005                            log.debug( "Adding type {}", type );
2006                        }
2007                    }
2008                } );
2009    
2010            // --------------------------------------------------------------------------------------------
2011            // Transition from type to vals
2012            // --------------------------------------------------------------------------------------------
2013            // AttributeList ::= SEQUENCE OF SEQUENCE {
2014            //     ...
2015            //     vals SET OF AttributeValue }
2016            //
2017            // Nothing to do here.
2018            super.transitions[LdapStatesEnum.TYPE_STATE][UniversalTag.SET_TAG] = new GrammarTransition(
2019                LdapStatesEnum.TYPE_STATE, LdapStatesEnum.VALUES_STATE, UniversalTag.SET_TAG, null );
2020    
2021            // --------------------------------------------------------------------------------------------
2022            // Transition from vals to Value
2023            // --------------------------------------------------------------------------------------------
2024            // AttributeList ::= SEQUENCE OF SEQUENCE {
2025            //     ...
2026            //     vals SET OF AttributeValue }
2027            //
2028            // AttributeValue OCTET STRING
2029            //
2030            // Store the value into the current attribute
2031            super.transitions[LdapStatesEnum.VALUES_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2032                LdapStatesEnum.VALUES_STATE, LdapStatesEnum.VALUE_STATE, UniversalTag.OCTET_STRING_TAG, new ValueAction() );
2033    
2034            // --------------------------------------------------------------------------------------------
2035            // Transition from Value to Value
2036            // --------------------------------------------------------------------------------------------
2037            // AttributeList ::= SEQUENCE OF SEQUENCE {
2038            //     ...
2039            //     vals SET OF AttributeValue }
2040            //
2041            // AttributeValue OCTET STRING
2042            //
2043            // Store the value into the current attribute
2044            super.transitions[LdapStatesEnum.VALUE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2045                LdapStatesEnum.VALUE_STATE, LdapStatesEnum.VALUE_STATE, UniversalTag.OCTET_STRING_TAG, new ValueAction() );
2046    
2047            // --------------------------------------------------------------------------------------------
2048            // Transition from Value to Attribute
2049            // --------------------------------------------------------------------------------------------
2050            // AttributeList ::= SEQUENCE OF SEQUENCE {
2051            //
2052            // Nothing to do here.
2053            super.transitions[LdapStatesEnum.VALUE_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
2054                LdapStatesEnum.VALUE_STATE, LdapStatesEnum.ATTRIBUTE_STATE, UniversalTag.SEQUENCE_TAG, null );
2055    
2056            // --------------------------------------------------------------------------------------------
2057            // Transition from Value to Controls
2058            // --------------------------------------------------------------------------------------------
2059            // AttributeList ::= SEQUENCE OF SEQUENCE {
2060            //
2061            // Initialize the controls
2062            super.transitions[LdapStatesEnum.VALUE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2063                LdapStatesEnum.VALUE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2064                new ControlsInitAction() );
2065    
2066            // --------------------------------------------------------------------------------------------
2067            // AddResponse Message.
2068            // --------------------------------------------------------------------------------------------
2069            // LdapMessage ::= ... AddResponse ...
2070            // AddResponse ::= [APPLICATION 9] LDAPResult
2071            // 
2072            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.ADD_RESPONSE_TAG] = new GrammarTransition(
2073                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.ADD_RESPONSE_STATE, LdapConstants.ADD_RESPONSE_TAG,
2074                new GrammarAction( "Init AddResponse" )
2075                {
2076                    public void action( IAsn1Container container ) throws DecoderException
2077                    {
2078    
2079                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2080    
2081                        // Now, we can allocate the AddResponse Object
2082                        AddResponseCodec addResponse = new AddResponseCodec();
2083                        addResponse.setMessageId( ldapMessageContainer.getMessageId() );
2084                        ldapMessageContainer.setLdapMessage( addResponse );
2085    
2086                        // We will check that the request is not null
2087                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2088    
2089                        int expectedLength = tlv.getLength();
2090    
2091                        if ( expectedLength == 0 )
2092                        {
2093                            String msg = I18n.err( I18n.ERR_04088 );
2094                            log.error( msg );
2095                            throw new DecoderException( msg );
2096                        }
2097    
2098                        log.debug( "Add Response" );
2099                    }
2100                } );
2101    
2102            // --------------------------------------------------------------------------------------------
2103            // AddResponse Message.
2104            // --------------------------------------------------------------------------------------------
2105            // LdapMessage ::= ... AddResponse ...
2106            // AddResponse ::= [APPLICATION 9] LDAPResult
2107            //
2108            // LDAPResult ::= SEQUENCE {
2109            //     resultCode    ENUMERATED {
2110            //         ...
2111            // 
2112            // Stores the result code
2113            super.transitions[LdapStatesEnum.ADD_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
2114                LdapStatesEnum.ADD_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
2115                new ResultCodeAction() );
2116    
2117            // --------------------------------------------------------------------------------------------
2118            // DelResponse Message.
2119            // --------------------------------------------------------------------------------------------
2120            // LdapMessage ::= ... DelResponse ...
2121            // DelResponse ::= [APPLICATION 11] LDAPResult
2122            // We have to switch to the DelResponse grammar
2123            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.DEL_RESPONSE_TAG] = new GrammarTransition(
2124                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.DEL_RESPONSE_STATE, LdapConstants.DEL_RESPONSE_TAG,
2125                new GrammarAction( "Init DelResponse" )
2126                {
2127                    public void action( IAsn1Container container )
2128                    {
2129                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2130    
2131                        // Now, we can allocate the DelResponse Object
2132                        DelResponseCodec delResponse = new DelResponseCodec();
2133                        delResponse.setMessageId( ldapMessageContainer.getMessageId() );
2134                        ldapMessageContainer.setLdapMessage( delResponse );
2135    
2136                        log.debug( "Del response " );
2137                    }
2138                } );
2139    
2140            // --------------------------------------------------------------------------------------------
2141            // DelResponse Message.
2142            // --------------------------------------------------------------------------------------------
2143            // LdapMessage ::= ... DelResponse ...
2144            // DelResponse ::= [APPLICATION 11] LDAPResult
2145            //
2146            // LDAPResult ::= SEQUENCE {
2147            //     resultCode    ENUMERATED {
2148            //         ...
2149            // 
2150            // Stores the result code
2151            super.transitions[LdapStatesEnum.DEL_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
2152                LdapStatesEnum.DEL_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
2153                new ResultCodeAction() );
2154    
2155            // --------------------------------------------------------------------------------------------
2156            // Transition from MessageID to ModifydDNRequest Message.
2157            // --------------------------------------------------------------------------------------------
2158            // LdapMessage ::= ... ModifyDNRequest ...
2159            // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { ...
2160            //
2161            // Create the ModifyDNRequest Object
2162            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.MODIFY_DN_REQUEST_TAG] = new GrammarTransition(
2163                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.MODIFY_DN_REQUEST_STATE,
2164                LdapConstants.MODIFY_DN_REQUEST_TAG, new GrammarAction( "Init Modify DN Request" )
2165                {
2166                    public void action( IAsn1Container container )
2167                    {
2168                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2169    
2170                        // Now, we can allocate the ModifyDNRequest Object
2171                        ModifyDNRequestCodec modifyDNRequest = new ModifyDNRequestCodec();
2172                        modifyDNRequest.setMessageId( ldapMessageContainer.getMessageId() );
2173                        ldapMessageContainer.setLdapMessage( modifyDNRequest );
2174    
2175                        log.debug( "ModifyDn request" );
2176                    }
2177                } );
2178    
2179            // --------------------------------------------------------------------------------------------
2180            // Transition from ModifydDNRequest Message to EntryModDN
2181            // --------------------------------------------------------------------------------------------
2182            // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { ...
2183            //     entry LDAPDN,
2184            //     ...
2185            //
2186            // Stores the entry DN
2187            super.transitions[LdapStatesEnum.MODIFY_DN_REQUEST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2188                LdapStatesEnum.MODIFY_DN_REQUEST_STATE, LdapStatesEnum.ENTRY_MOD_DN_STATE, UniversalTag.OCTET_STRING_TAG,
2189                new GrammarAction( "Store entry" )
2190                {
2191                    public void action( IAsn1Container container ) throws DecoderException
2192                    {
2193                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2194    
2195                        ModifyDNRequestCodec modifyDNRequest = ldapMessageContainer.getModifyDnRequest();
2196    
2197                        // Get the Value and store it in the modifyDNRequest
2198                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2199    
2200                        // We have to handle the special case of a 0 length matched
2201                        // DN
2202                        DN entry = null;
2203    
2204                        if ( tlv.getLength() == 0 )
2205                        {
2206                            // This will generate a PROTOCOL_ERROR
2207                            throw new DecoderException( I18n.err( I18n.ERR_04089 ) );
2208                        }
2209                        else
2210                        {
2211                            byte[] dnBytes = tlv.getValue().getData();
2212                            String dnStr = StringTools.utf8ToString( dnBytes );
2213    
2214                            try
2215                            {
2216                                entry = new DN( dnStr );
2217                            }
2218                            catch ( LdapInvalidDnException ine )
2219                            {
2220                                String msg = "Invalid DN given : " + dnStr + " ("
2221                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
2222                                log.error( "{} : {}", msg, ine.getMessage() );
2223    
2224                                ModifyDnResponseImpl response = new ModifyDnResponseImpl( modifyDNRequest.getMessageId() );
2225                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
2226                                    DN.EMPTY_DN, ine );
2227                            }
2228    
2229                            modifyDNRequest.setEntry( entry );
2230                        }
2231    
2232                        if ( IS_DEBUG )
2233                        {
2234                            log.debug( "Modifying DN {}", entry );
2235                        }
2236    
2237                        return;
2238                    }
2239                } );
2240    
2241            // --------------------------------------------------------------------------------------------
2242            // Transition from EntryModDN to NewRDN
2243            // --------------------------------------------------------------------------------------------
2244            // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { ...
2245            //     ...
2246            //     newrdn  RelativeRDN,
2247            //     ...
2248            //
2249            // RelativeRDN :: LDAPString
2250            //
2251            // Stores the new RDN
2252            super.transitions[LdapStatesEnum.ENTRY_MOD_DN_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2253                LdapStatesEnum.ENTRY_MOD_DN_STATE, LdapStatesEnum.NEW_RDN_STATE, UniversalTag.OCTET_STRING_TAG,
2254                new GrammarAction( "Store new RDN" )
2255                {
2256                    public void action( IAsn1Container container ) throws DecoderException
2257                    {
2258                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2259    
2260                        ModifyDNRequestCodec modifyDNRequest = ldapMessageContainer.getModifyDnRequest();
2261    
2262                        // Get the Value and store it in the modifyDNRequest
2263                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2264    
2265                        // We have to handle the special case of a 0 length matched
2266                        // newDN
2267                        RDN newRdn = null;
2268    
2269                        if ( tlv.getLength() == 0 )
2270                        {
2271                            String msg = I18n.err( I18n.ERR_04090 );
2272                            log.error( msg );
2273    
2274                            ModifyDnResponseImpl response = new ModifyDnResponseImpl( modifyDNRequest.getMessageId() );
2275                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
2276                                modifyDNRequest.getEntry(), null );
2277                        }
2278                        else
2279                        {
2280                            byte[] dnBytes = tlv.getValue().getData();
2281                            String dnStr = StringTools.utf8ToString( dnBytes );
2282    
2283                            try
2284                            {
2285                                DN dn = new DN( dnStr );
2286                                newRdn = dn.getRdn( 0 );
2287                            }
2288                            catch ( LdapInvalidDnException ine )
2289                            {
2290                                String msg = "Invalid new RDN given : " + dnStr + " ("
2291                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
2292                                log.error( "{} : {}", msg, ine.getMessage() );
2293    
2294                                ModifyDnResponseImpl response = new ModifyDnResponseImpl( modifyDNRequest.getMessageId() );
2295                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
2296                                    modifyDNRequest.getEntry(), ine );
2297                            }
2298    
2299                            modifyDNRequest.setNewRDN( newRdn );
2300                        }
2301    
2302                        if ( IS_DEBUG )
2303                        {
2304                            log.debug( "Modifying with new RDN {}", newRdn );
2305                        }
2306                    }
2307                } );
2308    
2309            // --------------------------------------------------------------------------------------------
2310            // Transition from NewRDN to DeleteOldRDN
2311            // --------------------------------------------------------------------------------------------
2312            // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { ...
2313            //     ...
2314            //     deleteoldrdn BOOLEAN,
2315            //     ...
2316            //
2317            // Stores the deleteOldRDN flag
2318            super.transitions[LdapStatesEnum.NEW_RDN_STATE][UniversalTag.BOOLEAN_TAG] = new GrammarTransition(
2319                LdapStatesEnum.NEW_RDN_STATE, LdapStatesEnum.DELETE_OLD_RDN_STATE, UniversalTag.BOOLEAN_TAG,
2320                new GrammarAction( "Store matching dnAttributes Value" )
2321                {
2322                    public void action( IAsn1Container container ) throws DecoderException
2323                    {
2324                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2325                        ModifyDNRequestCodec modifyDNRequest = ldapMessageContainer.getModifyDnRequest();
2326    
2327                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2328    
2329                        // We get the value. If it's a 0, it's a FALSE. If it's
2330                        // a FF, it's a TRUE. Any other value should be an error,
2331                        // but we could relax this constraint. So if we have
2332                        // something
2333                        // which is not 0, it will be interpreted as TRUE, but we
2334                        // will generate a warning.
2335                        Value value = tlv.getValue();
2336    
2337                        try
2338                        {
2339                            modifyDNRequest.setDeleteOldRDN( BooleanDecoder.parse( value ) );
2340                        }
2341                        catch ( BooleanDecoderException bde )
2342                        {
2343                            log.error( I18n.err( I18n.ERR_04091, StringTools.dumpBytes( value.getData() ), bde.getMessage() ) );
2344    
2345                            // This will generate a PROTOCOL_ERROR                        
2346                            throw new DecoderException( bde.getMessage() );
2347                        }
2348    
2349                        // We can have an END transition
2350                        ldapMessageContainer.grammarEndAllowed( true );
2351    
2352                        if ( IS_DEBUG )
2353                        {
2354                            if ( modifyDNRequest.isDeleteOldRDN() )
2355                            {
2356                                log.debug( " Old RDN attributes will be deleted" );
2357                            }
2358                            else
2359                            {
2360                                log.debug( " Old RDN attributes will be retained" );
2361                            }
2362                        }
2363                    }
2364                } );
2365    
2366            // --------------------------------------------------------------------------------------------
2367            // Transition from DeleteOldRDN to NewSuperior
2368            // --------------------------------------------------------------------------------------------
2369            // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { ...
2370            //     ...
2371            //     newSuperior [0] LDAPDN OPTIONAL }
2372            //
2373            // Stores the new superior
2374            super.transitions[LdapStatesEnum.DELETE_OLD_RDN_STATE][LdapConstants.MODIFY_DN_REQUEST_NEW_SUPERIOR_TAG] = 
2375                new GrammarTransition(
2376                LdapStatesEnum.DELETE_OLD_RDN_STATE, LdapStatesEnum.NEW_SUPERIOR_STATE,
2377                LdapConstants.MODIFY_DN_REQUEST_NEW_SUPERIOR_TAG, new GrammarAction( "Store new superior" )
2378                {
2379                    public void action( IAsn1Container container ) throws DecoderException
2380                    {
2381                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2382                        ModifyDNRequestCodec modifyDNRequest = ldapMessageContainer.getModifyDnRequest();
2383    
2384                        // Get the Value and store it in the modifyDNRequest
2385                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2386    
2387                        // We have to handle the special case of a 0 length matched
2388                        // DN
2389                        DN newSuperior = DN.EMPTY_DN;
2390    
2391                        if ( tlv.getLength() == 0 )
2392                        {
2393    
2394                            if ( modifyDNRequest.isDeleteOldRDN() )
2395                            {
2396                                // This will generate a PROTOCOL_ERROR
2397                                throw new DecoderException( I18n.err( I18n.ERR_04092 ) );
2398                            }
2399                            else
2400                            {
2401                                log.warn( "The new superior is null, so we will change the entry" );
2402                            }
2403    
2404                            modifyDNRequest.setNewSuperior( newSuperior );
2405                        }
2406                        else
2407                        {
2408                            byte[] dnBytes = tlv.getValue().getData();
2409                            String dnStr = StringTools.utf8ToString( dnBytes );
2410    
2411                            try
2412                            {
2413                                newSuperior = new DN( dnStr );
2414                            }
2415                            catch ( LdapInvalidDnException ine )
2416                            {
2417                                String msg = "Invalid new superior DN given : " + dnStr
2418                                    + " (" + StringTools.dumpBytes( dnBytes ) + ") is invalid";
2419                                log.error( "{} : {}", msg, ine.getMessage() );
2420    
2421                                ModifyDnResponseImpl response = new ModifyDnResponseImpl( modifyDNRequest.getMessageId() );
2422                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
2423                                    modifyDNRequest.getEntry(), ine );
2424                            }
2425    
2426                            modifyDNRequest.setNewSuperior( newSuperior );
2427                        }
2428    
2429                        // We can have an END transition
2430                        ldapMessageContainer.grammarEndAllowed( true );
2431    
2432                        if ( IS_DEBUG )
2433                        {
2434                            log.debug( "New superior DN {}", newSuperior );
2435                        }
2436    
2437                        return;
2438                    }
2439                } );
2440    
2441            // --------------------------------------------------------------------------------------------
2442            // Transition from DeleteOldRDN to Controls
2443            // --------------------------------------------------------------------------------------------
2444            //     modifyDNRequest ModifyDNRequest,
2445            //     ... },
2446            // controls   [0] Controls OPTIONAL }
2447            //
2448            // Stores the new superior
2449            super.transitions[LdapStatesEnum.DELETE_OLD_RDN_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2450                LdapStatesEnum.DELETE_OLD_RDN_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2451                new ControlsInitAction() );
2452    
2453            // --------------------------------------------------------------------------------------------
2454            // Transition from DeleteOldRDN to Controls
2455            // --------------------------------------------------------------------------------------------
2456            //     modifyDNRequest ModifyDNRequest,
2457            //     ... },
2458            // controls   [0] Controls OPTIONAL }
2459            //
2460            // Stores the new superior
2461            super.transitions[LdapStatesEnum.NEW_SUPERIOR_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2462                LdapStatesEnum.NEW_SUPERIOR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2463                new ControlsInitAction() );
2464    
2465            // --------------------------------------------------------------------------------------------
2466            // Transition from MessageID to ModifyDNResponse Message.
2467            // --------------------------------------------------------------------------------------------
2468            // ModifyDNResponse ::= [APPLICATION 13] SEQUENCE {
2469            //     ...
2470            //
2471            // Creates the ModifyDNResponse
2472            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.MODIFY_DN_RESPONSE_TAG] = new GrammarTransition(
2473                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.MODIFY_DN_RESPONSE_STATE,
2474                LdapConstants.MODIFY_DN_RESPONSE_TAG, new GrammarAction( "Init ModifyDNResponse" )
2475                {
2476                    public void action( IAsn1Container container )
2477                    {
2478    
2479                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2480                        
2481                        // Now, we can allocate the ModifyDnResponse Object
2482                        ModifyDNResponseCodec modifyDnResponse = new ModifyDNResponseCodec();
2483                        modifyDnResponse.setMessageId( ldapMessageContainer.getMessageId() );
2484                        ldapMessageContainer.setLdapMessage( modifyDnResponse );
2485    
2486                        log.debug( "Modify DN response " );
2487                    }
2488                } );
2489    
2490            // --------------------------------------------------------------------------------------------
2491            // Transition from ModifyDNResponse Message to Result Code
2492            // --------------------------------------------------------------------------------------------
2493            // LdapMessage ::= ... ModifyDNResponse ...
2494            // ModifyDNResponse ::= [APPLICATION 13] LDAPResult
2495            //
2496            // LDAPResult ::= SEQUENCE {
2497            //     resultCode    ENUMERATED {
2498            //         ...
2499            // 
2500            // Stores the result co        //     modifyDNRequest ModifyDNRequest,
2501            //     ... },
2502            // controls   [0] Controls OPTIONAL }
2503            super.transitions[LdapStatesEnum.MODIFY_DN_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
2504                LdapStatesEnum.MODIFY_DN_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
2505                new ResultCodeAction() );
2506    
2507            // --------------------------------------------------------------------------------------------
2508            // Transition from Message ID to CompareResquest
2509            // --------------------------------------------------------------------------------------------
2510            // LdapMessage ::= ... CompareRequest ...
2511            // 
2512            // CompareRequest ::= [APPLICATION 14] SEQUENCE {
2513            // ...
2514            //
2515            // Initialize the Compare Request object 
2516            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.COMPARE_REQUEST_TAG] = new GrammarTransition(
2517                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.COMPARE_REQUEST_STATE, LdapConstants.COMPARE_REQUEST_TAG,
2518                new GrammarAction( "Init Compare Request" )
2519                {
2520                    public void action( IAsn1Container container )
2521                    {
2522                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2523    
2524                        // Now, we can allocate the CompareRequest Object
2525                        CompareRequestCodec compareRequest = new CompareRequestCodec();
2526                        compareRequest.setMessageId( ldapMessageContainer.getMessageId() );
2527                        ldapMessageContainer.setLdapMessage( compareRequest );
2528    
2529                        log.debug( "Compare Request" );
2530                    }
2531                } );
2532    
2533            // --------------------------------------------------------------------------------------------
2534            // Transition from CompareResquest to entryComp
2535            // --------------------------------------------------------------------------------------------
2536            // CompareRequest ::= [APPLICATION 14] SEQUENCE {
2537            //     entry    LDAPDN,
2538            //     ...
2539            //
2540            // Stores the compared DN
2541            super.transitions[LdapStatesEnum.COMPARE_REQUEST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2542                LdapStatesEnum.COMPARE_REQUEST_STATE, LdapStatesEnum.ENTRY_COMP_STATE, UniversalTag.OCTET_STRING_TAG,
2543                new GrammarAction( "Store entry" )
2544                {
2545                    public void action( IAsn1Container container ) throws DecoderException
2546                    {
2547    
2548                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2549                        CompareRequestCodec compareRequest = ldapMessageContainer.getCompareRequest();
2550    
2551                        // Get the Value and store it in the CompareRequest
2552                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2553                        DN entry = null;
2554    
2555                        // We have to handle the special case of a 0 length matched
2556                        // DN
2557                        if ( tlv.getLength() == 0 )
2558                        {
2559                            // This will generate a PROTOCOL_ERROR
2560                            throw new DecoderException( I18n.err( I18n.ERR_04089 ) );
2561                        }
2562                        else
2563                        {
2564                            byte[] dnBytes = tlv.getValue().getData();
2565                            String dnStr = StringTools.utf8ToString( dnBytes );
2566    
2567                            try
2568                            {
2569                                entry = new DN( dnStr );
2570                            }
2571                            catch ( LdapInvalidDnException ine )
2572                            {
2573                                String msg = "Invalid DN given : " + dnStr + " ("
2574                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
2575                                log.error( "{} : {}", msg, ine.getMessage() );
2576    
2577                                CompareResponseImpl response = new CompareResponseImpl( compareRequest.getMessageId() );
2578                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
2579                                    DN.EMPTY_DN, ine );
2580                            }
2581    
2582                            compareRequest.setEntry( entry );
2583                        }
2584    
2585                        if ( IS_DEBUG )
2586                        {
2587                            log.debug( "Comparing DN {}", entry );
2588                        }
2589                    }
2590                } );
2591    
2592            // --------------------------------------------------------------------------------------------
2593            // Transition from entryComp to ava
2594            // --------------------------------------------------------------------------------------------
2595            // CompareRequest ::= [APPLICATION 14] SEQUENCE {
2596            //     ...
2597            //     ava AttributeValueAssertion }
2598            //
2599            // AttributeValueAssertion ::= SEQUENCE {
2600            // 
2601            // Nothing to do
2602            super.transitions[LdapStatesEnum.ENTRY_COMP_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
2603                LdapStatesEnum.ENTRY_COMP_STATE, LdapStatesEnum.AVA_STATE, UniversalTag.SEQUENCE_TAG, null );
2604    
2605            // --------------------------------------------------------------------------------------------
2606            // Transition from ava to AttributeDesc
2607            // --------------------------------------------------------------------------------------------
2608            // AttributeValueAssertion ::= SEQUENCE {
2609            //     attributeDesc AttributeDescription,
2610            //     ...
2611            //
2612            // AttributeDescription LDAPString
2613            // 
2614            // Stores the attribute description
2615            super.transitions[LdapStatesEnum.AVA_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2616                LdapStatesEnum.AVA_STATE, LdapStatesEnum.ATTRIBUTE_DESC_STATE, UniversalTag.OCTET_STRING_TAG,
2617                new GrammarAction( "Store attribute desc" )
2618                {
2619                    public void action( IAsn1Container container ) throws DecoderException
2620                    {
2621    
2622                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2623    
2624                        // Get the CompareRequest Object
2625                        CompareRequestCodec compareRequest = ldapMessageContainer.getCompareRequest();
2626    
2627                        // Get the Value and store it in the CompareRequest
2628                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2629    
2630                        // We have to handle the special case of a 0 length matched
2631                        // DN
2632                        if ( tlv.getLength() == 0 )
2633                        {
2634                            String msg = I18n.err( I18n.ERR_04093 );
2635                            log.error( msg );
2636                            CompareResponseImpl response = new CompareResponseImpl( compareRequest.getMessageId() );
2637    
2638                            throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
2639                                compareRequest.getEntry(), null );
2640                        }
2641    
2642                        String type = StringTools.getType( tlv.getValue().getData() );
2643                        compareRequest.setAttributeDesc( type );
2644    
2645                        if ( IS_DEBUG )
2646                        {
2647                            log.debug( "Comparing attribute description {}", compareRequest.getAttributeDesc() );
2648                        }
2649                    }
2650                } );
2651    
2652            // --------------------------------------------------------------------------------------------
2653            // Transition from AttributeDesc to Assertion Value
2654            // --------------------------------------------------------------------------------------------
2655            // AttributeValueAssertion ::= SEQUENCE {
2656            //     ...
2657            //     assertionValue AssertionValue }
2658            //
2659            // AssertionValue OCTET STRING
2660            // 
2661            // Stores the attribute value
2662            super.transitions[LdapStatesEnum.ATTRIBUTE_DESC_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
2663                LdapStatesEnum.ATTRIBUTE_DESC_STATE, LdapStatesEnum.ASSERTION_VALUE_STATE, UniversalTag.OCTET_STRING_TAG,
2664                new GrammarAction( "Store assertion value" )
2665                {
2666                    public void action( IAsn1Container container )
2667                    {
2668    
2669                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2670    
2671                        // Get the CompareRequest Object
2672                        CompareRequestCodec compareRequest = ldapMessageContainer.getCompareRequest();
2673    
2674                        // Get the Value and store it in the CompareRequest
2675                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2676    
2677                        // We have to handle the special case of a 0 length value
2678                        if ( tlv.getLength() == 0 )
2679                        {
2680                            compareRequest.setAssertionValue( "" );
2681                        }
2682                        else
2683                        {
2684                            if ( ldapMessageContainer.isBinary( compareRequest.getAttributeDesc() ) )
2685                            {
2686                                compareRequest.setAssertionValue( tlv.getValue().getData() );
2687    
2688                                if ( IS_DEBUG )
2689                                {
2690                                    log.debug( "Comparing attribute value {}", StringTools
2691                                        .dumpBytes( ( byte[] ) compareRequest.getAssertionValue() ) );
2692                                }
2693                            }
2694                            else
2695                            {
2696                                compareRequest.setAssertionValue( StringTools.utf8ToString( tlv.getValue().getData() ) );
2697    
2698                                if ( log.isDebugEnabled() )
2699                                {
2700                                    log.debug( "Comparing attribute value {}", compareRequest.getAssertionValue() );
2701                                }
2702                            }
2703                        }
2704    
2705                        // We can have an END transition
2706                        ldapMessageContainer.grammarEndAllowed( true );
2707                    }
2708                } );
2709    
2710            // --------------------------------------------------------------------------------------------
2711            // Transition from Assertion Value to Controls
2712            // --------------------------------------------------------------------------------------------
2713            // AttributeValueAssertion ::= SEQUENCE {
2714            //     ...
2715            //     assertionValue AssertionValue }
2716            //
2717            // AssertionValue OCTET STRING
2718            // 
2719            // Stores the attribute value
2720            super.transitions[LdapStatesEnum.ASSERTION_VALUE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2721                LdapStatesEnum.ASSERTION_VALUE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2722                new ControlsInitAction() );
2723    
2724            // --------------------------------------------------------------------------------------------
2725            // CompareResponse Message.
2726            // --------------------------------------------------------------------------------------------
2727            // LdapMessage ::= ... CompareResponse ...
2728            // CompareResponse ::= [APPLICATION 15] LDAPResult
2729            // We have to switch to the CompareResponse grammar
2730            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.COMPARE_RESPONSE_TAG] = new GrammarTransition(
2731                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.COMPARE_RESPONSE_STATE, LdapConstants.COMPARE_RESPONSE_TAG,
2732                new GrammarAction( "Init CompareResponse" )
2733                {
2734                    public void action( IAsn1Container container ) throws DecoderException
2735                    {
2736    
2737                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2738    
2739                        // Now, we can allocate the CompareResponse Object
2740                        CompareResponseCodec compareResponse = new CompareResponseCodec();
2741                        compareResponse.setMessageId( ldapMessageContainer.getMessageId() );
2742                        ldapMessageContainer.setLdapMessage( compareResponse );
2743    
2744                        // We will check that the request is not null
2745                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2746    
2747                        if ( tlv.getLength() == 0 )
2748                        {
2749                            String msg = I18n.err( I18n.ERR_04094 );
2750                            log.error( msg );
2751                            throw new DecoderException( msg );
2752                        }
2753    
2754                        log.debug( "Compare response " );
2755                    }
2756                } );
2757    
2758            // --------------------------------------------------------------------------------------------
2759            // CompareResponse Message.
2760            // --------------------------------------------------------------------------------------------
2761            // LdapMessage ::= ... CompareResponse ...
2762            // CompareResponse ::= [APPLICATION 15] LDAPResult
2763            //
2764            // LDAPResult ::= SEQUENCE {
2765            //     resultCode    ENUMERATED {
2766            //         ...
2767            // 
2768            // Stores the result code
2769            super.transitions[LdapStatesEnum.COMPARE_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
2770                LdapStatesEnum.COMPARE_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
2771                new ResultCodeAction() );
2772    
2773            // --------------------------------------------------------------------------------------------
2774            // Transition from MessageID to SearchResultReference Message.
2775            // --------------------------------------------------------------------------------------------
2776            // LdapMessage ::= ... SearchResultReference ...
2777            // SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
2778            //
2779            // Initialization of SearchResultReference object
2780            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.SEARCH_RESULT_REFERENCE_TAG] = new GrammarTransition(
2781                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_RESULT_REFERENCE_STATE,
2782                LdapConstants.SEARCH_RESULT_REFERENCE_TAG, new GrammarAction( "Init SearchResultReference" )
2783                {
2784                    public void action( IAsn1Container container ) throws DecoderException
2785                    {
2786                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2787                        
2788                        // Now, we can allocate the SearchResultReference Object
2789                        SearchResultReferenceCodec searchResultReference = new SearchResultReferenceCodec();
2790                        searchResultReference.setMessageId( ldapMessageContainer.getMessageId() );
2791                        ldapMessageContainer.setLdapMessage( searchResultReference );
2792    
2793                        log.debug( "SearchResultReference response " );
2794                    }
2795                } );
2796    
2797            // --------------------------------------------------------------------------------------------
2798            // Transition from SearchResultReference Message to Reference
2799            // --------------------------------------------------------------------------------------------
2800            // LdapMessage ::= ... SearchResultReference ...
2801            // SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
2802            //
2803            // Initialization of SearchResultReference object
2804            super.transitions[LdapStatesEnum.SEARCH_RESULT_REFERENCE_STATE][UniversalTag.OCTET_STRING] = new GrammarTransition(
2805                LdapStatesEnum.SEARCH_RESULT_REFERENCE_STATE, LdapStatesEnum.REFERENCE_STATE, UniversalTag.OCTET_STRING,
2806                new StoreReferenceAction() );
2807    
2808            // --------------------------------------------------------------------------------------------
2809            // Transition from Reference to Reference
2810            // --------------------------------------------------------------------------------------------
2811            // LdapMessage ::= ... SearchResultReference ...
2812            // SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
2813            //
2814            // Initialization of SearchResultReference object
2815            super.transitions[LdapStatesEnum.REFERENCE_STATE][UniversalTag.OCTET_STRING] = new GrammarTransition(
2816                LdapStatesEnum.REFERENCE_STATE, LdapStatesEnum.REFERENCE_STATE, UniversalTag.OCTET_STRING,
2817                new StoreReferenceAction() );
2818    
2819            // --------------------------------------------------------------------------------------------
2820            // Transition from Reference to Controls
2821            // --------------------------------------------------------------------------------------------
2822            //     searchResultReference SearchResultReference,
2823            //     ... },
2824            // controls   [0] Controls OPTIONAL }
2825            //
2826            // Initialization the controls
2827            super.transitions[LdapStatesEnum.REFERENCE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2828                LdapStatesEnum.REFERENCE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2829                new ControlsInitAction() );
2830    
2831            // --------------------------------------------------------------------------------------------
2832            // Transition from Message Id to ExtendedRequest Message
2833            // --------------------------------------------------------------------------------------------
2834            // LdapMessage ::= ... ExtendedRequest ...
2835            // ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
2836            //
2837            // Creates the ExtendedRequest object
2838            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.EXTENDED_REQUEST_TAG] = new GrammarTransition(
2839                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.EXTENDED_REQUEST_STATE, LdapConstants.EXTENDED_REQUEST_TAG,
2840                new GrammarAction( "Init Extended Request" )
2841                {
2842                    public void action( IAsn1Container container ) throws DecoderException
2843                    {
2844                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2845                        
2846                        // Now, we can allocate the ExtendedRequest Object
2847                        ExtendedRequestCodec extendedRequest = new ExtendedRequestCodec();
2848                        extendedRequest.setMessageId( ldapMessageContainer.getMessageId() );
2849                        ldapMessageContainer.setLdapMessage( extendedRequest );
2850    
2851                        log.debug( "Extended request" );
2852                    }
2853                } );
2854    
2855            // --------------------------------------------------------------------------------------------
2856            // Transition from ExtendedRequest Message to RequestName
2857            // --------------------------------------------------------------------------------------------
2858            // ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
2859            //     requestName [0] LDAPOID,
2860            //     ...
2861            //
2862            // Stores the name
2863            super.transitions[LdapStatesEnum.EXTENDED_REQUEST_STATE][LdapConstants.EXTENDED_REQUEST_NAME_TAG] = new GrammarTransition(
2864                LdapStatesEnum.EXTENDED_REQUEST_STATE, LdapStatesEnum.REQUEST_NAME_STATE,
2865                LdapConstants.EXTENDED_REQUEST_NAME_TAG, new GrammarAction( "Store name" )
2866                {
2867                    public void action( IAsn1Container container ) throws DecoderException
2868                    {
2869                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2870    
2871                        // We can allocate the ExtendedRequest Object
2872                        ExtendedRequestCodec extendedRequest = ldapMessageContainer.getExtendedRequest();
2873    
2874                        // Get the Value and store it in the ExtendedRequest
2875                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2876    
2877                        // We have to handle the special case of a 0 length matched
2878                        // OID
2879                        if ( tlv.getLength() == 0 )
2880                        {
2881                            log.error( I18n.err( I18n.ERR_04095 ) );
2882                            // This will generate a PROTOCOL_ERROR                        
2883                            throw new DecoderException( I18n.err( I18n.ERR_04095 ) );
2884                        }
2885                        else
2886                        {
2887                            byte[] requestNameBytes = tlv.getValue().getData();
2888    
2889                            try
2890                            {
2891                                OID oid = new OID( StringTools.utf8ToString( requestNameBytes ) );
2892                                extendedRequest.setRequestName( oid );
2893                            }
2894                            catch ( DecoderException de )
2895                            {
2896                                String msg = "The Request name is not a valid OID : "
2897                                    + StringTools.utf8ToString( requestNameBytes ) + " ("
2898                                    + StringTools.dumpBytes( requestNameBytes ) + ") is invalid";
2899                                log.error( "{} : {}", msg, de.getMessage() );
2900    
2901                                // Rethrow the exception, we will get a PROTOCOL_ERROR
2902                                throw de;
2903                            }
2904                        }
2905    
2906                        // We can have an END transition
2907                        ldapMessageContainer.grammarEndAllowed( true );
2908    
2909                        if ( IS_DEBUG )
2910                        {
2911                            log.debug( "OID read : {}", extendedRequest.getRequestName() );
2912                        }
2913                    }
2914                } );
2915    
2916            // --------------------------------------------------------------------------------------------
2917            // Transition from RequestName to RequestValue
2918            // --------------------------------------------------------------------------------------------
2919            // ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
2920            //     ...
2921            //     requestValue  [1] OCTET STRING OPTIONAL }
2922            //
2923            // Stores the value
2924            super.transitions[LdapStatesEnum.REQUEST_NAME_STATE][LdapConstants.EXTENDED_REQUEST_VALUE_TAG] = new GrammarTransition(
2925                LdapStatesEnum.REQUEST_NAME_STATE, LdapStatesEnum.REQUEST_VALUE_STATE,
2926                LdapConstants.EXTENDED_REQUEST_VALUE_TAG, new GrammarAction( "Store value" )
2927                {
2928                    public void action( IAsn1Container container ) throws DecoderException
2929                    {
2930                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2931    
2932                        // We can allocate the ExtendedRequest Object
2933                        ExtendedRequestCodec extendedRequest = ldapMessageContainer.getExtendedRequest();
2934    
2935                        // Get the Value and store it in the ExtendedRequest
2936                        TLV tlv = ldapMessageContainer.getCurrentTLV();
2937    
2938                        // We have to handle the special case of a 0 length matched
2939                        // value
2940                        if ( tlv.getLength() == 0 )
2941                        {
2942                            extendedRequest.setRequestValue( StringTools.EMPTY_BYTES );
2943                        }
2944                        else
2945                        {
2946                            extendedRequest.setRequestValue( tlv.getValue().getData() );
2947                        }
2948    
2949                        // We can have an END transition
2950                        ldapMessageContainer.grammarEndAllowed( true );
2951    
2952                        if ( IS_DEBUG )
2953                        {
2954                            log.debug( "Extended value : {}", extendedRequest.getRequestValue() );
2955                        }
2956                    }
2957                } );
2958    
2959            // --------------------------------------------------------------------------------------------
2960            // Transition from RequestName to Controls
2961            // --------------------------------------------------------------------------------------------
2962            //         extendedRequest   EtendedRequest,
2963            //         ... },
2964            //     controls       [0] Controls OPTIONAL }
2965            //
2966            // Stores the value
2967            super.transitions[LdapStatesEnum.REQUEST_NAME_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2968                LdapStatesEnum.REQUEST_NAME_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2969                new ControlsInitAction() );
2970    
2971            // --------------------------------------------------------------------------------------------
2972            // Transition from RequestValue to Controls
2973            // --------------------------------------------------------------------------------------------
2974            //         extendedRequest   EtendedRequest,
2975            //         ... },
2976            //     controls       [0] Controls OPTIONAL }
2977            //
2978            // Stores the value
2979            super.transitions[LdapStatesEnum.REQUEST_VALUE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
2980                LdapStatesEnum.REQUEST_VALUE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
2981                new ControlsInitAction() );
2982    
2983            // --------------------------------------------------------------------------------------------
2984            // Transition from MessageId to ExtendedResponse Message.
2985            // --------------------------------------------------------------------------------------------
2986            // LdapMessage ::= ... ExtendedResponse ...
2987            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
2988            //
2989            // Creates the ExtendeResponse object
2990            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.EXTENDED_RESPONSE_TAG] = new GrammarTransition(
2991                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.EXTENDED_RESPONSE_STATE,
2992                LdapConstants.EXTENDED_RESPONSE_TAG, new GrammarAction( "Init Extended Reponse" )
2993                {
2994                    public void action( IAsn1Container container ) throws DecoderException
2995                    {
2996                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
2997    
2998                        // Now, we can allocate the ExtendedResponse Object
2999                        ExtendedResponseCodec extendedResponse = new ExtendedResponseCodec();
3000                        extendedResponse.setMessageId( ldapMessageContainer.getMessageId() );
3001                        ldapMessageContainer.setLdapMessage( extendedResponse );
3002    
3003                        log.debug( "Extended Response" );
3004                    }
3005                } );
3006    
3007            // --------------------------------------------------------------------------------------------
3008            // Transition from ExtendedResponse Message to Result Code ER
3009            // --------------------------------------------------------------------------------------------
3010            // LdapMessage ::= ... ExtendedResponse ...
3011            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3012            //     COMPONENTS OF LDAPResult,
3013            //     ...
3014            //
3015            // Stores the result code
3016            super.transitions[LdapStatesEnum.EXTENDED_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
3017                LdapStatesEnum.EXTENDED_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_ER_STATE, UniversalTag.ENUMERATED_TAG,
3018                new ResultCodeAction() );
3019    
3020            // --------------------------------------------------------------------------------------------
3021            // Transition from Result Code ER to Matched DN ER
3022            // --------------------------------------------------------------------------------------------
3023            // LdapMessage ::= ... ExtendedResponse ...
3024            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3025            //     COMPONENTS OF LDAPResult,
3026            //     ...
3027            //
3028            // 
3029            super.transitions[LdapStatesEnum.RESULT_CODE_ER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3030                LdapStatesEnum.RESULT_CODE_ER_STATE, LdapStatesEnum.MATCHED_DN_ER_STATE, UniversalTag.OCTET_STRING_TAG,
3031                new MatchedDNAction() );
3032    
3033            // --------------------------------------------------------------------------------------------
3034            // Transition from Matched DN ER to Error Message ER 
3035            // --------------------------------------------------------------------------------------------
3036            // LdapMessage ::= ... ExtendedResponse ...
3037            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3038            //     COMPONENTS OF LDAPResult,
3039            //     ...
3040            //
3041            // 
3042            super.transitions[LdapStatesEnum.MATCHED_DN_ER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3043                LdapStatesEnum.MATCHED_DN_ER_STATE, LdapStatesEnum.ERROR_MESSAGE_ER_STATE, UniversalTag.OCTET_STRING_TAG,
3044                new ErrorMessageAction() );
3045    
3046            // --------------------------------------------------------------------------------------------
3047            // Transition from Error Message ER to Referrals ER 
3048            // --------------------------------------------------------------------------------------------
3049            // LdapMessage ::= ... ExtendedResponse ...
3050            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3051            //     COMPONENTS OF LDAPResult,
3052            //     ...
3053            //
3054            // 
3055            super.transitions[LdapStatesEnum.ERROR_MESSAGE_ER_STATE][LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG] = 
3056                new GrammarTransition(
3057                LdapStatesEnum.ERROR_MESSAGE_ER_STATE, LdapStatesEnum.REFERRALS_ER_STATE,
3058                LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, new InitReferralsAction() );
3059    
3060            // --------------------------------------------------------------------------------------------
3061            // Transition from Referrals ER to Referral ER 
3062            // --------------------------------------------------------------------------------------------
3063            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
3064            // URI ::= LDAPString
3065            //
3066            // Add a first Referral
3067            super.transitions[LdapStatesEnum.REFERRALS_ER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3068                LdapStatesEnum.REFERRALS_ER_STATE, LdapStatesEnum.REFERRAL_ER_STATE, UniversalTag.OCTET_STRING_TAG,
3069                new ReferralAction() );
3070    
3071            // --------------------------------------------------------------------------------------------
3072            // Transition from Referral ER to Referral ER 
3073            // --------------------------------------------------------------------------------------------
3074            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
3075            // URI ::= LDAPString
3076            //
3077            // Adda new Referral
3078            super.transitions[LdapStatesEnum.REFERRAL_ER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3079                LdapStatesEnum.REFERRAL_ER_STATE, LdapStatesEnum.REFERRAL_ER_STATE, UniversalTag.OCTET_STRING_TAG,
3080                new ReferralAction() );
3081    
3082            // --------------------------------------------------------------------------------------------
3083            // Transition from Referral ER to ResponseName 
3084            // --------------------------------------------------------------------------------------------
3085            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
3086            // URI ::= LDAPString
3087            //
3088            // Adda new Referral
3089            super.transitions[LdapStatesEnum.REFERRAL_ER_STATE][LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG] = 
3090                new GrammarTransition(
3091                LdapStatesEnum.REFERRAL_ER_STATE, LdapStatesEnum.RESPONSE_NAME_STATE,
3092                LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG, new ResponseNameAction() );
3093    
3094            // --------------------------------------------------------------------------------------------
3095            // Transition from Referral ER to Response 
3096            // --------------------------------------------------------------------------------------------
3097            // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
3098            // URI ::= LDAPString
3099            //
3100            // Adda new Referral
3101            super.transitions[LdapStatesEnum.REFERRAL_ER_STATE][LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG] = new GrammarTransition(
3102                LdapStatesEnum.REFERRAL_ER_STATE, LdapStatesEnum.RESPONSE_STATE,
3103                LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG, new ResponseAction() );
3104    
3105            // --------------------------------------------------------------------------------------------
3106            // Transition from Referral ER to Controls 
3107            // --------------------------------------------------------------------------------------------
3108            //         extendedResponse   ExtendedResponse,
3109            //         ... },
3110            //     controls       [0] Controls OPTIONAL }
3111            //
3112            // Adda new Referral
3113            super.transitions[LdapStatesEnum.REFERRAL_ER_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3114                LdapStatesEnum.REFERRAL_ER_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3115                new ControlsInitAction() );
3116    
3117            // --------------------------------------------------------------------------------------------
3118            // Transition from Error Message ER to Controls 
3119            // --------------------------------------------------------------------------------------------
3120            // LdapMessage ::= ... ExtendedResponse ...
3121            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3122            //     COMPONENTS OF LDAPResult,
3123            //     ...
3124            //
3125            // 
3126            super.transitions[LdapStatesEnum.ERROR_MESSAGE_ER_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3127                LdapStatesEnum.ERROR_MESSAGE_ER_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3128                new ControlsInitAction() );
3129    
3130            // --------------------------------------------------------------------------------------------
3131            // Transition from Error Message ER to ResponseName 
3132            // --------------------------------------------------------------------------------------------
3133            // LdapMessage ::= ... ExtendedResponse ...
3134            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3135            //     COMPONENTS OF LDAPResult,
3136            //     responseName   [10] LDAPOID OPTIONAL,
3137            //     ...
3138            //
3139            // Stores the response name
3140            super.transitions[LdapStatesEnum.ERROR_MESSAGE_ER_STATE][LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG] = 
3141                new GrammarTransition(
3142                LdapStatesEnum.ERROR_MESSAGE_ER_STATE, LdapStatesEnum.RESPONSE_NAME_STATE,
3143                LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG, new ResponseNameAction() );
3144    
3145            // --------------------------------------------------------------------------------------------
3146            // Transition from Response Name to Response 
3147            // --------------------------------------------------------------------------------------------
3148            // LdapMessage ::= ... ExtendedResponse ...
3149            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3150            //     ...
3151            //     responseName   [10] LDAPOID OPTIONAL,
3152            //     response       [11] OCTET STRING OPTIONAL}
3153            //
3154            // Stores the response
3155            super.transitions[LdapStatesEnum.RESPONSE_NAME_STATE][LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG] = new GrammarTransition(
3156                LdapStatesEnum.RESPONSE_NAME_STATE, LdapStatesEnum.RESPONSE_STATE,
3157                LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG, new ResponseAction() );
3158    
3159            // --------------------------------------------------------------------------------------------
3160            // Transition from ResponseName to Controls 
3161            // --------------------------------------------------------------------------------------------
3162            //         extendedRequest   EtendedRequest,
3163            //         ... },
3164            //     controls       [0] Controls OPTIONAL }
3165            //
3166            // Init the controls
3167            super.transitions[LdapStatesEnum.RESPONSE_NAME_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3168                LdapStatesEnum.RESPONSE_NAME_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3169                new ControlsInitAction() );
3170    
3171            // --------------------------------------------------------------------------------------------
3172            // Transition from Error Message ER to Response 
3173            // --------------------------------------------------------------------------------------------
3174            // LdapMessage ::= ... ExtendedResponse ...
3175            // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
3176            //     COMPONENTS OF LDAPResult,
3177            //     ...
3178            //     response       [11] OCTET STRING OPTIONAL}
3179            //
3180            // Stores the response
3181            super.transitions[LdapStatesEnum.ERROR_MESSAGE_ER_STATE][LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG] = 
3182                new GrammarTransition(
3183                LdapStatesEnum.ERROR_MESSAGE_ER_STATE, LdapStatesEnum.RESPONSE_STATE,
3184                LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG, new ResponseAction() );
3185    
3186            // --------------------------------------------------------------------------------------------
3187            // Transition from Response to Controls 
3188            // --------------------------------------------------------------------------------------------
3189            //         extendedRequest   EtendedRequest,
3190            //         ... },
3191            //     controls       [0] Controls OPTIONAL }
3192            //
3193            // Init the controls
3194            super.transitions[LdapStatesEnum.RESPONSE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3195                LdapStatesEnum.RESPONSE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3196                new ControlsInitAction() );
3197    
3198    
3199            // --------------------------------------------------------------------------------------------
3200            // Transition from Message Id to IntermediateResponse Message
3201            // --------------------------------------------------------------------------------------------
3202            // LdapMessage ::= ... IntermediateResponse ...
3203            // IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
3204            //
3205            // Creates the IntermediateResponse object
3206            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.INTERMEDIATE_RESPONSE_TAG] = new GrammarTransition(
3207                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.INTERMEDIATE_RESPONSE_STATE, LdapConstants.INTERMEDIATE_RESPONSE_TAG,
3208                new GrammarAction( "Init Intermediate Response" )
3209                {
3210                    public void action( IAsn1Container container ) throws DecoderException
3211                    {
3212                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3213    
3214                        // Now, we can allocate the IntermediateResponse Object
3215                        IntermediateResponseCodec intermediateResponse = new IntermediateResponseCodec();
3216                        intermediateResponse.setMessageId( ldapMessageContainer.getMessageId() );
3217                        ldapMessageContainer.setLdapMessage( intermediateResponse );
3218    
3219                        log.debug( "Intermediate Response" );
3220                    }
3221                } );
3222    
3223            // --------------------------------------------------------------------------------------------
3224            // Transition from IntermediateResponse Message to ResponseName
3225            // --------------------------------------------------------------------------------------------
3226            // IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
3227            //     responseName [0] LDAPOID OPTIONAL,
3228            //     ...
3229            //
3230            // Stores the name
3231            super.transitions[LdapStatesEnum.INTERMEDIATE_RESPONSE_STATE][LdapConstants.INTERMEDIATE_RESPONSE_NAME_TAG] = new GrammarTransition(
3232                LdapStatesEnum.INTERMEDIATE_RESPONSE_STATE, LdapStatesEnum.INTERMEDIATE_RESPONSE_NAME_STATE,
3233                LdapConstants.INTERMEDIATE_RESPONSE_NAME_TAG, new GrammarAction( "Store response name" )
3234                {
3235                    public void action( IAsn1Container container ) throws DecoderException
3236                    {
3237    
3238                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3239    
3240                        // We can get the IntermediateResponse Object
3241                        IntermediateResponseCodec intermediateResponse = ldapMessageContainer.getIntermediateResponse();
3242    
3243                        // Get the Value and store it in the IntermediateResponse
3244                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3245    
3246                        // We have to handle the special case of a 0 length matched
3247                        // OID.
3248                        if ( tlv.getLength() == 0 )
3249                        {
3250                            log.error( I18n.err( I18n.ERR_04095 ) );
3251                            // This will generate a PROTOCOL_ERROR                        
3252                            throw new DecoderException( I18n.err( I18n.ERR_04095 ) );
3253                        }
3254                        else
3255                        {
3256                            byte[] responseNameBytes = tlv.getValue().getData();
3257    
3258                            try
3259                            {
3260                                OID oid = new OID( StringTools.utf8ToString( responseNameBytes ) );
3261                                intermediateResponse.setResponseName( oid );
3262                            }
3263                            catch ( DecoderException de )
3264                            {
3265                                String msg = "The Intermediate Response name is not a valid OID : "
3266                                    + StringTools.utf8ToString( responseNameBytes ) + " ("
3267                                    + StringTools.dumpBytes( responseNameBytes ) + ") is invalid";
3268                                log.error( "{} : {}", msg, de.getMessage() );
3269    
3270                                // Rethrow the exception, we will get a PROTOCOL_ERROR
3271                                throw de;
3272                            }
3273                        }
3274    
3275                        // We can have an END transition
3276                        ldapMessageContainer.grammarEndAllowed( true );
3277    
3278                        if ( IS_DEBUG )
3279                        {
3280                            log.debug( "OID read : {}", intermediateResponse.getResponseName() );
3281                        }
3282                    }
3283                } );
3284    
3285            // --------------------------------------------------------------------------------------------
3286            // Transition from IntermediateResponse Message to ResponseValue (ResponseName is null)
3287            // --------------------------------------------------------------------------------------------
3288            // IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
3289            //     ...
3290            //     responseValue [1] OCTET STRING OPTIONAL
3291            //     }
3292            //
3293            // Stores the value
3294            super.transitions[LdapStatesEnum.INTERMEDIATE_RESPONSE_STATE][LdapConstants.INTERMEDIATE_RESPONSE_VALUE_TAG] = new GrammarTransition(
3295                LdapStatesEnum.INTERMEDIATE_RESPONSE_STATE, LdapStatesEnum.INTERMEDIATE_RESPONSE_VALUE_STATE,
3296                LdapConstants.INTERMEDIATE_RESPONSE_VALUE_TAG, new GrammarAction( "Store response value" )
3297                {
3298                    public void action( IAsn1Container container ) throws DecoderException
3299                    {
3300                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3301    
3302                        // We can get the IntermediateResponse Object
3303                        IntermediateResponseCodec intermediateResponse = ldapMessageContainer.getIntermediateResponse();
3304    
3305                        // Get the Value and store it in the IntermediateResponse
3306                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3307    
3308                        // We have to handle the special case of a 0 length matched
3309                        // value
3310                        if ( tlv.getLength() == 0 )
3311                        {
3312                            intermediateResponse.setResponseValue( StringTools.EMPTY_BYTES );
3313                        }
3314                        else
3315                        {
3316                            intermediateResponse.setResponseValue( tlv.getValue().getData() );
3317                        }
3318    
3319                        // We can have an END transition
3320                        ldapMessageContainer.grammarEndAllowed( true );
3321    
3322                        if ( IS_DEBUG )
3323                        {
3324                            log.debug( "Value read : {}", StringTools.dumpBytes( intermediateResponse.getResponseValue() ) );
3325                        }
3326                    }
3327                } );
3328    
3329            // --------------------------------------------------------------------------------------------
3330            // Transition from ResponseName to ResponseValue
3331            // --------------------------------------------------------------------------------------------
3332            // IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
3333            //     ...
3334            //     responseValue  [1] OCTET STRING OPTIONAL }
3335            //
3336            // Stores the value
3337            super.transitions[LdapStatesEnum.INTERMEDIATE_RESPONSE_NAME_STATE][LdapConstants.INTERMEDIATE_RESPONSE_VALUE_TAG] = new GrammarTransition(
3338                LdapStatesEnum.INTERMEDIATE_RESPONSE_NAME_STATE, LdapStatesEnum.INTERMEDIATE_RESPONSE_VALUE_STATE,
3339                LdapConstants.INTERMEDIATE_RESPONSE_VALUE_TAG, new GrammarAction( "Store value" )
3340                {
3341                    public void action( IAsn1Container container ) throws DecoderException
3342                    {
3343                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3344    
3345                        // We can allocate the ExtendedRequest Object
3346                        IntermediateResponseCodec intermediateResponse = ldapMessageContainer.getIntermediateResponse();
3347    
3348                        // Get the Value and store it in the IntermediateResponse
3349                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3350    
3351                        // We have to handle the special case of a 0 length matched
3352                        // value
3353                        if ( tlv.getLength() == 0 )
3354                        {
3355                            intermediateResponse.setResponseValue( StringTools.EMPTY_BYTES );
3356                        }
3357                        else
3358                        {
3359                            intermediateResponse.setResponseValue( tlv.getValue().getData() );
3360                        }
3361    
3362                        // We can have an END transition
3363                        ldapMessageContainer.grammarEndAllowed( true );
3364    
3365                        if ( IS_DEBUG )
3366                        {
3367                            log.debug( "Response value : {}", intermediateResponse.getResponseValue() );
3368                        }
3369                    }
3370                } );
3371    
3372            // --------------------------------------------------------------------------------------------
3373            // Transition from ResponseName to Controls
3374            // --------------------------------------------------------------------------------------------
3375            //         intermediateResponse   IntermediateResponse,
3376            //         ... },
3377            //     controls       [0] Controls OPTIONAL }
3378            //
3379            // Stores the value
3380            super.transitions[LdapStatesEnum.INTERMEDIATE_RESPONSE_NAME_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3381                LdapStatesEnum.INTERMEDIATE_RESPONSE_NAME_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3382                new ControlsInitAction() );
3383    
3384            // --------------------------------------------------------------------------------------------
3385            // Transition from ResponseValue to Controls
3386            // --------------------------------------------------------------------------------------------
3387            //         intermediateResponse   IntermediateResponse,
3388            //         ... },
3389            //     controls       [0] Controls OPTIONAL }
3390            //
3391            // Stores the value
3392            super.transitions[LdapStatesEnum.INTERMEDIATE_RESPONSE_VALUE_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
3393                LdapStatesEnum.INTERMEDIATE_RESPONSE_VALUE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
3394                new ControlsInitAction() );
3395    
3396    
3397            // --------------------------------------------------------------------------------------------
3398            // Controls
3399            // --------------------------------------------------------------------------------------------
3400            IAction addControl = new GrammarAction( "Add Control" )
3401            {
3402                public void action( IAsn1Container container ) throws DecoderException
3403                {
3404                    LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3405    
3406                    TLV tlv = ldapMessageContainer.getCurrentTLV();
3407                    int expectedLength = tlv.getLength();
3408    
3409                    // The Length should be null
3410                    if ( expectedLength == 0 )
3411                    {
3412                        log.error( I18n.err( I18n.ERR_04096 ) );
3413    
3414                        // This will generate a PROTOCOL_ERROR
3415                        throw new DecoderException( I18n.err( I18n.ERR_04096 ) );
3416                    }
3417                }
3418            };
3419    
3420            // ============================================================================================
3421            // Transition from Controls to Control
3422            // ============================================================================================
3423            // ...
3424            // Controls ::= SEQUENCE OF Control
3425            //  ...
3426            //
3427            // Initialize the controls 
3428            super.transitions[LdapStatesEnum.CONTROLS_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
3429                LdapStatesEnum.CONTROLS_STATE, LdapStatesEnum.CONTROL_STATE, UniversalTag.SEQUENCE_TAG, addControl );
3430    
3431            // ============================================================================================
3432            // Transition from Control to ControlType
3433            // ============================================================================================
3434            // Control ::= SEQUENCE {
3435            //     ...
3436            //
3437            // Create a new Control object, and store it in the message Container
3438            super.transitions[LdapStatesEnum.CONTROL_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3439                LdapStatesEnum.CONTROL_STATE, LdapStatesEnum.CONTROL_TYPE_STATE, UniversalTag.OCTET_STRING_TAG,
3440                new GrammarAction( "Set Control Type" )
3441                {
3442                    public void action( IAsn1Container container ) throws DecoderException
3443                    {
3444                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3445                        LdapMessageCodec message = ldapMessageContainer.getLdapMessage();
3446    
3447                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3448    
3449                        // Get the current control
3450                        Control control = null;
3451    
3452                        // Store the type
3453                        // We have to handle the special case of a 0 length OID
3454                        if ( tlv.getLength() == 0 )
3455                        {
3456                            log.error( I18n.err( I18n.ERR_04097 ) );
3457    
3458                            // This will generate a PROTOCOL_ERROR
3459                            throw new DecoderException( I18n.err( I18n.ERR_04097 ) );
3460                        }
3461    
3462                        byte[] value = tlv.getValue().getData();
3463                        String oidValue = StringTools.asciiBytesToString( value );
3464    
3465                        // The OID is encoded as a String, not an Object Id
3466                        if ( !OID.isOID( oidValue ) )
3467                        {
3468                            log.error( I18n.err( I18n.ERR_04098, StringTools.dumpBytes( value ) ) );
3469    
3470                            // This will generate a PROTOCOL_ERROR
3471                            throw new DecoderException( I18n.err( I18n.ERR_04099, oidValue ) );
3472                        }
3473                        
3474                        // get the Control for this OID
3475                        control = message.getCodecControl( oidValue );
3476                        
3477                        if ( control == null )
3478                        {
3479                            // This control is unknown, we will create a neutral control
3480                            control = new ControlImpl( oidValue );
3481                        }
3482                        
3483                        // The control may be null, if not known
3484                        message.addControl( control );
3485    
3486                        // We can have an END transition
3487                        ldapMessageContainer.grammarEndAllowed( true );
3488    
3489                        if ( IS_DEBUG )
3490                        {
3491                            log.debug( "Control OID : " + control.getOid() );
3492                        }
3493                    }
3494                } );
3495    
3496            // ============================================================================================
3497            // Transition from ControlType to Control Criticality
3498            // ============================================================================================
3499            // Control ::= SEQUENCE {
3500            //     ...
3501            //     criticality BOOLEAN DEFAULT FALSE,
3502            //     ...
3503            //
3504            // Store the value in the control object created before
3505            super.transitions[LdapStatesEnum.CONTROL_TYPE_STATE][UniversalTag.BOOLEAN_TAG] = new GrammarTransition(
3506                LdapStatesEnum.CONTROL_TYPE_STATE, LdapStatesEnum.CRITICALITY_STATE, UniversalTag.OCTET_STRING_TAG,
3507                new GrammarAction( "Set Criticality" )
3508                {
3509                    public void action( IAsn1Container container ) throws DecoderException
3510                    {
3511                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3512                        LdapMessageCodec message = ldapMessageContainer.getLdapMessage();
3513    
3514                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3515    
3516                        // Get the current control
3517                        Control control = message.getCurrentControl();
3518    
3519                        // Store the criticality
3520                        // We get the value. If it's a 0, it's a FALSE. If it's
3521                        // a FF, it's a TRUE. Any other value should be an error,
3522                        // but we could relax this constraint. So if we have
3523                        // something
3524                        // which is not 0, it will be interpreted as TRUE, but we
3525                        // will generate a warning.
3526                        Value value = tlv.getValue();
3527    
3528                        try
3529                        {
3530                            control.setCritical( BooleanDecoder.parse( value ) );
3531                        }
3532                        catch ( BooleanDecoderException bde )
3533                        {
3534                            log.error( I18n.err( I18n.ERR_04100, StringTools.dumpBytes( value.getData() ), bde.getMessage() ) );
3535    
3536                            // This will generate a PROTOCOL_ERROR
3537                            throw new DecoderException( bde.getMessage() );
3538                        }
3539    
3540                        // We can have an END transition
3541                        ldapMessageContainer.grammarEndAllowed( true );
3542    
3543                        if ( IS_DEBUG )
3544                        {
3545                            log.debug( "Control criticality : " + control.isCritical() );
3546                        }
3547                    }
3548                } );
3549    
3550            // ============================================================================================
3551            // Transition from Control Criticality to Control Value
3552            // ============================================================================================
3553            // Control ::= SEQUENCE {
3554            //     ...
3555            //     controlValue OCTET STRING OPTIONAL }
3556            //
3557            // Store the value in the control object created before
3558            super.transitions[LdapStatesEnum.CRITICALITY_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3559                LdapStatesEnum.CRITICALITY_STATE, LdapStatesEnum.CONTROL_VALUE_STATE, UniversalTag.OCTET_STRING_TAG,
3560                new ControlValueAction() );
3561    
3562            // ============================================================================================
3563            // Transition from Control Type to Control Value
3564            // ============================================================================================
3565            // Control ::= SEQUENCE {
3566            //     ...
3567            //     controlValue OCTET STRING OPTIONAL }
3568            //
3569            // Store the value in the control object created before
3570            super.transitions[LdapStatesEnum.CONTROL_TYPE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3571                LdapStatesEnum.CONTROL_TYPE_STATE, LdapStatesEnum.CONTROL_VALUE_STATE, UniversalTag.OCTET_STRING_TAG,
3572                new ControlValueAction() );
3573    
3574            // ============================================================================================
3575            // Transition from Control Type to Control
3576            // ============================================================================================
3577            // Control ::= SEQUENCE {
3578            //     ...
3579            //     controlValue OCTET STRING OPTIONAL }
3580            //
3581            // Store the value in the control object created before
3582            super.transitions[LdapStatesEnum.CONTROL_TYPE_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
3583                LdapStatesEnum.CONTROL_TYPE_STATE, LdapStatesEnum.CONTROL_STATE, UniversalTag.SEQUENCE_TAG, addControl );
3584    
3585            // ============================================================================================
3586            // Transition from Control Criticality to Control
3587            // ============================================================================================
3588            // Control ::= SEQUENCE {
3589            //     ...
3590            //     controlValue OCTET STRING OPTIONAL }
3591            //
3592            // Store the value in the control object created before
3593            super.transitions[LdapStatesEnum.CRITICALITY_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
3594                LdapStatesEnum.CRITICALITY_STATE, LdapStatesEnum.CONTROL_STATE, UniversalTag.SEQUENCE_TAG, addControl );
3595    
3596            // ============================================================================================
3597            // Transition from Control Value to Control
3598            // ============================================================================================
3599            // Control ::= SEQUENCE {
3600            //     ...
3601            //     controlValue OCTET STRING OPTIONAL }
3602            //
3603            // Store the value in the control object created before
3604            super.transitions[LdapStatesEnum.CONTROL_VALUE_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
3605                LdapStatesEnum.CONTROL_VALUE_STATE, LdapStatesEnum.CONTROL_STATE, UniversalTag.SEQUENCE_TAG, addControl );
3606    
3607            // --------------------------------------------------------------------------------------------
3608            // Transition from message ID to SearchRequest Message
3609            // --------------------------------------------------------------------------------------------
3610            // LdapMessage ::= ... SearchRequest ...
3611            // SearchRequest ::= [APPLICATION 3] SEQUENCE { ...
3612            //
3613            // Initialize the searchRequest object
3614            super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.SEARCH_REQUEST_TAG] = new GrammarTransition(
3615                LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_REQUEST_STATE, LdapConstants.SEARCH_REQUEST_TAG,
3616                new GrammarAction( "Init SearchRequest" )
3617                {
3618                    public void action( IAsn1Container container )
3619                    {
3620                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3621                        
3622                        // Now, we can allocate the SearchRequest Object
3623                        SearchRequestCodec searchRequest = new SearchRequestCodec();
3624                        searchRequest.setMessageId( ldapMessageContainer.getMessageId() );
3625                        ldapMessageContainer.setLdapMessage( searchRequest );
3626    
3627                        log.debug( "Search Request" );
3628                    }
3629                } );
3630    
3631            // --------------------------------------------------------------------------------------------
3632            // Transition from SearchRequest Message to BaseObject
3633            // --------------------------------------------------------------------------------------------
3634            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3635            //     baseObject LDAPDN,
3636            //     ...
3637            //
3638            // We have a value for the base object, we will store it in the message
3639            super.transitions[LdapStatesEnum.SEARCH_REQUEST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
3640                LdapStatesEnum.SEARCH_REQUEST_STATE, LdapStatesEnum.BASE_OBJECT_STATE, UniversalTag.OCTET_STRING_TAG,
3641                new GrammarAction( "store base object value" )
3642                {
3643                    public void action( IAsn1Container container ) throws DecoderException
3644                    {
3645                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3646                        SearchRequestCodec searchRequest = ldapMessageContainer.getSearchRequest();
3647    
3648                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3649    
3650                        // We have to check that this is a correct DN
3651                        DN baseObject = DN.EMPTY_DN;
3652    
3653                        // We have to handle the special case of a 0 length base
3654                        // object,
3655                        // which means that the search is done from the default
3656                        // root.
3657                        if ( tlv.getLength() != 0 )
3658                        {
3659                            byte[] dnBytes = tlv.getValue().getData();
3660                            String dnStr = StringTools.utf8ToString( dnBytes );
3661    
3662                            try
3663                            {
3664                                baseObject = new DN( dnStr );
3665                            }
3666                            catch ( LdapInvalidDnException ine )
3667                            {
3668                                String msg = "Invalid root DN given : " + dnStr + " ("
3669                                    + StringTools.dumpBytes( dnBytes ) + ") is invalid";
3670                                log.error( "{} : {}", msg, ine.getMessage() );
3671    
3672                                SearchResponseDoneImpl response = new SearchResponseDoneImpl( searchRequest.getMessageId() );
3673                                throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
3674                                    DN.EMPTY_DN, ine );
3675                            }
3676                        }
3677    
3678                        searchRequest.setBaseObject( baseObject );
3679    
3680                        log.debug( "Searching with root DN : {}", baseObject );
3681    
3682                        return;
3683                    }
3684                } );
3685    
3686            // --------------------------------------------------------------------------------------------
3687            // Transition from BaseObject to Scope
3688            // --------------------------------------------------------------------------------------------
3689            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3690            //     ...
3691            //     scope ENUMERATED {
3692            //         baseObject   (0),
3693            //         singleLevel  (1),
3694            //         wholeSubtree (2) },
3695            //     ...
3696            //
3697            // We have a value for the scope, we will store it in the message
3698            super.transitions[LdapStatesEnum.BASE_OBJECT_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
3699                LdapStatesEnum.BASE_OBJECT_STATE, LdapStatesEnum.SCOPE_STATE, UniversalTag.ENUMERATED_TAG,
3700                new GrammarAction( "store scope value" )
3701                {
3702                    public void action( IAsn1Container container ) throws DecoderException
3703                    {
3704                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3705    
3706                        SearchRequestCodec searchRequest = ldapMessageContainer.getSearchRequest();
3707    
3708                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3709    
3710                        // We have to check that this is a correct scope
3711                        Value value = tlv.getValue();
3712                        int scope = 0;
3713    
3714                        try
3715                        {
3716                            scope = IntegerDecoder.parse( value, LdapConstants.SCOPE_BASE_OBJECT,
3717                                LdapConstants.SCOPE_WHOLE_SUBTREE );
3718                        }
3719                        catch ( IntegerDecoderException ide )
3720                        {
3721                            log.error( I18n.err( I18n.ERR_04101, value.toString() ) );
3722                            throw new DecoderException( I18n.err( I18n.ERR_04101,  value.toString() ) );
3723                        }
3724    
3725                        searchRequest.setScope( SearchScope.getSearchScope( scope ) );
3726    
3727                        if ( IS_DEBUG )
3728                        {
3729                            switch ( scope )
3730                            {
3731                                case LdapConstants.SCOPE_BASE_OBJECT:
3732                                    log.debug( "Searching within BASE_OBJECT scope " );
3733                                    break;
3734    
3735                                case LdapConstants.SCOPE_SINGLE_LEVEL:
3736                                    log.debug( "Searching within SINGLE_LEVEL scope " );
3737                                    break;
3738    
3739                                case LdapConstants.SCOPE_WHOLE_SUBTREE:
3740                                    log.debug( "Searching within WHOLE_SUBTREE scope " );
3741                                    break;
3742                            }
3743                        }
3744    
3745                        return;
3746                    }
3747                } );
3748    
3749            // --------------------------------------------------------------------------------------------
3750            // Transition from Scope to DerefAlias
3751            // --------------------------------------------------------------------------------------------
3752            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3753            //     ...
3754            //     derefAliases ENUMERATED {
3755            //         neverDerefAliases   (0),
3756            //         derefInSearching    (1),
3757            //         derefFindingBaseObj (2),
3758            //         derefAlways         (3) },
3759            //     ...
3760            //
3761            // We have a value for the derefAliases, we will store it in the message
3762            super.transitions[LdapStatesEnum.SCOPE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
3763                LdapStatesEnum.SCOPE_STATE, LdapStatesEnum.DEREF_ALIAS_STATE, UniversalTag.ENUMERATED_TAG,
3764                new GrammarAction( "store derefAliases value" )
3765                {
3766                    public void action( IAsn1Container container ) throws DecoderException
3767                    {
3768                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3769    
3770                        SearchRequestCodec searchRequest = ldapMessageContainer.getSearchRequest();
3771    
3772                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3773    
3774                        // We have to check that this is a correct derefAliases
3775                        Value value = tlv.getValue();
3776                        int derefAliases = 0;
3777    
3778                        try
3779                        {
3780                            derefAliases = IntegerDecoder.parse( value, LdapConstants.NEVER_DEREF_ALIASES,
3781                                LdapConstants.DEREF_ALWAYS );
3782                        }
3783                        catch ( IntegerDecoderException ide )
3784                        {
3785                            log.error( I18n.err( I18n.ERR_04102, value.toString() ) );
3786                            throw new DecoderException( I18n.err( I18n.ERR_04102, value.toString() ) );
3787                        }
3788    
3789                        searchRequest.setDerefAliases( derefAliases );
3790    
3791                        if ( IS_DEBUG )
3792                        {
3793                            switch ( derefAliases )
3794                            {
3795                                case LdapConstants.NEVER_DEREF_ALIASES:
3796                                    log.debug( "Handling object strategy : NEVER_DEREF_ALIASES" );
3797                                    break;
3798    
3799                                case LdapConstants.DEREF_IN_SEARCHING:
3800                                    log.debug( "Handling object strategy : DEREF_IN_SEARCHING" );
3801                                    break;
3802    
3803                                case LdapConstants.DEREF_FINDING_BASE_OBJ:
3804                                    log.debug( "Handling object strategy : DEREF_FINDING_BASE_OBJ" );
3805                                    break;
3806    
3807                                case LdapConstants.DEREF_ALWAYS:
3808                                    log.debug( "Handling object strategy : DEREF_ALWAYS" );
3809                                    break;
3810                            }
3811                        }
3812                        return;
3813                    }
3814                } );
3815    
3816            // --------------------------------------------------------------------------------------------
3817            // Transition from DerefAlias to SizeLimit
3818            // --------------------------------------------------------------------------------------------
3819            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3820            //     ...
3821            //     sizeLimit INTEGER (0 .. maxInt),
3822            //     ...
3823            //
3824            // We have a value for the sizeLimit, we will store it in the message
3825            super.transitions[LdapStatesEnum.DEREF_ALIAS_STATE][UniversalTag.INTEGER_TAG] = new GrammarTransition(
3826                LdapStatesEnum.DEREF_ALIAS_STATE, LdapStatesEnum.SIZE_LIMIT_STATE, UniversalTag.INTEGER_TAG,
3827                new GrammarAction( "store sizeLimit value" )
3828                {
3829                    public void action( IAsn1Container container ) throws DecoderException
3830                    {
3831                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3832    
3833                        SearchRequestCodec searchRequest = ldapMessageContainer.getSearchRequest();
3834    
3835                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3836    
3837                        // The current TLV should be a integer
3838                        // We get it and store it in sizeLimit
3839                        Value value = tlv.getValue();
3840                        long sizeLimit = 0;
3841    
3842                        try
3843                        {
3844                            sizeLimit = LongDecoder.parse( value, 0, Integer.MAX_VALUE );
3845                        }
3846                        catch ( LongDecoderException lde )
3847                        {
3848                            log.error( I18n.err( I18n.ERR_04103, value.toString() ) );
3849                            throw new DecoderException( I18n.err( I18n.ERR_04103, value.toString() ) );
3850                        }
3851    
3852                        searchRequest.setSizeLimit( sizeLimit );
3853    
3854                        if ( IS_DEBUG )
3855                        {
3856                            log.debug( "The sizeLimit value is set to {} objects", Long.valueOf( sizeLimit ) );
3857                        }
3858    
3859                        return;
3860                    }
3861                } );
3862    
3863            // --------------------------------------------------------------------------------------------
3864            // Transition from SizeLimit to TimeLimit
3865            // --------------------------------------------------------------------------------------------
3866            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3867            //     ...
3868            //     timeLimit INTEGER (0 .. maxInt),
3869            //     ...
3870            //
3871            // We have a value for the timeLimit, we will store it in the message
3872            super.transitions[LdapStatesEnum.SIZE_LIMIT_STATE][UniversalTag.INTEGER_TAG] = new GrammarTransition(
3873                LdapStatesEnum.SIZE_LIMIT_STATE, LdapStatesEnum.TIME_LIMIT_STATE, UniversalTag.INTEGER_TAG,
3874                new GrammarAction( "store timeLimit value" )
3875                {
3876                    public void action( IAsn1Container container ) throws DecoderException
3877                    {
3878                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3879    
3880                        SearchRequestCodec searchRequest = ldapMessageContainer.getSearchRequest();
3881    
3882                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3883    
3884                        // The current TLV should be a integer
3885                        // We get it and store it in timeLimit
3886                        Value value = tlv.getValue();
3887    
3888                        int timeLimit = 0;
3889    
3890                        try
3891                        {
3892                            timeLimit = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
3893                        }
3894                        catch ( IntegerDecoderException ide )
3895                        {
3896                            log.error( I18n.err( I18n.ERR_04104, value.toString() ) );
3897                            throw new DecoderException( I18n.err( I18n.ERR_04104, value.toString() ) );
3898                        }
3899    
3900                        searchRequest.setTimeLimit( timeLimit );
3901    
3902                        if ( IS_DEBUG )
3903                        {
3904                            log.debug( "The timeLimit value is set to {} seconds", Integer.valueOf( timeLimit ) );
3905                        }
3906    
3907                        return;
3908                    }
3909                } );
3910    
3911            // --------------------------------------------------------------------------------------------
3912            // Transition from TimeLimit to TypesOnly
3913            // --------------------------------------------------------------------------------------------
3914            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
3915            //     ...
3916            //     typesOnly BOOLEAN,
3917            //     ...
3918            //
3919            // We have a value for the typesOnly, we will store it in the message.
3920            super.transitions[LdapStatesEnum.TIME_LIMIT_STATE][UniversalTag.BOOLEAN_TAG] = new GrammarTransition(
3921                LdapStatesEnum.TIME_LIMIT_STATE, LdapStatesEnum.TYPES_ONLY_STATE, UniversalTag.BOOLEAN_TAG,
3922                new GrammarAction( "store typesOnly value" )
3923                {
3924                    public void action( IAsn1Container container ) throws DecoderException
3925                    {
3926                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
3927    
3928                        SearchRequestCodec searchRequest = ldapMessageContainer.getSearchRequest();
3929    
3930                        TLV tlv = ldapMessageContainer.getCurrentTLV();
3931    
3932                        // We get the value. If it's a 0, it's a FALSE. If it's
3933                        // a FF, it's a TRUE. Any other value should be an error,
3934                        // but we could relax this constraint. So if we have
3935                        // something
3936                        // which is not 0, it will be interpreted as TRUE, but we
3937                        // will generate a warning.
3938                        Value value = tlv.getValue();
3939    
3940                        try
3941                        {
3942                            searchRequest.setTypesOnly( BooleanDecoder.parse( value ) );
3943                        }
3944                        catch ( BooleanDecoderException bde )
3945                        {
3946                            log.error( I18n.err( I18n.ERR_04105, StringTools.dumpBytes( value.getData() ), bde.getMessage() ) );
3947    
3948                            throw new DecoderException( bde.getMessage() );
3949                        }
3950    
3951                        if ( IS_DEBUG )
3952                        {
3953                            log.debug( "The search will return {}", ( searchRequest.isTypesOnly() ? "only attributs type"
3954                                : "attributes types and values" ) );
3955                        }
3956                        return;
3957                    }
3958                } );
3959    
3960            //============================================================================================
3961            // Search Request And Filter
3962            // This is quite complicated, because we have a tree structure to build,
3963            // and we may have many elements on each node. For instance, considering the 
3964            // search filter :
3965            // (& (| (a = b) (c = d)) (! (e = f)) (attr =* h))
3966            // We will have to create an And filter with three children :
3967            //  - an Or child,
3968            //  - a Not child
3969            //  - and a Present child.
3970            // The Or child will also have two children.
3971            //
3972            // We know when we have a children while decoding the PDU, because the length
3973            // of its parent has not yet reached its expected length.
3974            //
3975            // This search filter :
3976            // (&(|(objectclass=top)(ou=contacts))(!(objectclass=ttt))(objectclass=*top))
3977            // is encoded like this :
3978            //                              +----------------+---------------+
3979            //                              | ExpectedLength | CurrentLength |
3980            //+-----------------------------+----------------+---------------+
3981            //|A0 52                        | 82             | 0             | new level 1
3982            //|   A1 24                     | 82 36          | 0 0           | new level 2
3983            //|      A3 12                  | 82 36 18       | 0 0 0         | new level 3
3984            //|         04 0B 'objectclass' | 82 36 18       | 0 0 13        |
3985            //|         04 03 'top'         | 82 36 18       | 0 20 18       | 
3986            //|                             |       ^               ^        |
3987            //|                             |       |               |        |
3988            //|                             |       +---------------+        |
3989            //+-----------------------------* end level 3 -------------------*
3990            //|      A3 0E                  | 82 36 14       | 0 0 0         | new level 3
3991            //|         04 02 'ou'          | 82 36 14       | 0 0 4         |
3992            //|         04 08 'contacts'    | 82 36 14       | 38 36 14      | 
3993            //|                             |    ^  ^             ^  ^       |
3994            //|                             |    |  |             |  |       |
3995            //|                             |    |  +-------------|--+       |
3996            //|                             |    +----------------+          |
3997            //+-----------------------------* end level 3, end level 2 ------*
3998            //|   A2 14                     | 82 20          | 38 0          | new level 2
3999            //|      A3 12                  | 82 20 18       | 38 0 0        | new level 3
4000            //|         04 0B 'objectclass' | 82 20 18       | 38 0 13       | 
4001            //|         04 03 'ttt'         | 82 20 18       | 60 20 18      |
4002            //|                             |    ^  ^             ^  ^       |
4003            //|                             |    |  |             |  |       |
4004            //|                             |    |  +-------------|--+       |
4005            //|                             |    +----------------+          |
4006            //+-----------------------------* end level 3, end level 2 ------*
4007            //|   A4 14                     | 82 20          | 60 0          | new level 2
4008            //|      04 0B 'objectclass'    | 82 20          | 60 13         |
4009            //|      30 05                  | 82 20          | 60 13         |
4010            //|         82 03 'top'         | 82 20          | 82 20         | 
4011            //|                             | ^  ^             ^  ^          |
4012            //|                             | |  |             |  |          |
4013            //|                             | |  +-------------|--+          |
4014            //|                             | +----------------+             |
4015            //+-----------------------------* end level 2, end level 1 ------*
4016            //+-----------------------------+----------------+---------------+
4017            //
4018            // When the current length equals the expected length of the parent PDU,
4019            // then we are able to 'close' the parent : it has all its children. This
4020            // is propagated through all the tree, until either there are no more
4021            // parents, or the expected length of the parent is different from the
4022            // current length.
4023    
4024            // --------------------------------------------------------------------------------------------
4025            // Transition from TypesOnly to AND filter
4026            // --------------------------------------------------------------------------------------------
4027            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4028            //     ...
4029            //     filter Filter,
4030            //     ...
4031            //
4032            // Filter ::= CHOICE {
4033            //     and             [0] SET OF Filter,
4034            //     ...
4035            //
4036            // Init AND filter
4037            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
4038                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
4039                new InitAndFilterAction() );
4040    
4041            // --------------------------------------------------------------------------------------------
4042            // Transition from TypesOnly to OR filter
4043            // --------------------------------------------------------------------------------------------
4044            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4045            //     ...
4046            //     filter Filter,
4047            //     ...
4048            //
4049            // Filter ::= CHOICE {
4050            //     ...
4051            //     or              [1] SET OF Filter,
4052            //     ...
4053            //
4054            // Init OR filter
4055            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
4056                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
4057                new InitOrFilterAction() );
4058    
4059            // --------------------------------------------------------------------------------------------
4060            // Transition from TypesOnly to NOT filter
4061            // --------------------------------------------------------------------------------------------
4062            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4063            //     ...
4064            //     filter Filter,
4065            //     ...
4066            //
4067            // Filter ::= CHOICE {
4068            //     ...
4069            //     not             [2] SET OF Filter,
4070            //     ...
4071            //
4072            // Init NOT filter
4073            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
4074                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
4075                new InitNotFilterAction() );
4076    
4077            // --------------------------------------------------------------------------------------------
4078            // Transition from TypesOnly to Equality Match filter
4079            // --------------------------------------------------------------------------------------------
4080            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4081            //     ...
4082            //     filter Filter,
4083            //     ...
4084            //
4085            // Filter ::= CHOICE {
4086            //     ...
4087            //     equalityMatch   [3] AttributeValueAssertion,
4088            //     ...
4089            //
4090            // Init NOT filter
4091            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
4092                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE,
4093                LdapConstants.EQUALITY_MATCH_FILTER_TAG, new InitEqualityMatchFilterAction() );
4094    
4095            // --------------------------------------------------------------------------------------------
4096            // Transition from TypesOnly to Substrings filter
4097            // --------------------------------------------------------------------------------------------
4098            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4099            //     ...
4100            //     filter Filter,
4101            //     ...
4102            //
4103            // Filter ::= CHOICE {
4104            //     ...
4105            //     substrings     [4] SubstringFilter,
4106            //     ...
4107            //
4108            // Init Substrings filter
4109            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
4110                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE,
4111                LdapConstants.SUBSTRINGS_FILTER_TAG, new InitSubstringsFilterAction() );
4112    
4113            // --------------------------------------------------------------------------------------------
4114            // Transition from TypesOnly to GreaterOrEqual filter
4115            // --------------------------------------------------------------------------------------------
4116            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4117            //     ...
4118            //     filter Filter,
4119            //     ...
4120            //
4121            // Filter ::= CHOICE {
4122            //     ...
4123            //     greaterOrEqual  [5] AttributeValueAssertion,
4124            //     ...
4125            //
4126            // Init Greater Or Equal filter
4127            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4128                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
4129                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
4130    
4131            // --------------------------------------------------------------------------------------------
4132            // Transition from TypesOnly to LessOrEqual filter
4133            // --------------------------------------------------------------------------------------------
4134            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4135            //     ...
4136            //     filter Filter,
4137            //     ...
4138            //
4139            // Filter ::= CHOICE {
4140            //     ...
4141            //     LessOrEqual    [6] AttributeValueAssertion,
4142            //     ...
4143            //
4144            // Init Less Or Equal filter
4145            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4146                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE,
4147                LdapConstants.LESS_OR_EQUAL_FILTER_TAG, new InitLessOrEqualFilterAction() );
4148    
4149            // --------------------------------------------------------------------------------------------
4150            // Transition from TypesOnly to Present filter
4151            // --------------------------------------------------------------------------------------------
4152            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4153            //     ...
4154            //     filter Filter,
4155            //     ...
4156            //
4157            // Filter ::= CHOICE {
4158            //     ...
4159            //     present        [7] AttributeDescription,
4160            //     ...
4161            //
4162            // Init Approx Match filter
4163            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
4164                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
4165                new InitPresentFilterAction() );
4166    
4167            // --------------------------------------------------------------------------------------------
4168            // Transition from TypesOnly to Approx Match filter
4169            // --------------------------------------------------------------------------------------------
4170            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4171            //     ...
4172            //     filter Filter,
4173            //     ...
4174            //
4175            // Filter ::= CHOICE {
4176            //     ...
4177            //     approxMatch     [8] AttributeValueAssertion,
4178            //     ...
4179            //
4180            // Init Approx Match filter
4181            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
4182                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
4183                new InitApproxMatchFilterAction() );
4184    
4185            // --------------------------------------------------------------------------------------------
4186            // Transition from TypesOnly to Extensible Match filter
4187            // --------------------------------------------------------------------------------------------
4188            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4189            //     ...
4190            //     filter Filter,
4191            //     ...
4192            //
4193            // Filter ::= CHOICE {
4194            //     ...
4195            //     extensibleMatch  [9] MatchingRuleAssertion,
4196            //     ...
4197            //
4198            // Init Approx Match filter
4199            super.transitions[LdapStatesEnum.TYPES_ONLY_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
4200                LdapStatesEnum.TYPES_ONLY_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
4201                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
4202    
4203            // --------------------------------------------------------------------------------------------
4204            // Transition from AND to AND filter
4205            // --------------------------------------------------------------------------------------------
4206            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4207            //     ...
4208            //     filter Filter,
4209            //     ...
4210            //
4211            // Filter ::= CHOICE {
4212            //     and             [0] SET OF Filter,
4213            //     ...
4214            //
4215            // Init AND filter
4216            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
4217                LdapStatesEnum.AND_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG, new InitAndFilterAction() );
4218    
4219            // --------------------------------------------------------------------------------------------
4220            // Transition from AND to OR filter
4221            // --------------------------------------------------------------------------------------------
4222            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4223            //     ...
4224            //     filter Filter,
4225            //     ...
4226            //
4227            // Filter ::= CHOICE {
4228            //     ...
4229            //     or              [1] SET OF Filter,
4230            //     ...
4231            //
4232            // Init OR filter
4233            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
4234                LdapStatesEnum.AND_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG, new InitOrFilterAction() );
4235    
4236            // --------------------------------------------------------------------------------------------
4237            // Transition from AND to NOT filter
4238            // --------------------------------------------------------------------------------------------
4239            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4240            //     ...
4241            //     filter Filter,
4242            //     ...
4243            //
4244            // Filter ::= CHOICE {
4245            //     ...
4246            //     not             [2] SET OF Filter,
4247            //     ...
4248            //
4249            // Init NOT filter
4250            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
4251                LdapStatesEnum.AND_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG, new InitNotFilterAction() );
4252    
4253            // --------------------------------------------------------------------------------------------
4254            // Transition from AND to Equality Match filter
4255            // --------------------------------------------------------------------------------------------
4256            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4257            //     ...
4258            //     filter Filter,
4259            //     ...
4260            //
4261            // Filter ::= CHOICE {
4262            //     ...
4263            //     equalityMatch   [3] AttributeValueAssertion,
4264            //     ...
4265            //
4266            // Init NOT filter
4267            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
4268                LdapStatesEnum.AND_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
4269                new InitEqualityMatchFilterAction() );
4270    
4271            // --------------------------------------------------------------------------------------------
4272            // Transition from AND to Substrings filter
4273            // --------------------------------------------------------------------------------------------
4274            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4275            //     ...
4276            //     filter Filter,
4277            //     ...
4278            //
4279            // Filter ::= CHOICE {
4280            //     ...
4281            //     substrings     [4] SubstringFilter,
4282            //     ...
4283            //
4284            // Init Substrings filter
4285            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
4286                LdapStatesEnum.AND_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
4287                new InitSubstringsFilterAction() );
4288    
4289            // --------------------------------------------------------------------------------------------
4290            // Transition from AND to GreaterOrEqual filter
4291            // --------------------------------------------------------------------------------------------
4292            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4293            //     ...
4294            //     filter Filter,
4295            //     ...
4296            //
4297            // Filter ::= CHOICE {
4298            //     ...
4299            //     greaterOrEqual  [5] AttributeValueAssertion,
4300            //     ...
4301            //
4302            // Init Greater Or Equal filter
4303            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4304                LdapStatesEnum.AND_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE, LdapConstants.GREATER_OR_EQUAL_FILTER_TAG,
4305                new InitGreaterOrEqualFilterAction() );
4306    
4307            // --------------------------------------------------------------------------------------------
4308            // Transition from AND to LessOrEqual filter
4309            // --------------------------------------------------------------------------------------------
4310            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4311            //     ...
4312            //     filter Filter,
4313            //     ...
4314            //
4315            // Filter ::= CHOICE {
4316            //     ...
4317            //     LessOrEqual    [6] AttributeValueAssertion,
4318            //     ...
4319            //
4320            // Init Less Or Equal filter
4321            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4322                LdapStatesEnum.AND_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
4323                new InitLessOrEqualFilterAction() );
4324    
4325            // --------------------------------------------------------------------------------------------
4326            // Transition from AND to Present filter
4327            // --------------------------------------------------------------------------------------------
4328            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4329            //     ...
4330            //     filter Filter,
4331            //     ...
4332            //
4333            // Filter ::= CHOICE {
4334            //     ...
4335            //     present        [7] AttributeDescription,
4336            //     ...
4337            //
4338            // Init Approx Match filter
4339            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
4340                LdapStatesEnum.AND_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
4341                new InitPresentFilterAction() );
4342    
4343            // --------------------------------------------------------------------------------------------
4344            // Transition from AND to Approx Match filter
4345            // --------------------------------------------------------------------------------------------
4346            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4347            //     ...
4348            //     filter Filter,
4349            //     ...
4350            //
4351            // Filter ::= CHOICE {
4352            //     ...
4353            //     approxMatch     [8] AttributeValueAssertion,
4354            //     ...
4355            //
4356            // Init Approx Match filter
4357            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
4358                LdapStatesEnum.AND_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
4359                new InitApproxMatchFilterAction() );
4360    
4361            // --------------------------------------------------------------------------------------------
4362            // Transition from AND to Extensible Match filter
4363            // --------------------------------------------------------------------------------------------
4364            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4365            //     ...
4366            //     filter Filter,
4367            //     ...
4368            //
4369            // Filter ::= CHOICE {
4370            //     ...
4371            //     extensibleMatch  [9] MatchingRuleAssertion,
4372            //     ...
4373            //
4374            // Init Approx Match filter
4375            super.transitions[LdapStatesEnum.AND_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
4376                LdapStatesEnum.AND_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG,
4377                new InitExtensibleMatchFilterAction() );
4378    
4379            // --------------------------------------------------------------------------------------------
4380            // Transition from OR to AND filter
4381            // --------------------------------------------------------------------------------------------
4382            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4383            //     ...
4384            //     filter Filter,
4385            //     ...
4386            //
4387            // Filter ::= CHOICE {
4388            //     and             [0] SET OF Filter,
4389            //     ...
4390            //
4391            // Init AND filter
4392            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
4393                LdapStatesEnum.OR_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG, new InitAndFilterAction() );
4394    
4395            // --------------------------------------------------------------------------------------------
4396            // Transition from OR to OR filter
4397            // --------------------------------------------------------------------------------------------
4398            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4399            //     ...
4400            //     filter Filter,
4401            //     ...
4402            //
4403            // Filter ::= CHOICE {
4404            //     ...
4405            //     or              [1] SET OF Filter,
4406            //     ...
4407            //
4408            // Init OR filter
4409            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
4410                LdapStatesEnum.OR_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG, new InitOrFilterAction() );
4411    
4412            // --------------------------------------------------------------------------------------------
4413            // Transition from OR to NOT filter
4414            // --------------------------------------------------------------------------------------------
4415            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4416            //     ...
4417            //     filter Filter,
4418            //     ...
4419            //
4420            // Filter ::= CHOICE {
4421            //     ...
4422            //     not             [2] SET OF Filter,
4423            //     ...
4424            //
4425            // Init NOT filter
4426            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
4427                LdapStatesEnum.OR_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG, new InitNotFilterAction() );
4428    
4429            // --------------------------------------------------------------------------------------------
4430            // Transition from OR to Equality Match filter
4431            // --------------------------------------------------------------------------------------------
4432            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4433            //     ...
4434            //     filter Filter,
4435            //     ...
4436            //
4437            // Filter ::= CHOICE {
4438            //     ...
4439            //     equalityMatch   [3] AttributeValueAssertion,
4440            //     ...
4441            //
4442            // Init NOT filter
4443            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
4444                LdapStatesEnum.OR_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
4445                new InitEqualityMatchFilterAction() );
4446    
4447            // --------------------------------------------------------------------------------------------
4448            // Transition from OR to Substrings filter
4449            // --------------------------------------------------------------------------------------------
4450            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4451            //     ...
4452            //     filter Filter,
4453            //     ...
4454            //
4455            // Filter ::= CHOICE {
4456            //     ...
4457            //     substrings     [4] SubstringFilter,
4458            //     ...
4459            //
4460            // Init Substrings filter
4461            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
4462                LdapStatesEnum.OR_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
4463                new InitSubstringsFilterAction() );
4464    
4465            // --------------------------------------------------------------------------------------------
4466            // Transition from OR to GreaterOrEqual filter
4467            // --------------------------------------------------------------------------------------------
4468            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4469            //     ...
4470            //     filter Filter,
4471            //     ...
4472            //
4473            // Filter ::= CHOICE {
4474            //     ...
4475            //     greaterOrEqual  [5] AttributeValueAssertion,
4476            //     ...
4477            //
4478            // Init Greater Or Equal filter
4479            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4480                LdapStatesEnum.OR_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE, LdapConstants.GREATER_OR_EQUAL_FILTER_TAG,
4481                new InitGreaterOrEqualFilterAction() );
4482    
4483            // --------------------------------------------------------------------------------------------
4484            // Transition from OR to LessOrEqual filter
4485            // --------------------------------------------------------------------------------------------
4486            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4487            //     ...
4488            //     filter Filter,
4489            //     ...
4490            //
4491            // Filter ::= CHOICE {
4492            //     ...
4493            //     LessOrEqual    [6] AttributeValueAssertion,
4494            //     ...
4495            //
4496            // Init Less Or Equal filter
4497            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4498                LdapStatesEnum.OR_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
4499                new InitLessOrEqualFilterAction() );
4500    
4501            // --------------------------------------------------------------------------------------------
4502            // Transition from OR to Present filter
4503            // --------------------------------------------------------------------------------------------
4504            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4505            //     ...
4506            //     filter Filter,
4507            //     ...
4508            //
4509            // Filter ::= CHOICE {
4510            //     ...
4511            //     present        [7] AttributeDescription,
4512            //     ...
4513            //
4514            // Init Approx Match filter
4515            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
4516                LdapStatesEnum.OR_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
4517                new InitPresentFilterAction() );
4518    
4519            // --------------------------------------------------------------------------------------------
4520            // Transition from OR to Approx Match filter
4521            // --------------------------------------------------------------------------------------------
4522            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4523            //     ...
4524            //     filter Filter,
4525            //     ...
4526            //
4527            // Filter ::= CHOICE {
4528            //     ...
4529            //     approxMatch     [8] AttributeValueAssertion,
4530            //     ...
4531            //
4532            // Init Approx Match filter
4533            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
4534                LdapStatesEnum.OR_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
4535                new InitApproxMatchFilterAction() );
4536    
4537            // --------------------------------------------------------------------------------------------
4538            // Transition from OR to Extensible Match filter
4539            // --------------------------------------------------------------------------------------------
4540            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4541            //     ...
4542            //     filter Filter,
4543            //     ...
4544            //
4545            // Filter ::= CHOICE {
4546            //     ...
4547            //     extensibleMatch  [9] MatchingRuleAssertion,
4548            //     ...
4549            //
4550            // Init Approx Match filter
4551            super.transitions[LdapStatesEnum.OR_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
4552                LdapStatesEnum.OR_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG,
4553                new InitExtensibleMatchFilterAction() );
4554    
4555            // --------------------------------------------------------------------------------------------
4556            // Transition from NOT to AND filter
4557            // --------------------------------------------------------------------------------------------
4558            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4559            //     ...
4560            //     filter Filter,
4561            //     ...
4562            //
4563            // Filter ::= CHOICE {
4564            //     and             [0] SET OF Filter,
4565            //     ...
4566            //
4567            // Init AND filter
4568            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
4569                LdapStatesEnum.NOT_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG, new InitAndFilterAction() );
4570    
4571            // --------------------------------------------------------------------------------------------
4572            // Transition from NOT to OR filter
4573            // --------------------------------------------------------------------------------------------
4574            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4575            //     ...
4576            //     filter Filter,
4577            //     ...
4578            //
4579            // Filter ::= CHOICE {
4580            //     ...
4581            //     or              [1] SET OF Filter,
4582            //     ...
4583            //
4584            // Init OR filter
4585            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
4586                LdapStatesEnum.NOT_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG, new InitOrFilterAction() );
4587    
4588            // --------------------------------------------------------------------------------------------
4589            // Transition from NOT to NOT filter
4590            // --------------------------------------------------------------------------------------------
4591            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4592            //     ...
4593            //     filter Filter,
4594            //     ...
4595            //
4596            // Filter ::= CHOICE {
4597            //     ...
4598            //     not             [2] SET OF Filter,
4599            //     ...
4600            //
4601            // Init NOT filter
4602            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
4603                LdapStatesEnum.NOT_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG, new InitNotFilterAction() );
4604    
4605            // --------------------------------------------------------------------------------------------
4606            // Transition from NOT to Equality Match filter
4607            // --------------------------------------------------------------------------------------------
4608            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4609            //     ...
4610            //     filter Filter,
4611            //     ...
4612            //
4613            // Filter ::= CHOICE {
4614            //     ...
4615            //     equalityMatch   [3] AttributeValueAssertion,
4616            //     ...
4617            //
4618            // Init NOT filter
4619            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
4620                LdapStatesEnum.NOT_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
4621                new InitEqualityMatchFilterAction() );
4622    
4623            // --------------------------------------------------------------------------------------------
4624            // Transition from NOT to Substrings filter
4625            // --------------------------------------------------------------------------------------------
4626            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4627            //     ...
4628            //     filter Filter,
4629            //     ...
4630            //
4631            // Filter ::= CHOICE {
4632            //     ...
4633            //     substrings     [4] SubstringFilter,
4634            //     ...
4635            //
4636            // Init Substrings filter
4637            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
4638                LdapStatesEnum.NOT_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
4639                new InitSubstringsFilterAction() );
4640    
4641            // --------------------------------------------------------------------------------------------
4642            // Transition from NOT to GreaterOrEqual filter
4643            // --------------------------------------------------------------------------------------------
4644            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4645            //     ...
4646            //     filter Filter,
4647            //     ...
4648            //
4649            // Filter ::= CHOICE {
4650            //     ...
4651            //     greaterOrEqual  [5] AttributeValueAssertion,
4652            //     ...
4653            //
4654            // Init Greater Or Equal filter
4655            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4656                LdapStatesEnum.NOT_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE, LdapConstants.GREATER_OR_EQUAL_FILTER_TAG,
4657                new InitGreaterOrEqualFilterAction() );
4658    
4659            // --------------------------------------------------------------------------------------------
4660            // Transition from NOT to LessOrEqual filter
4661            // --------------------------------------------------------------------------------------------
4662            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4663            //     ...
4664            //     filter Filter,
4665            //     ...
4666            //
4667            // Filter ::= CHOICE {
4668            //     ...
4669            //     LessOrEqual    [6] AttributeValueAssertion,
4670            //     ...
4671            //
4672            // Init Less Or Equal filter
4673            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
4674                LdapStatesEnum.NOT_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
4675                new InitLessOrEqualFilterAction() );
4676    
4677            // --------------------------------------------------------------------------------------------
4678            // Transition from NOT to Present filter
4679            // --------------------------------------------------------------------------------------------
4680            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4681            //     ...
4682            //     filter Filter,
4683            //     ...
4684            //
4685            // Filter ::= CHOICE {
4686            //     ...
4687            //     present        [7] AttributeDescription,
4688            //     ...
4689            //
4690            // Init present filter
4691            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
4692                LdapStatesEnum.NOT_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
4693                new InitPresentFilterAction() );
4694    
4695            // --------------------------------------------------------------------------------------------
4696            // Transition from NOT to Approx Match filter
4697            // --------------------------------------------------------------------------------------------
4698            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4699            //     ...
4700            //     filter Filter,
4701            //     ...
4702            //
4703            // Filter ::= CHOICE {
4704            //     ...
4705            //     approxMatch     [8] AttributeValueAssertion,
4706            //     ...
4707            //
4708            // Init Approx Match filter
4709            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
4710                LdapStatesEnum.NOT_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
4711                new InitApproxMatchFilterAction() );
4712    
4713            // --------------------------------------------------------------------------------------------
4714            // Transition from NOT to Extensible Match filter
4715            // --------------------------------------------------------------------------------------------
4716            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4717            //     ...
4718            //     filter Filter,
4719            //     ...
4720            //
4721            // Filter ::= CHOICE {
4722            //     ...
4723            //     extensibleMatch  [9] MatchingRuleAssertion,
4724            //     ...
4725            //
4726            // Init extensible match filter
4727            super.transitions[LdapStatesEnum.NOT_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
4728                LdapStatesEnum.NOT_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG,
4729                new InitExtensibleMatchFilterAction() );
4730    
4731            // --------------------------------------------------------------------------------------------
4732            // Transition from Equality match to Attribute Desc Filter
4733            // --------------------------------------------------------------------------------------------
4734            // Filter ::= CHOICE {
4735            //     ...
4736            //     equalityMatch  [3] AttributeValueAssertion,
4737            //     ...
4738            //
4739            // AttributeValueAssertion ::= SEQUENCE {
4740            //     attributeDesc   AttributeDescription,
4741            //     ...
4742            //
4743            // Init Attribute Desc filter
4744            super.transitions[LdapStatesEnum.EQUALITY_MATCH_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
4745                LdapStatesEnum.EQUALITY_MATCH_STATE, LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE,
4746                UniversalTag.OCTET_STRING_TAG, new InitAttributeDescFilterAction() );
4747    
4748            // --------------------------------------------------------------------------------------------
4749            // Transition from Attribute Desc Filter to Assertion Value Filter
4750            // --------------------------------------------------------------------------------------------
4751            // Filter ::= CHOICE {
4752            //     ...
4753            //     equalityMatch  [3] AttributeValueAssertion,
4754            //     ...
4755            //
4756            // AttributeValueAssertion ::= SEQUENCE {
4757            //     ...
4758            //     assertionValue   AssertionValue }
4759            //
4760            // Init Assertion Value filter
4761            super.transitions[LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
4762                LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE, LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE,
4763                UniversalTag.OCTET_STRING_TAG, new InitAssertionValueFilterAction() );
4764    
4765            // --------------------------------------------------------------------------------------------
4766            // Transition from Assertion Value Filter to AND filter
4767            // --------------------------------------------------------------------------------------------
4768            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4769            //     ...
4770            //     filter Filter,
4771            //     ...
4772            //
4773            // Filter ::= CHOICE {
4774            //     and             [0] SET OF Filter,
4775            //     ...
4776            //
4777            // Init AND filter
4778            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
4779                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
4780                new InitAndFilterAction() );
4781    
4782            // --------------------------------------------------------------------------------------------
4783            // Transition from Assertion Value Filter to OR filter
4784            // --------------------------------------------------------------------------------------------
4785            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4786            //     ...
4787            //     filter Filter,
4788            //     ...
4789            //
4790            // Filter ::= CHOICE {
4791            //     ...
4792            //     or              [1] SET OF Filter,
4793            //     ...
4794            //
4795            // Init OR filter
4796            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
4797                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
4798                new InitOrFilterAction() );
4799    
4800            // --------------------------------------------------------------------------------------------
4801            // Transition from Assertion Value Filter to NOT filter
4802            // --------------------------------------------------------------------------------------------
4803            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4804            //     ...
4805            //     filter Filter,
4806            //     ...
4807            //
4808            // Filter ::= CHOICE {
4809            //     ...
4810            //     not             [2] SET OF Filter,
4811            //     ...
4812            //
4813            // Init NOT filter
4814            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
4815                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
4816                new InitNotFilterAction() );
4817    
4818            // --------------------------------------------------------------------------------------------
4819            // Transition from Assertion Value Filter to Equality Match filter
4820            // --------------------------------------------------------------------------------------------
4821            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4822            //     ...
4823            //     filter Filter,
4824            //     ...
4825            //
4826            // Filter ::= CHOICE {
4827            //     ...
4828            //     equalityMatch   [3] AttributeValueAssertion,
4829            //     ...
4830            //
4831            // Init NOT filter
4832            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = 
4833                new GrammarTransition(
4834                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE,
4835                LdapConstants.EQUALITY_MATCH_FILTER_TAG, new InitEqualityMatchFilterAction() );
4836    
4837            // --------------------------------------------------------------------------------------------
4838            // Transition from Assertion Value Filter to Substrings filter
4839            // --------------------------------------------------------------------------------------------
4840            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4841            //     ...
4842            //     filter Filter,
4843            //     ...
4844            //
4845            // Filter ::= CHOICE {
4846            //     ...
4847            //     substrings     [4] SubstringFilter,
4848            //     ...
4849            //
4850            // Init Substrings filter
4851            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
4852                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE,
4853                LdapConstants.SUBSTRINGS_FILTER_TAG, new InitSubstringsFilterAction() );
4854    
4855            // --------------------------------------------------------------------------------------------
4856            // Transition from Assertion Value Filter to GreaterOrEqual filter
4857            // --------------------------------------------------------------------------------------------
4858            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4859            //     ...
4860            //     filter Filter,
4861            //     ...
4862            //
4863            // Filter ::= CHOICE {
4864            //     ...
4865            //     greaterOrEqual  [5] AttributeValueAssertion,
4866            //     ...
4867            //
4868            // Init Greater Or Equal filter
4869            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = 
4870                new GrammarTransition(
4871                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
4872                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
4873    
4874            // --------------------------------------------------------------------------------------------
4875            // Transition from Assertion Value Filter to LessOrEqual filter
4876            // --------------------------------------------------------------------------------------------
4877            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4878            //     ...
4879            //     filter Filter,
4880            //     ...
4881            //
4882            // Filter ::= CHOICE {
4883            //     ...
4884            //     LessOrEqual    [6] AttributeValueAssertion,
4885            //     ...
4886            //
4887            // Init Less Or Equal filter
4888            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = 
4889                new GrammarTransition(
4890                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE,
4891                LdapConstants.LESS_OR_EQUAL_FILTER_TAG, new InitLessOrEqualFilterAction() );
4892    
4893            // --------------------------------------------------------------------------------------------
4894            // Transition from Assertion Value Filter to Present filter
4895            // --------------------------------------------------------------------------------------------
4896            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4897            //     ...
4898            //     filter Filter,
4899            //     ...
4900            //
4901            // Filter ::= CHOICE {
4902            //     ...
4903            //     present        [7] AttributeDescription,
4904            //     ...
4905            //
4906            // Init present filter
4907            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
4908                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.PRESENT_STATE,
4909                LdapConstants.PRESENT_FILTER_TAG, new InitPresentFilterAction() );
4910    
4911            // --------------------------------------------------------------------------------------------
4912            // Transition from Assertion Value Filter to Approx Match filter
4913            // --------------------------------------------------------------------------------------------
4914            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4915            //     ...
4916            //     filter Filter,
4917            //     ...
4918            //
4919            // Filter ::= CHOICE {
4920            //     ...
4921            //     approxMatch     [8] AttributeValueAssertion,
4922            //     ...
4923            //
4924            // Init Approx Match filter
4925            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = 
4926                new GrammarTransition(
4927                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.APPROX_MATCH_STATE,
4928                LdapConstants.APPROX_MATCH_FILTER_TAG, new InitApproxMatchFilterAction() );
4929    
4930            // --------------------------------------------------------------------------------------------
4931            // Transition from Assertion Value Filter to Extensible Match filter
4932            // --------------------------------------------------------------------------------------------
4933            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4934            //     ...
4935            //     filter Filter,
4936            //     ...
4937            //
4938            // Filter ::= CHOICE {
4939            //     ...
4940            //     extensibleMatch  [9] MatchingRuleAssertion,
4941            //     ...
4942            //
4943            // Init Assertion Value Filter filter
4944            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = 
4945                new GrammarTransition(
4946                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
4947                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
4948    
4949            // --------------------------------------------------------------------------------------------
4950            // Transition from Assertion Value Filter to Attribute Description List
4951            // --------------------------------------------------------------------------------------------
4952            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4953            //     ...
4954            //     filter      Filter,
4955            //     attributes  AttributeDescriptionList }
4956            //
4957            // AttributeDescriptionList ::= SEQUENCE OF
4958            //     AttributeDescription
4959            //
4960            // Init attribute description list
4961            super.transitions[LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
4962                LdapStatesEnum.ASSERTION_VALUE_FILTER_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE,
4963                UniversalTag.SEQUENCE_TAG, new InitAttributeDescListAction() );
4964    
4965            // --------------------------------------------------------------------------------------------
4966            // Transition from Attribute Description List to AttributeDescription
4967            // --------------------------------------------------------------------------------------------
4968            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4969            //     ...
4970            //     filter      Filter,
4971            //     attributes  AttributeDescriptionList }
4972            //
4973            // AttributeDescriptionList ::= SEQUENCE OF
4974            //     AttributeDescription
4975            //
4976            // Store attribute description
4977            super.transitions[LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
4978                LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE,
4979                UniversalTag.OCTET_STRING_TAG, new AttributeDescAction() );
4980    
4981            // --------------------------------------------------------------------------------------------
4982            // Transition from Attribute Description List to Controls
4983            // --------------------------------------------------------------------------------------------
4984            //         searchRequest   SearchRequest,
4985            //         ... },
4986            //     controls       [0] Controls OPTIONAL }
4987            //
4988            // Empty attribute description list, with controls
4989            super.transitions[LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
4990                LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
4991                new ControlsInitAction() );
4992    
4993            // --------------------------------------------------------------------------------------------
4994            // Transition from Attribute Description to AttributeDescription
4995            // --------------------------------------------------------------------------------------------
4996            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
4997            //     ...
4998            //     filter      Filter,
4999            //     attributes  AttributeDescriptionList }
5000            //
5001            // AttributeDescriptionList ::= SEQUENCE OF
5002            //     AttributeDescription
5003            //
5004            // Store attribute description
5005            super.transitions[LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
5006                LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE,
5007                UniversalTag.OCTET_STRING_TAG, new AttributeDescAction() );
5008    
5009            // --------------------------------------------------------------------------------------------
5010            // transition from Attribute Description to Controls.
5011            // --------------------------------------------------------------------------------------------
5012            //         searchRequest   SearchRequest,
5013            //         ... },
5014            //     controls       [0] Controls OPTIONAL }
5015            //
5016            super.transitions[LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
5017                LdapStatesEnum.ATTRIBUTE_DESCRIPTION_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
5018                new ControlsInitAction() );
5019    
5020            // --------------------------------------------------------------------------------------------
5021            // Transition from Greater Or Equal to Attribute Desc Filter
5022            // --------------------------------------------------------------------------------------------
5023            // Filter ::= CHOICE {
5024            //     ...
5025            //     greaterOrEqual  [5] AttributeValueAssertion,
5026            //     ...
5027            //
5028            // AttributeValueAssertion ::= SEQUENCE {
5029            //     attributeDesc   AttributeDescription,
5030            //     ...
5031            //
5032            // Init Attribute Desc filter
5033            super.transitions[LdapStatesEnum.GREATER_OR_EQUAL_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
5034                LdapStatesEnum.GREATER_OR_EQUAL_STATE, LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE,
5035                UniversalTag.OCTET_STRING_TAG, new InitAttributeDescFilterAction() );
5036    
5037            // --------------------------------------------------------------------------------------------
5038            // Transition from Less Or Equal to Attribute Desc Filter
5039            // --------------------------------------------------------------------------------------------
5040            // Filter ::= CHOICE {
5041            //     ...
5042            //     lessOrEqual  [6] AttributeValueAssertion,
5043            //     ...
5044            //
5045            // AttributeValueAssertion ::= SEQUENCE {
5046            //     attributeDesc   AttributeDescription,
5047            //     ...
5048            //
5049            // Init Attribute Desc filter
5050            super.transitions[LdapStatesEnum.LESS_OR_EQUAL_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
5051                LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE,
5052                UniversalTag.OCTET_STRING_TAG, new InitAttributeDescFilterAction() );
5053    
5054            // --------------------------------------------------------------------------------------------
5055            // Transition from Substrings to typeSubstring
5056            // --------------------------------------------------------------------------------------------
5057            // Filter ::= CHOICE {
5058            //     ...
5059            //     substrings  [4] SubstringFilter,
5060            //     ...
5061            //
5062            // SubstringFilter ::= SEQUENCE {
5063            //     type   AttributeDescription,
5064            //     ...
5065            //
5066            // Init substring type
5067            super.transitions[LdapStatesEnum.SUBSTRING_FILTER_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
5068                LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapStatesEnum.TYPE_SUBSTRING_STATE, UniversalTag.OCTET_STRING_TAG,
5069                new GrammarAction( "Store substring filter type" )
5070                {
5071                    public void action( IAsn1Container container ) throws DecoderException
5072                    {
5073                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
5074                        SearchRequestCodec searchRequest = ldapMessageContainer.getSearchRequest();
5075    
5076                        TLV tlv = ldapMessageContainer.getCurrentTLV();
5077    
5078                        // Store the value.
5079                        SubstringFilter substringFilter = ( SubstringFilter ) searchRequest.getTerminalFilter();
5080    
5081                        if ( tlv.getLength() == 0 )
5082                        {
5083                            log.error( I18n.err( I18n.ERR_04106 ) );
5084                            throw new DecoderException( I18n.err( I18n.ERR_04106 ) );
5085                        }
5086                        else
5087                        {
5088                            String type = StringTools.getType( tlv.getValue().getData() );
5089                            substringFilter.setType( type );
5090    
5091                            // We now have to get back to the nearest filter which
5092                            // is not terminal.
5093                            searchRequest.setTerminalFilter( substringFilter );
5094                        }
5095                    }
5096                } );
5097    
5098            // --------------------------------------------------------------------------------------------
5099            // Transition from typeSubstring to substrings
5100            // --------------------------------------------------------------------------------------------
5101            // Filter ::= CHOICE {
5102            //     ...
5103            //     substrings  [4] SubstringFilter,
5104            //     ...
5105            //
5106            // SubstringFilter ::= SEQUENCE {
5107            //     ...
5108            //     substrings SEQUENCE OF CHOICE {
5109            //     ...
5110            //
5111            // Init substring type
5112            super.transitions[LdapStatesEnum.TYPE_SUBSTRING_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
5113                LdapStatesEnum.TYPE_SUBSTRING_STATE, LdapStatesEnum.SUBSTRINGS_STATE, UniversalTag.SEQUENCE_TAG,
5114                new GrammarAction( "Substring Filter substringsSequence " )
5115                {
5116                    public void action( IAsn1Container container ) throws DecoderException
5117                    {
5118                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
5119    
5120                        TLV tlv = ldapMessageContainer.getCurrentTLV();
5121    
5122                        if ( tlv.getLength() == 0 )
5123                        {
5124                            log.error( I18n.err( I18n.ERR_04107 ) );
5125                            throw new DecoderException( "The substring sequence is empty" );
5126                        }
5127                    }
5128                } );
5129    
5130            // --------------------------------------------------------------------------------------------
5131            // Transition from substrings to Initial
5132            // --------------------------------------------------------------------------------------------
5133            // SubstringFilter ::= SEQUENCE {
5134            //     ...
5135            //     substrings SEQUENCE OF CHOICE {
5136            //         initial  [0] LDAPSTRING,
5137            //         ...
5138            //
5139            // Store initial value
5140            super.transitions[LdapStatesEnum.SUBSTRINGS_STATE][LdapConstants.SUBSTRINGS_FILTER_INITIAL_TAG] = new GrammarTransition(
5141                LdapStatesEnum.SUBSTRINGS_STATE, LdapStatesEnum.INITIAL_STATE, LdapConstants.SUBSTRINGS_FILTER_INITIAL_TAG,
5142                new GrammarAction( "Store substring filter initial Value" )
5143                {
5144                    public void action( IAsn1Container container ) throws DecoderException
5145                    {
5146                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
5147                        SearchRequestCodec searchRequest = ldapMessageContainer.getSearchRequest();
5148    
5149                        TLV tlv = ldapMessageContainer.getCurrentTLV();
5150    
5151                        // Store the value.
5152                        SubstringFilter substringFilter = ( SubstringFilter ) searchRequest.getTerminalFilter();
5153    
5154                        if ( tlv.getLength() == 0 )
5155                        {
5156                            log.error( I18n.err( I18n.ERR_04108 ) );
5157                            throw new DecoderException( I18n.err( I18n.ERR_04108 ) );
5158                        }
5159    
5160                        substringFilter.setInitialSubstrings( StringTools.utf8ToString( tlv.getValue().getData() ) );
5161    
5162                        // We now have to get back to the nearest filter which is
5163                        // not terminal.
5164                        searchRequest.unstackFilters( container );
5165                    }
5166                } );
5167    
5168            // --------------------------------------------------------------------------------------------
5169            // Transition from substrings to any
5170            // --------------------------------------------------------------------------------------------
5171            // SubstringFilter ::= SEQUENCE {
5172            //     ...
5173            //     substrings SEQUENCE OF CHOICE {
5174            //         ...
5175            //         any  [1] LDAPSTRING,
5176            //         ...
5177            //
5178            // Store substring any type
5179            super.transitions[LdapStatesEnum.SUBSTRINGS_STATE][LdapConstants.SUBSTRINGS_FILTER_ANY_TAG] = new GrammarTransition(
5180                LdapStatesEnum.SUBSTRINGS_STATE, LdapStatesEnum.ANY_STATE, LdapConstants.SUBSTRINGS_FILTER_ANY_TAG,
5181                new StoreAnyAction() );
5182    
5183            // --------------------------------------------------------------------------------------------
5184            // Transition from substrings to final
5185            // --------------------------------------------------------------------------------------------
5186            // SubstringFilter ::= SEQUENCE {
5187            //     ...
5188            //     substrings SEQUENCE OF CHOICE {
5189            //         ...
5190            //         final  [2] LDAPSTRING }
5191            //
5192            // Store substring final type
5193            super.transitions[LdapStatesEnum.SUBSTRINGS_STATE][LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG] = new GrammarTransition(
5194                LdapStatesEnum.SUBSTRINGS_STATE, LdapStatesEnum.FINAL_STATE, LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG,
5195                new StoreFinalAction() );
5196    
5197            // --------------------------------------------------------------------------------------------
5198            // Transition from initial to any
5199            // --------------------------------------------------------------------------------------------
5200            // SubstringFilter ::= SEQUENCE {
5201            //     ...
5202            //     substrings SEQUENCE OF CHOICE {
5203            //         ...
5204            //         any  [1] LDAPSTRING,
5205            //         ...
5206            //
5207            // Store substring any type
5208            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.SUBSTRINGS_FILTER_ANY_TAG] = new GrammarTransition(
5209                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.ANY_STATE, LdapConstants.SUBSTRINGS_FILTER_ANY_TAG,
5210                new StoreAnyAction() );
5211    
5212            // --------------------------------------------------------------------------------------------
5213            // Transition from initial to final
5214            // --------------------------------------------------------------------------------------------
5215            // SubstringFilter ::= SEQUENCE {
5216            //     ...
5217            //     substrings SEQUENCE OF CHOICE {
5218            //         ...
5219            //         final  [2] LDAPSTRING }
5220            //
5221            // Store substring final type
5222            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG] = new GrammarTransition(
5223                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.FINAL_STATE, LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG,
5224                new StoreFinalAction() );
5225    
5226            // --------------------------------------------------------------------------------------------
5227            // Transition from initial to Attribute Description List
5228            // --------------------------------------------------------------------------------------------
5229            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5230            //     ...
5231            //     filter      Filter,
5232            //     attributes  AttributeDescriptionList }
5233            //
5234            // AttributeDescriptionList ::= SEQUENCE OF
5235            //     AttributeDescription
5236            //
5237            // Init attribute description list
5238            super.transitions[LdapStatesEnum.INITIAL_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
5239                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, UniversalTag.SEQUENCE_TAG,
5240                new InitAttributeDescListAction() );
5241    
5242            // --------------------------------------------------------------------------------------------
5243            // Transition from initial to AND filter
5244            // --------------------------------------------------------------------------------------------
5245            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5246            //     ...
5247            //     filter Filter,
5248            //     ...
5249            //
5250            // Filter ::= CHOICE {
5251            //     and             [0] SET OF Filter,
5252            //     ...
5253            //
5254            // Init AND filter
5255            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
5256                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
5257                new InitAndFilterAction() );
5258    
5259            // --------------------------------------------------------------------------------------------
5260            // Transition from initial to OR filter
5261            // --------------------------------------------------------------------------------------------
5262            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5263            //     ...
5264            //     filter Filter,
5265            //     ...
5266            //
5267            // Filter ::= CHOICE {
5268            //     ...
5269            //     or              [1] SET OF Filter,
5270            //     ...
5271            //
5272            // Init OR filter
5273            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
5274                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
5275                new InitOrFilterAction() );
5276    
5277            // --------------------------------------------------------------------------------------------
5278            // Transition from initial to NOT filter
5279            // --------------------------------------------------------------------------------------------
5280            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5281            //     ...
5282            //     filter Filter,
5283            //     ...
5284            //
5285            // Filter ::= CHOICE {
5286            //     ...
5287            //     not             [2] SET OF Filter,
5288            //     ...
5289            //
5290            // Init NOT filter
5291            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
5292                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
5293                new InitNotFilterAction() );
5294    
5295            // --------------------------------------------------------------------------------------------
5296            // Transition from initial to Equality Match filter
5297            // --------------------------------------------------------------------------------------------
5298            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5299            //     ...
5300            //     filter Filter,
5301            //     ...
5302            //
5303            // Filter ::= CHOICE {
5304            //     ...
5305            //     equalityMatch   [3] AttributeValueAssertion,
5306            //     ...
5307            //
5308            // Init NOT filter
5309            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
5310                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
5311                new InitEqualityMatchFilterAction() );
5312    
5313            // --------------------------------------------------------------------------------------------
5314            // Transition from initial to Substrings filter
5315            // --------------------------------------------------------------------------------------------
5316            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5317            //     ...
5318            //     filter Filter,
5319            //     ...
5320            //
5321            // Filter ::= CHOICE {
5322            //     ...
5323            //     substrings     [4] SubstringFilter,
5324            //     ...
5325            //
5326            // Init Substrings filter
5327            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
5328                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
5329                new InitSubstringsFilterAction() );
5330    
5331            // --------------------------------------------------------------------------------------------
5332            // Transition from initial to GreaterOrEqual filter
5333            // --------------------------------------------------------------------------------------------
5334            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5335            //     ...
5336            //     filter Filter,
5337            //     ...
5338            //
5339            // Filter ::= CHOICE {
5340            //     ...
5341            //     greaterOrEqual  [5] AttributeValueAssertion,
5342            //     ...
5343            //
5344            // Init Greater Or Equal filter
5345            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5346                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
5347                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
5348    
5349            // --------------------------------------------------------------------------------------------
5350            // Transition from initial to LessOrEqual filter
5351            // --------------------------------------------------------------------------------------------
5352            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5353            //     ...
5354            //     filter Filter,
5355            //     ...
5356            //
5357            // Filter ::= CHOICE {
5358            //     ...
5359            //     LessOrEqual    [6] AttributeValueAssertion,
5360            //     ...
5361            //
5362            // Init Less Or Equal filter
5363            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5364                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
5365                new InitLessOrEqualFilterAction() );
5366    
5367            // --------------------------------------------------------------------------------------------
5368            // Transition from initial to Present filter
5369            // --------------------------------------------------------------------------------------------
5370            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5371            //     ...
5372            //     filter Filter,
5373            //     ...
5374            //
5375            // Filter ::= CHOICE {
5376            //     ...
5377            //     present        [7] AttributeDescription,
5378            //     ...
5379            //
5380            // Init present filter
5381            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
5382                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
5383                new InitPresentFilterAction() );
5384    
5385            // --------------------------------------------------------------------------------------------
5386            // Transition from initial to Approx Match filter
5387            // --------------------------------------------------------------------------------------------
5388            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5389            //     ...
5390            //     filter Filter,
5391            //     ...
5392            //
5393            // Filter ::= CHOICE {
5394            //     ...
5395            //     approxMatch     [8] AttributeValueAssertion,
5396            //     ...
5397            //
5398            // Init Approx Match filter
5399            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
5400                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
5401                new InitApproxMatchFilterAction() );
5402    
5403            // --------------------------------------------------------------------------------------------
5404            // Transition from initial to Extensible Match filter
5405            // --------------------------------------------------------------------------------------------
5406            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5407            //     ...
5408            //     filter Filter,
5409            //     ...
5410            //
5411            // Filter ::= CHOICE {
5412            //     ...
5413            //     extensibleMatch  [9] MatchingRuleAssertion,
5414            //     ...
5415            //
5416            // Init Assertion Value Filter filter
5417            super.transitions[LdapStatesEnum.INITIAL_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
5418                LdapStatesEnum.INITIAL_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
5419                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
5420    
5421            // --------------------------------------------------------------------------------------------
5422            // Transition from any to final
5423            // --------------------------------------------------------------------------------------------
5424            // SubstringFilter ::= SEQUENCE {
5425            //     ...
5426            //     substrings SEQUENCE OF CHOICE {
5427            //         ...
5428            //         final  [2] LDAPSTRING }
5429            //
5430            // Store substring final type
5431            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG] = new GrammarTransition(
5432                LdapStatesEnum.ANY_STATE, LdapStatesEnum.FINAL_STATE, LdapConstants.SUBSTRINGS_FILTER_FINAL_TAG,
5433                new StoreFinalAction() );
5434    
5435            // --------------------------------------------------------------------------------------------
5436            // Transition from any to any
5437            // --------------------------------------------------------------------------------------------
5438            // SubstringFilter ::= SEQUENCE {
5439            //     ...
5440            //     substrings SEQUENCE OF CHOICE {
5441            //         ...
5442            //         any  [1] LDAPSTRING 
5443            //         ...
5444            //
5445            // Store substring any type
5446            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.SUBSTRINGS_FILTER_ANY_TAG] = new GrammarTransition(
5447                LdapStatesEnum.ANY_STATE, LdapStatesEnum.ANY_STATE, LdapConstants.SUBSTRINGS_FILTER_ANY_TAG,
5448                new StoreAnyAction() );
5449    
5450            // --------------------------------------------------------------------------------------------
5451            // Transition from any to Attribute Description List
5452            // --------------------------------------------------------------------------------------------
5453            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5454            //     ...
5455            //     filter      Filter,
5456            //     attributes  AttributeDescriptionList }
5457            //
5458            // AttributeDescriptionList ::= SEQUENCE OF
5459            //     AttributeDescription
5460            //
5461            // Init attribute description list
5462            super.transitions[LdapStatesEnum.ANY_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
5463                LdapStatesEnum.ANY_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, UniversalTag.SEQUENCE_TAG,
5464                new InitAttributeDescListAction() );
5465    
5466            // --------------------------------------------------------------------------------------------
5467            // Transition from any to AND filter
5468            // --------------------------------------------------------------------------------------------
5469            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5470            //     ...
5471            //     filter Filter,
5472            //     ...
5473            //
5474            // Filter ::= CHOICE {
5475            //     and             [0] SET OF Filter,
5476            //     ...
5477            //
5478            // Init AND filter
5479            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
5480                LdapStatesEnum.ANY_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG, new InitAndFilterAction() );
5481    
5482            // --------------------------------------------------------------------------------------------
5483            // Transition from any to OR filter
5484            // --------------------------------------------------------------------------------------------
5485            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5486            //     ...
5487            //     filter Filter,
5488            //     ...
5489            //
5490            // Filter ::= CHOICE {
5491            //     ...
5492            //     or              [1] SET OF Filter,
5493            //     ...
5494            //
5495            // Init OR filter
5496            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
5497                LdapStatesEnum.ANY_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG, new InitOrFilterAction() );
5498    
5499            // --------------------------------------------------------------------------------------------
5500            // Transition from any to NOT filter
5501            // --------------------------------------------------------------------------------------------
5502            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5503            //     ...
5504            //     filter Filter,
5505            //     ...
5506            //
5507            // Filter ::= CHOICE {
5508            //     ...
5509            //     not             [2] SET OF Filter,
5510            //     ...
5511            //
5512            // Init NOT filter
5513            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
5514                LdapStatesEnum.ANY_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG, new InitNotFilterAction() );
5515    
5516            // --------------------------------------------------------------------------------------------
5517            // Transition from any to Equality Match filter
5518            // --------------------------------------------------------------------------------------------
5519            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5520            //     ...
5521            //     filter Filter,
5522            //     ...
5523            //
5524            // Filter ::= CHOICE {
5525            //     ...
5526            //     equalityMatch   [3] AttributeValueAssertion,
5527            //     ...
5528            //
5529            // Init NOT filter
5530            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
5531                LdapStatesEnum.ANY_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
5532                new InitEqualityMatchFilterAction() );
5533    
5534            // --------------------------------------------------------------------------------------------
5535            // Transition from any to Substrings filter
5536            // --------------------------------------------------------------------------------------------
5537            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5538            //     ...
5539            //     filter Filter,
5540            //     ...
5541            //
5542            // Filter ::= CHOICE {
5543            //     ...
5544            //     substrings     [4] SubstringFilter,
5545            //     ...
5546            //
5547            // Init Substrings filter
5548            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
5549                LdapStatesEnum.ANY_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
5550                new InitSubstringsFilterAction() );
5551    
5552            // --------------------------------------------------------------------------------------------
5553            // Transition from any to GreaterOrEqual filter
5554            // --------------------------------------------------------------------------------------------
5555            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5556            //     ...
5557            //     filter Filter,
5558            //     ...
5559            //
5560            // Filter ::= CHOICE {
5561            //     ...
5562            //     greaterOrEqual  [5] AttributeValueAssertion,
5563            //     ...
5564            //
5565            // Init Greater Or Equal filter
5566            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5567                LdapStatesEnum.ANY_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE, LdapConstants.GREATER_OR_EQUAL_FILTER_TAG,
5568                new InitGreaterOrEqualFilterAction() );
5569    
5570            // --------------------------------------------------------------------------------------------
5571            // Transition from any to LessOrEqual filter
5572            // --------------------------------------------------------------------------------------------
5573            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5574            //     ...
5575            //     filter Filter,
5576            //     ...
5577            //
5578            // Filter ::= CHOICE {
5579            //     ...
5580            //     LessOrEqual    [6] AttributeValueAssertion,
5581            //     ...
5582            //
5583            // Init Less Or Equal filter
5584            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5585                LdapStatesEnum.ANY_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
5586                new InitLessOrEqualFilterAction() );
5587    
5588            // --------------------------------------------------------------------------------------------
5589            // Transition from any to Present filter
5590            // --------------------------------------------------------------------------------------------
5591            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5592            //     ...
5593            //     filter Filter,
5594            //     ...
5595            //
5596            // Filter ::= CHOICE {
5597            //     ...
5598            //     present        [7] AttributeDescription,
5599            //     ...
5600            //
5601            // Init present filter
5602            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
5603                LdapStatesEnum.ANY_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
5604                new InitPresentFilterAction() );
5605    
5606            // --------------------------------------------------------------------------------------------
5607            // Transition from any to Approx Match filter
5608            // --------------------------------------------------------------------------------------------
5609            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5610            //     ...
5611            //     filter Filter,
5612            //     ...
5613            //
5614            // Filter ::= CHOICE {
5615            //     ...
5616            //     approxMatch     [8] AttributeValueAssertion,
5617            //     ...
5618            //
5619            // Init Approx Match filter
5620            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
5621                LdapStatesEnum.ANY_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
5622                new InitApproxMatchFilterAction() );
5623    
5624            // --------------------------------------------------------------------------------------------
5625            // Transition from any to Extensible Match filter
5626            // --------------------------------------------------------------------------------------------
5627            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5628            //     ...
5629            //     filter Filter,
5630            //     ...
5631            //
5632            // Filter ::= CHOICE {
5633            //     ...
5634            //     extensibleMatch  [9] MatchingRuleAssertion,
5635            //     ...
5636            //
5637            // Init Assertion Value Filter filter
5638            super.transitions[LdapStatesEnum.ANY_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
5639                LdapStatesEnum.ANY_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG,
5640                new InitExtensibleMatchFilterAction() );
5641    
5642            // --------------------------------------------------------------------------------------------
5643            // Transition from final to Attribute Description List
5644            // --------------------------------------------------------------------------------------------
5645            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5646            //     ...
5647            //     filter      Filter,
5648            //     attributes  AttributeDescriptionList }
5649            //
5650            // AttributeDescriptionList ::= SEQUENCE OF
5651            //     AttributeDescription
5652            //
5653            // Init attribute description list
5654            super.transitions[LdapStatesEnum.FINAL_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
5655                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, UniversalTag.SEQUENCE_TAG,
5656                new InitAttributeDescListAction() );
5657    
5658            // --------------------------------------------------------------------------------------------
5659            // Transition from final to AND filter
5660            // --------------------------------------------------------------------------------------------
5661            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5662            //     ...
5663            //     filter Filter,
5664            //     ...
5665            //
5666            // Filter ::= CHOICE {
5667            //     and             [0] SET OF Filter,
5668            //     ...
5669            //
5670            // Init AND filter
5671            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
5672                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
5673                new InitAndFilterAction() );
5674    
5675            // --------------------------------------------------------------------------------------------
5676            // Transition from final to OR filter
5677            // --------------------------------------------------------------------------------------------
5678            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5679            //     ...
5680            //     filter Filter,
5681            //     ...
5682            //
5683            // Filter ::= CHOICE {
5684            //     ...
5685            //     or              [1] SET OF Filter,
5686            //     ...
5687            //
5688            // Init OR filter
5689            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
5690                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG, new InitOrFilterAction() );
5691    
5692            // --------------------------------------------------------------------------------------------
5693            // Transition from final to NOT filter
5694            // --------------------------------------------------------------------------------------------
5695            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5696            //     ...
5697            //     filter Filter,
5698            //     ...
5699            //
5700            // Filter ::= CHOICE {
5701            //     ...
5702            //     not             [2] SET OF Filter,
5703            //     ...
5704            //
5705            // Init NOT filter
5706            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
5707                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
5708                new InitNotFilterAction() );
5709    
5710            // --------------------------------------------------------------------------------------------
5711            // Transition from final to Equality Match filter
5712            // --------------------------------------------------------------------------------------------
5713            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5714            //     ...
5715            //     filter Filter,
5716            //     ...
5717            //
5718            // Filter ::= CHOICE {
5719            //     ...
5720            //     equalityMatch   [3] AttributeValueAssertion,
5721            //     ...
5722            //
5723            // Init NOT filter
5724            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
5725                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
5726                new InitEqualityMatchFilterAction() );
5727    
5728            // --------------------------------------------------------------------------------------------
5729            // Transition from final to Substrings filter
5730            // --------------------------------------------------------------------------------------------
5731            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5732            //     ...
5733            //     filter Filter,
5734            //     ...
5735            //
5736            // Filter ::= CHOICE {
5737            //     ...
5738            //     substrings     [4] SubstringFilter,
5739            //     ...
5740            //
5741            // Init Substrings filter
5742            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
5743                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
5744                new InitSubstringsFilterAction() );
5745    
5746            // --------------------------------------------------------------------------------------------
5747            // Transition from final to GreaterOrEqual filter
5748            // --------------------------------------------------------------------------------------------
5749            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5750            //     ...
5751            //     filter Filter,
5752            //     ...
5753            //
5754            // Filter ::= CHOICE {
5755            //     ...
5756            //     greaterOrEqual  [5] AttributeValueAssertion,
5757            //     ...
5758            //
5759            // Init Greater Or Equal filter
5760            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5761                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
5762                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
5763    
5764            // --------------------------------------------------------------------------------------------
5765            // Transition from final to LessOrEqual filter
5766            // --------------------------------------------------------------------------------------------
5767            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5768            //     ...
5769            //     filter Filter,
5770            //     ...
5771            //
5772            // Filter ::= CHOICE {
5773            //     ...
5774            //     LessOrEqual    [6] AttributeValueAssertion,
5775            //     ...
5776            //
5777            // Init Less Or Equal filter
5778            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5779                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
5780                new InitLessOrEqualFilterAction() );
5781    
5782            // --------------------------------------------------------------------------------------------
5783            // Transition from final to Present filter
5784            // --------------------------------------------------------------------------------------------
5785            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5786            //     ...
5787            //     filter Filter,
5788            //     ...
5789            //
5790            // Filter ::= CHOICE {
5791            //     ...
5792            //     present        [7] AttributeDescription,
5793            //     ...
5794            //
5795            // Init present filter
5796            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
5797                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
5798                new InitPresentFilterAction() );
5799    
5800            // --------------------------------------------------------------------------------------------
5801            // Transition from final to Approx Match filter
5802            // --------------------------------------------------------------------------------------------
5803            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5804            //     ...
5805            //     filter Filter,
5806            //     ...
5807            //
5808            // Filter ::= CHOICE {
5809            //     ...
5810            //     approxMatch     [8] AttributeValueAssertion,
5811            //     ...
5812            //
5813            // Init Approx Match filter
5814            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
5815                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
5816                new InitApproxMatchFilterAction() );
5817    
5818            // --------------------------------------------------------------------------------------------
5819            // Transition from final to Extensible Match filter
5820            // --------------------------------------------------------------------------------------------
5821            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5822            //     ...
5823            //     filter Filter,
5824            //     ...
5825            //
5826            // Filter ::= CHOICE {
5827            //     ...
5828            //     extensibleMatch  [9] MatchingRuleAssertion,
5829            //     ...
5830            //
5831            // Init Assertion Value Filter filter
5832            super.transitions[LdapStatesEnum.FINAL_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
5833                LdapStatesEnum.FINAL_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
5834                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
5835    
5836            // --------------------------------------------------------------------------------------------
5837            // Transition from Present Filter to AND filter
5838            // --------------------------------------------------------------------------------------------
5839            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5840            //     ...
5841            //     filter Filter,
5842            //     ...
5843            //
5844            // Filter ::= CHOICE {
5845            //     and             [0] SET OF Filter,
5846            //     ...
5847            //
5848            // Init AND filter
5849            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
5850                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
5851                new InitAndFilterAction() );
5852    
5853            // --------------------------------------------------------------------------------------------
5854            // Transition from Present Filter to OR filter
5855            // --------------------------------------------------------------------------------------------
5856            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5857            //     ...
5858            //     filter Filter,
5859            //     ...
5860            //
5861            // Filter ::= CHOICE {
5862            //     ...
5863            //     or              [1] SET OF Filter,
5864            //     ...
5865            //
5866            // Init OR filter
5867            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
5868                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
5869                new InitOrFilterAction() );
5870    
5871            // --------------------------------------------------------------------------------------------
5872            // Transition from Present Filter to NOT filter
5873            // --------------------------------------------------------------------------------------------
5874            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5875            //     ...
5876            //     filter Filter,
5877            //     ...
5878            //
5879            // Filter ::= CHOICE {
5880            //     ...
5881            //     not             [2] SET OF Filter,
5882            //     ...
5883            //
5884            // Init NOT filter
5885            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
5886                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
5887                new InitNotFilterAction() );
5888    
5889            // --------------------------------------------------------------------------------------------
5890            // Transition from Present Filter to Equality Match filter
5891            // --------------------------------------------------------------------------------------------
5892            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5893            //     ...
5894            //     filter Filter,
5895            //     ...
5896            //
5897            // Filter ::= CHOICE {
5898            //     ...
5899            //     equalityMatch   [3] AttributeValueAssertion,
5900            //     ...
5901            //
5902            // Init NOT filter
5903            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
5904                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE, LdapConstants.EQUALITY_MATCH_FILTER_TAG,
5905                new InitEqualityMatchFilterAction() );
5906    
5907            // --------------------------------------------------------------------------------------------
5908            // Transition from Present Filter to Substrings filter
5909            // --------------------------------------------------------------------------------------------
5910            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5911            //     ...
5912            //     filter Filter,
5913            //     ...
5914            //
5915            // Filter ::= CHOICE {
5916            //     ...
5917            //     substrings     [4] SubstringFilter,
5918            //     ...
5919            //
5920            // Init Substrings filter
5921            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
5922                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE, LdapConstants.SUBSTRINGS_FILTER_TAG,
5923                new InitSubstringsFilterAction() );
5924    
5925            // --------------------------------------------------------------------------------------------
5926            // Transition from Present Filter to GreaterOrEqual filter
5927            // --------------------------------------------------------------------------------------------
5928            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5929            //     ...
5930            //     filter Filter,
5931            //     ...
5932            //
5933            // Filter ::= CHOICE {
5934            //     ...
5935            //     greaterOrEqual  [5] AttributeValueAssertion,
5936            //     ...
5937            //
5938            // Init Greater Or Equal filter
5939            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5940                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
5941                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
5942    
5943            // --------------------------------------------------------------------------------------------
5944            // Transition from Present Filter to LessOrEqual filter
5945            // --------------------------------------------------------------------------------------------
5946            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5947            //     ...
5948            //     filter Filter,
5949            //     ...
5950            //
5951            // Filter ::= CHOICE {
5952            //     ...
5953            //     LessOrEqual    [6] AttributeValueAssertion,
5954            //     ...
5955            //
5956            // Init Less Or Equal filter
5957            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
5958                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE, LdapConstants.LESS_OR_EQUAL_FILTER_TAG,
5959                new InitLessOrEqualFilterAction() );
5960    
5961            // --------------------------------------------------------------------------------------------
5962            // Transition from Present Filter to Present filter
5963            // --------------------------------------------------------------------------------------------
5964            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5965            //     ...
5966            //     filter Filter,
5967            //     ...
5968            //
5969            // Filter ::= CHOICE {
5970            //     ...
5971            //     present        [7] AttributeDescription,
5972            //     ...
5973            //
5974            // Init present filter
5975            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
5976                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
5977                new InitPresentFilterAction() );
5978    
5979            // --------------------------------------------------------------------------------------------
5980            // Transition from Present Filter to Approx Match filter
5981            // --------------------------------------------------------------------------------------------
5982            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
5983            //     ...
5984            //     filter Filter,
5985            //     ...
5986            //
5987            // Filter ::= CHOICE {
5988            //     ...
5989            //     approxMatch     [8] AttributeValueAssertion,
5990            //     ...
5991            //
5992            // Init Approx Match filter
5993            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
5994                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
5995                new InitApproxMatchFilterAction() );
5996    
5997            // --------------------------------------------------------------------------------------------
5998            // Transition from Present Filter to Extensible Match filter
5999            // --------------------------------------------------------------------------------------------
6000            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6001            //     ...
6002            //     filter Filter,
6003            //     ...
6004            //
6005            // Filter ::= CHOICE {
6006            //     ...
6007            //     extensibleMatch  [9] MatchingRuleAssertion,
6008            //     ...
6009            //
6010            // Init Assertion Value Filter filter
6011            super.transitions[LdapStatesEnum.PRESENT_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
6012                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
6013                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
6014    
6015            // --------------------------------------------------------------------------------------------
6016            // Transition from Present Filter to Attribute Description List
6017            // --------------------------------------------------------------------------------------------
6018            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6019            //     ...
6020            //     filter      Filter,
6021            //     attributes  AttributeDescriptionList }
6022            //
6023            // AttributeDescriptionList ::= SEQUENCE OF
6024            //     AttributeDescription
6025            //
6026            // Init attribute description list
6027            super.transitions[LdapStatesEnum.PRESENT_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
6028                LdapStatesEnum.PRESENT_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE, UniversalTag.SEQUENCE_TAG,
6029                new InitAttributeDescListAction() );
6030    
6031            // --------------------------------------------------------------------------------------------
6032            // Transition from Approx Match to Attribute Desc Filter
6033            // --------------------------------------------------------------------------------------------
6034            // Filter ::= CHOICE {
6035            //     ...
6036            //     approxMatch  [8] AttributeValueAssertion,
6037            //     ...
6038            //
6039            // AttributeValueAssertion ::= SEQUENCE {
6040            //     attributeDesc   AttributeDescription,
6041            //     ...
6042            //
6043            // Init Attribute Desc filter
6044            super.transitions[LdapStatesEnum.APPROX_MATCH_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
6045                LdapStatesEnum.APPROX_MATCH_STATE, LdapStatesEnum.ATTRIBUTE_DESC_FILTER_STATE,
6046                UniversalTag.OCTET_STRING_TAG, new InitAttributeDescFilterAction() );
6047    
6048            // --------------------------------------------------------------------------------------------
6049            // Transition from Extensible Match to MatchingRule
6050            // --------------------------------------------------------------------------------------------
6051            // Filter ::= CHOICE {
6052            //     ...
6053            //     extensibleMatch  [9] MatchingRuleAssertion }
6054            //
6055            // MatchingRuleAssertion ::= SEQUENCE {
6056            //     matchingRule [1] MatchingRuleId OPTIONAL,
6057            //     ...
6058            //
6059            // Store the matching rule ID 
6060            super.transitions[LdapStatesEnum.EXTENSIBLE_MATCH_STATE][LdapConstants.MATCHING_RULE_ID_TAG] = new GrammarTransition(
6061                LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapStatesEnum.MATCHING_RULE_STATE,
6062                LdapConstants.MATCHING_RULE_ID_TAG, new GrammarAction( "Store matching rule Value" )
6063                {
6064                    public void action( IAsn1Container container ) throws DecoderException
6065                    {
6066                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
6067                        SearchRequestCodec searchRequest = ldapMessageContainer.getSearchRequest();
6068    
6069                        TLV tlv = ldapMessageContainer.getCurrentTLV();
6070    
6071                        // Store the value.
6072                        ExtensibleMatchFilter extensibleMatchFilter = ( ExtensibleMatchFilter ) searchRequest
6073                            .getTerminalFilter();
6074    
6075                        if ( tlv.getLength() == 0 )
6076                        {
6077                            log.error( I18n.err( I18n.ERR_04109 ) );
6078    
6079                            // It will generate a PROTOCOL_ERROR
6080                            throw new DecoderException( I18n.err( I18n.ERR_04109 ) );
6081                        }
6082                        else
6083                        {
6084                            extensibleMatchFilter.setMatchingRule( StringTools.utf8ToString( tlv.getValue().getData() ) );
6085                        }
6086                    }
6087                } );
6088    
6089            // --------------------------------------------------------------------------------------------
6090            // Transition from Extensible Match to type matching rule
6091            // --------------------------------------------------------------------------------------------
6092            // Filter ::= CHOICE {
6093            //     ...
6094            //     extensibleMatch  [9] MatchingRuleAssertion }
6095            //
6096            // MatchingRuleAssertion ::= SEQUENCE {
6097            //     ...
6098            //     type [2] AttributeDescription OPTIONAL,
6099            //     ...
6100            //
6101            // Store the matching rule ID 
6102            super.transitions[LdapStatesEnum.EXTENSIBLE_MATCH_STATE][LdapConstants.MATCHING_RULE_TYPE_TAG] = new GrammarTransition(
6103                LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapStatesEnum.TYPE_MATCHING_RULE_STATE,
6104                LdapConstants.MATCHING_RULE_TYPE_TAG, new StoreTypeMatchingRuleAction() );
6105    
6106            // --------------------------------------------------------------------------------------------
6107            // Transition from Extensible Match to match value
6108            // --------------------------------------------------------------------------------------------
6109            // Filter ::= CHOICE {
6110            //     ...
6111            //     extensibleMatch  [9] MatchingRuleAssertion }
6112            //
6113            // MatchingRuleAssertion ::= SEQUENCE {
6114            //     ...
6115            //     matchValue [3] AssertionValue,
6116            //     ...
6117            //
6118            // Store the matching rule ID 
6119            super.transitions[LdapStatesEnum.EXTENSIBLE_MATCH_STATE][LdapConstants.MATCH_VALUE_TAG] = new GrammarTransition(
6120                LdapStatesEnum.EXTENSIBLE_MATCH_STATE, LdapStatesEnum.MATCH_VALUE_STATE, LdapConstants.MATCH_VALUE_TAG,
6121                new StoreMatchValueAction() );
6122    
6123            // --------------------------------------------------------------------------------------------
6124            // Transition from matching rule to type matching rule
6125            // --------------------------------------------------------------------------------------------
6126            // Filter ::= CHOICE {
6127            //     ...
6128            //     extensibleMatch  [9] MatchingRuleAssertion }
6129            //
6130            // MatchingRuleAssertion ::= SEQUENCE {
6131            //     ...
6132            //     type [2] AttributeDescription OPTIONAL,
6133            //     ...
6134            //
6135            // Store the matching rule ID 
6136            super.transitions[LdapStatesEnum.MATCHING_RULE_STATE][LdapConstants.MATCHING_RULE_TYPE_TAG] = new GrammarTransition(
6137                LdapStatesEnum.MATCHING_RULE_STATE, LdapStatesEnum.TYPE_MATCHING_RULE_STATE,
6138                LdapConstants.MATCHING_RULE_TYPE_TAG, new StoreTypeMatchingRuleAction() );
6139    
6140            // --------------------------------------------------------------------------------------------
6141            // Transition from matching rule to match value
6142            // --------------------------------------------------------------------------------------------
6143            // Filter ::= CHOICE {
6144            //     ...
6145            //     extensibleMatch  [9] MatchingRuleAssertion }
6146            //
6147            // MatchingRuleAssertion ::= SEQUENCE {
6148            //     ...
6149            //     matchValue [3] AssertionValue,
6150            //     ...
6151            //
6152            // Store the matching rule ID 
6153            super.transitions[LdapStatesEnum.MATCHING_RULE_STATE][LdapConstants.MATCH_VALUE_TAG] = new GrammarTransition(
6154                LdapStatesEnum.MATCHING_RULE_STATE, LdapStatesEnum.MATCH_VALUE_STATE, LdapConstants.MATCH_VALUE_TAG,
6155                new StoreMatchValueAction() );
6156    
6157            // --------------------------------------------------------------------------------------------
6158            // Transition from matching type to match value
6159            // --------------------------------------------------------------------------------------------
6160            // Filter ::= CHOICE {
6161            //     ...
6162            //     extensibleMatch  [9] MatchingRuleAssertion }
6163            //
6164            // MatchingRuleAssertion ::= SEQUENCE {
6165            //     ...
6166            //     matchValue [3] AssertionValue,
6167            //     ...
6168            //
6169            // Store the matching rule ID 
6170            super.transitions[LdapStatesEnum.TYPE_MATCHING_RULE_STATE][LdapConstants.MATCH_VALUE_TAG] = new GrammarTransition(
6171                LdapStatesEnum.TYPE_MATCHING_RULE_STATE, LdapStatesEnum.MATCH_VALUE_STATE, LdapConstants.MATCH_VALUE_TAG,
6172                new StoreMatchValueAction() );
6173    
6174            // --------------------------------------------------------------------------------------------
6175            // Transition from match value to dnAttributes
6176            // --------------------------------------------------------------------------------------------
6177            // Filter ::= CHOICE {
6178            //     ...
6179            //     extensibleMatch  [9] MatchingRuleAssertion }
6180            //
6181            // MatchingRuleAssertion ::= SEQUENCE {
6182            //     ...
6183            //     dnAttributes [4] BOOLEAN DEFAULT FALSE }
6184            //
6185            // Store the dnAttributes flag 
6186            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.DN_ATTRIBUTES_FILTER_TAG] = new GrammarTransition(
6187                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.DN_ATTRIBUTES_STATE,
6188                LdapConstants.DN_ATTRIBUTES_FILTER_TAG, new GrammarAction( "Store matching dnAttributes Value" )
6189                {
6190                    public void action( IAsn1Container container ) throws DecoderException
6191                    {
6192                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
6193                        SearchRequestCodec searchRequest = ldapMessageContainer.getSearchRequest();
6194    
6195                        TLV tlv = ldapMessageContainer.getCurrentTLV();
6196    
6197                        // Store the value.
6198                        ExtensibleMatchFilter extensibleMatchFilter = ( ExtensibleMatchFilter ) searchRequest
6199                            .getTerminalFilter();
6200    
6201                        // We get the value. If it's a 0, it's a FALSE. If it's
6202                        // a FF, it's a TRUE. Any other value should be an error,
6203                        // but we could relax this constraint. So if we have
6204                        // something
6205                        // which is not 0, it will be interpreted as TRUE, but we
6206                        // will generate a warning.
6207                        Value value = tlv.getValue();
6208    
6209                        try
6210                        {
6211                            extensibleMatchFilter.setDnAttributes( BooleanDecoder.parse( value ) );
6212                        }
6213                        catch ( BooleanDecoderException bde )
6214                        {
6215                            log.error( I18n.err( I18n.ERR_04110, StringTools.dumpBytes( value.getData() ), bde.getMessage() ) );
6216    
6217                            throw new DecoderException( bde.getMessage() );
6218                        }
6219    
6220                        if ( IS_DEBUG )
6221                        {
6222                            log.debug( "DN Attributes : {}", Boolean.valueOf( extensibleMatchFilter.isDnAttributes() ) );
6223                        }
6224    
6225                        // unstack the filters if needed
6226                        searchRequest.unstackFilters( ldapMessageContainer );
6227                    }
6228                } );
6229    
6230            // --------------------------------------------------------------------------------------------
6231            // Transition from match value to AND filter
6232            // --------------------------------------------------------------------------------------------
6233            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6234            //     ...
6235            //     filter Filter,
6236            //     ...
6237            //
6238            // Filter ::= CHOICE {
6239            //     and             [0] SET OF Filter,
6240            //     ...
6241            //
6242            // Init AND filter
6243            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
6244                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
6245                new InitAndFilterAction() );
6246    
6247            // --------------------------------------------------------------------------------------------
6248            // Transition from match value to OR filter
6249            // --------------------------------------------------------------------------------------------
6250            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6251            //     ...
6252            //     filter Filter,
6253            //     ...
6254            //
6255            // Filter ::= CHOICE {
6256            //     ...
6257            //     or              [1] SET OF Filter,
6258            //     ...
6259            //
6260            // Init OR filter
6261            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
6262                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
6263                new InitOrFilterAction() );
6264    
6265            // --------------------------------------------------------------------------------------------
6266            // Transition from match value to NOT filter
6267            // --------------------------------------------------------------------------------------------
6268            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6269            //     ...
6270            //     filter Filter,
6271            //     ...
6272            //
6273            // Filter ::= CHOICE {
6274            //     ...
6275            //     not             [2] SET OF Filter,
6276            //     ...
6277            //
6278            // Init NOT filter
6279            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
6280                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
6281                new InitNotFilterAction() );
6282    
6283            // --------------------------------------------------------------------------------------------
6284            // Transition from match value to Equality Match filter
6285            // --------------------------------------------------------------------------------------------
6286            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6287            //     ...
6288            //     filter Filter,
6289            //     ...
6290            //
6291            // Filter ::= CHOICE {
6292            //     ...
6293            //     equalityMatch   [3] AttributeValueAssertion,
6294            //     ...
6295            //
6296            // Init NOT filter
6297            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
6298                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE,
6299                LdapConstants.EQUALITY_MATCH_FILTER_TAG, new InitEqualityMatchFilterAction() );
6300    
6301            // --------------------------------------------------------------------------------------------
6302            // Transition from match value to Substrings filter
6303            // --------------------------------------------------------------------------------------------
6304            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6305            //     ...
6306            //     filter Filter,
6307            //     ...
6308            //
6309            // Filter ::= CHOICE {
6310            //     ...
6311            //     substrings     [4] SubstringFilter,
6312            //     ...
6313            //
6314            // Init Substrings filter
6315            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
6316                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE,
6317                LdapConstants.SUBSTRINGS_FILTER_TAG, new InitSubstringsFilterAction() );
6318    
6319            // --------------------------------------------------------------------------------------------
6320            // Transition from match value to GreaterOrEqual filter
6321            // --------------------------------------------------------------------------------------------
6322            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6323            //     ...
6324            //     filter Filter,
6325            //     ...
6326            //
6327            // Filter ::= CHOICE {
6328            //     ...
6329            //     greaterOrEqual  [5] AttributeValueAssertion,
6330            //     ...
6331            //
6332            // Init Greater Or Equal filter
6333            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
6334                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
6335                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
6336    
6337            // --------------------------------------------------------------------------------------------
6338            // Transition from match value to LessOrEqual filter
6339            // --------------------------------------------------------------------------------------------
6340            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6341            //     ...
6342            //     filter Filter,
6343            //     ...
6344            //
6345            // Filter ::= CHOICE {
6346            //     ...
6347            //     LessOrEqual    [6] AttributeValueAssertion,
6348            //     ...
6349            //
6350            // Init Less Or Equal filter
6351            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
6352                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE,
6353                LdapConstants.LESS_OR_EQUAL_FILTER_TAG, new InitLessOrEqualFilterAction() );
6354    
6355            // --------------------------------------------------------------------------------------------
6356            // Transition from match value to Present filter
6357            // --------------------------------------------------------------------------------------------
6358            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6359            //     ...
6360            //     filter Filter,
6361            //     ...
6362            //
6363            // Filter ::= CHOICE {
6364            //     ...
6365            //     present        [7] AttributeDescription,
6366            //     ...
6367            //
6368            // Init present filter
6369            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
6370                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
6371                new InitPresentFilterAction() );
6372    
6373            // --------------------------------------------------------------------------------------------
6374            // Transition from match value to Approx Match filter
6375            // --------------------------------------------------------------------------------------------
6376            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6377            //     ...
6378            //     filter Filter,
6379            //     ...
6380            //
6381            // Filter ::= CHOICE {
6382            //     ...
6383            //     approxMatch     [8] AttributeValueAssertion,
6384            //     ...
6385            //
6386            // Init Approx Match filter
6387            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
6388                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.APPROX_MATCH_STATE, LdapConstants.APPROX_MATCH_FILTER_TAG,
6389                new InitApproxMatchFilterAction() );
6390    
6391            // --------------------------------------------------------------------------------------------
6392            // Transition from match value to Extensible Match filter
6393            // --------------------------------------------------------------------------------------------
6394            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6395            //     ...
6396            //     filter Filter,
6397            //     ...
6398            //
6399            // Filter ::= CHOICE {
6400            //     ...
6401            //     extensibleMatch  [9] MatchingRuleAssertion,
6402            //     ...
6403            //
6404            // Init Assertion Value Filter filter
6405            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
6406                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
6407                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
6408    
6409            // --------------------------------------------------------------------------------------------
6410            // Transition from match value to Attribute Description List
6411            // --------------------------------------------------------------------------------------------
6412            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6413            //     ...
6414            //     filter      Filter,
6415            //     attributes  AttributeDescriptionList }
6416            //
6417            // AttributeDescriptionList ::= SEQUENCE OF
6418            //     AttributeDescription
6419            //
6420            // Init attribute description list
6421            super.transitions[LdapStatesEnum.MATCH_VALUE_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
6422                LdapStatesEnum.MATCH_VALUE_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE,
6423                UniversalTag.SEQUENCE_TAG, new InitAttributeDescListAction() );
6424    
6425            // --------------------------------------------------------------------------------------------
6426            // Transition from dnAttributes to AND filter
6427            // --------------------------------------------------------------------------------------------
6428            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6429            //     ...
6430            //     filter Filter,
6431            //     ...
6432            //
6433            // Filter ::= CHOICE {
6434            //     and             [0] SET OF Filter,
6435            //     ...
6436            //
6437            // Init AND filter
6438            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.AND_FILTER_TAG] = new GrammarTransition(
6439                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.AND_STATE, LdapConstants.AND_FILTER_TAG,
6440                new InitAndFilterAction() );
6441    
6442            // --------------------------------------------------------------------------------------------
6443            // Transition from dnAttributes to OR filter
6444            // --------------------------------------------------------------------------------------------
6445            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6446            //     ...
6447            //     filter Filter,
6448            //     ...
6449            //
6450            // Filter ::= CHOICE {
6451            //     ...
6452            //     or              [1] SET OF Filter,
6453            //     ...
6454            //
6455            // Init OR filter
6456            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.OR_FILTER_TAG] = new GrammarTransition(
6457                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.OR_STATE, LdapConstants.OR_FILTER_TAG,
6458                new InitOrFilterAction() );
6459    
6460            // --------------------------------------------------------------------------------------------
6461            // Transition from dnAttributes to NOT filter
6462            // --------------------------------------------------------------------------------------------
6463            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6464            //     ...
6465            //     filter Filter,
6466            //     ...
6467            //
6468            // Filter ::= CHOICE {
6469            //     ...
6470            //     not             [2] SET OF Filter,
6471            //     ...
6472            //
6473            // Init NOT filter
6474            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.NOT_FILTER_TAG] = new GrammarTransition(
6475                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.NOT_STATE, LdapConstants.NOT_FILTER_TAG,
6476                new InitNotFilterAction() );
6477    
6478            // --------------------------------------------------------------------------------------------
6479            // Transition from dnAttributes to Equality Match filter
6480            // --------------------------------------------------------------------------------------------
6481            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6482            //     ...
6483            //     filter Filter,
6484            //     ...
6485            //
6486            // Filter ::= CHOICE {
6487            //     ...
6488            //     equalityMatch   [3] AttributeValueAssertion,
6489            //     ...
6490            //
6491            // Init NOT filter
6492            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.EQUALITY_MATCH_FILTER_TAG] = new GrammarTransition(
6493                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.EQUALITY_MATCH_STATE,
6494                LdapConstants.EQUALITY_MATCH_FILTER_TAG, new InitEqualityMatchFilterAction() );
6495    
6496            // --------------------------------------------------------------------------------------------
6497            // Transition from dnAttributes to Substrings filter
6498            // --------------------------------------------------------------------------------------------
6499            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6500            //     ...
6501            //     filter Filter,
6502            //     ...
6503            //
6504            // Filter ::= CHOICE {
6505            //     ...
6506            //     substrings     [4] SubstringFilter,
6507            //     ...
6508            //
6509            // Init Substrings filter
6510            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.SUBSTRINGS_FILTER_TAG] = new GrammarTransition(
6511                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.SUBSTRING_FILTER_STATE,
6512                LdapConstants.SUBSTRINGS_FILTER_TAG, new InitSubstringsFilterAction() );
6513    
6514            // --------------------------------------------------------------------------------------------
6515            // Transition from dnAttributes to GreaterOrEqual filter
6516            // --------------------------------------------------------------------------------------------
6517            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6518            //     ...
6519            //     filter Filter,
6520            //     ...
6521            //
6522            // Filter ::= CHOICE {
6523            //     ...
6524            //     greaterOrEqual  [5] AttributeValueAssertion,
6525            //     ...
6526            //
6527            // Init Greater Or Equal filter
6528            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.GREATER_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
6529                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.GREATER_OR_EQUAL_STATE,
6530                LdapConstants.GREATER_OR_EQUAL_FILTER_TAG, new InitGreaterOrEqualFilterAction() );
6531    
6532            // --------------------------------------------------------------------------------------------
6533            // Transition from dnAttributes to LessOrEqual filter
6534            // --------------------------------------------------------------------------------------------
6535            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6536            //     ...
6537            //     filter Filter,
6538            //     ...
6539            //
6540            // Filter ::= CHOICE {
6541            //     ...
6542            //     LessOrEqual    [6] AttributeValueAssertion,
6543            //     ...
6544            //
6545            // Init Less Or Equal filter
6546            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.LESS_OR_EQUAL_FILTER_TAG] = new GrammarTransition(
6547                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.LESS_OR_EQUAL_STATE,
6548                LdapConstants.LESS_OR_EQUAL_FILTER_TAG, new InitLessOrEqualFilterAction() );
6549    
6550            // --------------------------------------------------------------------------------------------
6551            // Transition from dnAttributes to Present filter
6552            // --------------------------------------------------------------------------------------------
6553            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6554            //     ...
6555            //     filter Filter,
6556            //     ...
6557            //
6558            // Filter ::= CHOICE {
6559            //     ...
6560            //     present        [7] AttributeDescription,
6561            //     ...
6562            //
6563            // Init present filter
6564            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.PRESENT_FILTER_TAG] = new GrammarTransition(
6565                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.PRESENT_STATE, LdapConstants.PRESENT_FILTER_TAG,
6566                new InitPresentFilterAction() );
6567    
6568            // --------------------------------------------------------------------------------------------
6569            // Transition from dnAttributes to Approx Match filter
6570            // --------------------------------------------------------------------------------------------
6571            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6572            //     ...
6573            //     filter Filter,
6574            //     ...
6575            //
6576            // Filter ::= CHOICE {
6577            //     ...
6578            //     approxMatch     [8] AttributeValueAssertion,
6579            //     ...
6580            //
6581            // Init Approx Match filter
6582            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.APPROX_MATCH_FILTER_TAG] = new GrammarTransition(
6583                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.APPROX_MATCH_STATE,
6584                LdapConstants.APPROX_MATCH_FILTER_TAG, new InitApproxMatchFilterAction() );
6585    
6586            // --------------------------------------------------------------------------------------------
6587            // Transition from dnAttributes to Extensible Match filter
6588            // --------------------------------------------------------------------------------------------
6589            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6590            //     ...
6591            //     filter Filter,
6592            //     ...
6593            //
6594            // Filter ::= CHOICE {
6595            //     ...
6596            //     extensibleMatch  [9] MatchingRuleAssertion,
6597            //     ...
6598            //
6599            // Init Assertion Value Filter filter
6600            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG] = new GrammarTransition(
6601                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.EXTENSIBLE_MATCH_STATE,
6602                LdapConstants.EXTENSIBLE_MATCH_FILTER_TAG, new InitExtensibleMatchFilterAction() );
6603    
6604            // --------------------------------------------------------------------------------------------
6605            // Transition from dnAttributes to Attribute Description List
6606            // --------------------------------------------------------------------------------------------
6607            // SearchRequest ::= [APPLICATION 3] SEQUENCE {
6608            //     ...
6609            //     filter      Filter,
6610            //     attributes  AttributeDescriptionList }
6611            //
6612            // AttributeDescriptionList ::= SEQUENCE OF
6613            //     AttributeDescription
6614            //
6615            // Init attribute description list
6616            super.transitions[LdapStatesEnum.DN_ATTRIBUTES_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
6617                LdapStatesEnum.DN_ATTRIBUTES_STATE, LdapStatesEnum.ATTRIBUTE_DESCRIPTION_LIST_STATE,
6618                UniversalTag.SEQUENCE_TAG, new InitAttributeDescListAction() );
6619        }
6620    
6621    
6622        // ~ Methods
6623        // ------------------------------------------------------------------------------------
6624    
6625        /**
6626         * Get the instance of this grammar
6627         * 
6628         * @return An instance on the LdapMessage Grammar
6629         */
6630        public static IGrammar getInstance()
6631        {
6632            return instance;
6633        }
6634    }