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 */
020package org.apache.directory.api.dsmlv2.reponse;
021
022
023import java.io.IOException;
024import java.lang.reflect.Array;
025import java.util.HashMap;
026import java.util.HashSet;
027import java.util.Set;
028
029import org.apache.directory.api.asn1.DecoderException;
030import org.apache.directory.api.asn1.util.Oid;
031import org.apache.directory.api.dsmlv2.AbstractDsmlMessageDecorator;
032import org.apache.directory.api.dsmlv2.AbstractGrammar;
033import org.apache.directory.api.dsmlv2.DsmlControl;
034import org.apache.directory.api.dsmlv2.DsmlDecorator;
035import org.apache.directory.api.dsmlv2.Dsmlv2Container;
036import org.apache.directory.api.dsmlv2.Dsmlv2StatesEnum;
037import org.apache.directory.api.dsmlv2.Grammar;
038import org.apache.directory.api.dsmlv2.GrammarAction;
039import org.apache.directory.api.dsmlv2.GrammarTransition;
040import org.apache.directory.api.dsmlv2.ParserUtils;
041import org.apache.directory.api.dsmlv2.Tag;
042import org.apache.directory.api.dsmlv2.reponse.ErrorResponse.ErrorResponseType;
043import org.apache.directory.api.i18n.I18n;
044import org.apache.directory.api.ldap.codec.api.CodecControl;
045import org.apache.directory.api.ldap.model.exception.LdapException;
046import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
047import org.apache.directory.api.ldap.model.exception.LdapURLEncodingException;
048import org.apache.directory.api.ldap.model.message.AddResponseImpl;
049import org.apache.directory.api.ldap.model.message.BindResponseImpl;
050import org.apache.directory.api.ldap.model.message.CompareResponseImpl;
051import org.apache.directory.api.ldap.model.message.Control;
052import org.apache.directory.api.ldap.model.message.DeleteResponseImpl;
053import org.apache.directory.api.ldap.model.message.ExtendedResponse;
054import org.apache.directory.api.ldap.model.message.ExtendedResponseImpl;
055import org.apache.directory.api.ldap.model.message.LdapResult;
056import org.apache.directory.api.ldap.model.message.Message;
057import org.apache.directory.api.ldap.model.message.ModifyDnResponseImpl;
058import org.apache.directory.api.ldap.model.message.ModifyResponseImpl;
059import org.apache.directory.api.ldap.model.message.ReferralImpl;
060import org.apache.directory.api.ldap.model.message.Response;
061import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
062import org.apache.directory.api.ldap.model.message.ResultResponse;
063import org.apache.directory.api.ldap.model.message.SearchResultDoneImpl;
064import org.apache.directory.api.ldap.model.message.SearchResultEntryImpl;
065import org.apache.directory.api.ldap.model.message.SearchResultReference;
066import org.apache.directory.api.ldap.model.message.SearchResultReferenceImpl;
067import org.apache.directory.api.ldap.model.message.controls.OpaqueControl;
068import org.apache.directory.api.ldap.model.name.Dn;
069import org.apache.directory.api.ldap.model.url.LdapUrl;
070import org.apache.directory.api.util.Base64;
071import org.apache.directory.api.util.Strings;
072import org.xmlpull.v1.XmlPullParser;
073import org.xmlpull.v1.XmlPullParserException;
074
075/**
076 * This Class represents the DSMLv2 Response Grammar
077 * 
078 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
079 */
080public final class Dsmlv2ResponseGrammar extends AbstractGrammar implements Grammar
081{
082    /** The instance of grammar. Dsmlv2ResponseGrammar is a singleton */
083    private static Dsmlv2ResponseGrammar instance = new Dsmlv2ResponseGrammar();
084
085    /** The DSMLv2 description tags */
086    private static final Set<String> DSMLV2_DESCR_TAGS;
087    static
088    {
089        DSMLV2_DESCR_TAGS = new HashSet<String>();
090        DSMLV2_DESCR_TAGS.add( "success" );
091        DSMLV2_DESCR_TAGS.add( "operationsError" );
092        DSMLV2_DESCR_TAGS.add( "protocolError" );
093        DSMLV2_DESCR_TAGS.add( "timeLimitExceeded" );
094        DSMLV2_DESCR_TAGS.add( "sizeLimitExceeded" );
095        DSMLV2_DESCR_TAGS.add( "compareFalse" );
096        DSMLV2_DESCR_TAGS.add( "compareTrue" );
097        DSMLV2_DESCR_TAGS.add( "authMethodNotSupported" );
098        DSMLV2_DESCR_TAGS.add( "strongAuthRequired" );
099        DSMLV2_DESCR_TAGS.add( "referral" );
100        DSMLV2_DESCR_TAGS.add( "adminLimitExceeded" );
101        DSMLV2_DESCR_TAGS.add( "unavailableCriticalExtension" );
102        DSMLV2_DESCR_TAGS.add( "confidentialityRequired" );
103        DSMLV2_DESCR_TAGS.add( "saslBindInProgress" );
104        DSMLV2_DESCR_TAGS.add( "noSuchAttribute" );
105        DSMLV2_DESCR_TAGS.add( "undefinedAttributeType" );
106        DSMLV2_DESCR_TAGS.add( "inappropriateMatching" );
107        DSMLV2_DESCR_TAGS.add( "constraintViolation" );
108        DSMLV2_DESCR_TAGS.add( "attributeOrValueExists" );
109        DSMLV2_DESCR_TAGS.add( "invalidAttributeSyntax" );
110        DSMLV2_DESCR_TAGS.add( "noSuchObject" );
111        DSMLV2_DESCR_TAGS.add( "aliasProblem" );
112        DSMLV2_DESCR_TAGS.add( "invalidDNSyntax" );
113        DSMLV2_DESCR_TAGS.add( "aliasDereferencingProblem" );
114        DSMLV2_DESCR_TAGS.add( "inappropriateAuthentication" );
115        DSMLV2_DESCR_TAGS.add( "invalidCredentials" );
116        DSMLV2_DESCR_TAGS.add( "insufficientAccessRights" );
117        DSMLV2_DESCR_TAGS.add( "busy" );
118        DSMLV2_DESCR_TAGS.add( "unavailable" );
119        DSMLV2_DESCR_TAGS.add( "unwillingToPerform" );
120        DSMLV2_DESCR_TAGS.add( "loopDetect" );
121        DSMLV2_DESCR_TAGS.add( "namingViolation" );
122        DSMLV2_DESCR_TAGS.add( "objectClassViolation" );
123        DSMLV2_DESCR_TAGS.add( "notAllowedOnNonLeaf" );
124        DSMLV2_DESCR_TAGS.add( "notAllowedOnRDN" );
125        DSMLV2_DESCR_TAGS.add( "entryAlreadyExists" );
126        DSMLV2_DESCR_TAGS.add( "objectClassModsProhibited" );
127        DSMLV2_DESCR_TAGS.add( "affectMultipleDSAs" );
128        DSMLV2_DESCR_TAGS.add( "other" );
129    }
130
131
132    @SuppressWarnings("unchecked")
133    private Dsmlv2ResponseGrammar()
134    {
135        name = Dsmlv2ResponseGrammar.class.getName();
136
137        // Create the transitions table
138        super.transitions = ( HashMap<Tag, GrammarTransition>[] ) Array.newInstance( HashMap.class, 300 ); // TODO Change this value
139
140        //====================================================
141        //  Transitions concerning : BATCH RESPONSE
142        //====================================================
143        super.transitions[Dsmlv2StatesEnum.INIT_GRAMMAR_STATE.ordinal()] = new HashMap<Tag, GrammarTransition>();
144
145        // ** OPEN BATCH Reponse **
146        // State: [INIT_GRAMMAR_STATE] - Tag: <batchResponse>
147        super.transitions[Dsmlv2StatesEnum.INIT_GRAMMAR_STATE.ordinal()].put( new Tag( "batchResponse", Tag.START ),
148            new GrammarTransition( Dsmlv2StatesEnum.INIT_GRAMMAR_STATE, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
149                batchResponseCreation ) );
150
151        //====================================================
152        //  Transitions concerning : BATCH RESPONSE LOOP
153        //====================================================
154        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()] = new HashMap<Tag, GrammarTransition>();
155
156        // State: [BATCH_RESPONSE_LOOP] - Tag: <addResponse>
157        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "addResponse", Tag.START ),
158            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
159                addResponseCreation ) );
160
161        // State: [BATCH_RESPONSE_LOOP] - Tag: <authResponse>
162        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "authResponse", Tag.START ),
163            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
164                authResponseCreation ) );
165
166        // State: [BATCH_RESPONSE_LOOP] - Tag: <compareResponse>
167        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "compareResponse", Tag.START ),
168            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
169                compareResponseCreation ) );
170
171        // State: [BATCH_RESPONSE_LOOP] - Tag: <delResponse>
172        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "delResponse", Tag.START ),
173            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
174                delResponseCreation ) );
175
176        // State: [BATCH_RESPONSE_LOOP] - Tag: <modifyResponse>
177        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "modifyResponse", Tag.START ),
178            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
179                modifyResponseCreation ) );
180
181        // State: [BATCH_RESPONSE_LOOP] - Tag: <modDNResponse>
182        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "modDNResponse", Tag.START ),
183            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
184                modDNResponseCreation ) );
185
186        // State: [BATCH_RESPONSE_LOOP] - Tag: <extendedResponse>
187        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put(
188            new Tag( "extendedResponse", Tag.START ),
189            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.EXTENDED_RESPONSE,
190                extendedResponseCreation ) );
191
192        // State: [BATCH_RESPONSE_LOOP] - Tag: <errorResponse>
193        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "errorResponse", Tag.START ),
194            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.ERROR_RESPONSE,
195                errorResponseCreation ) );
196
197        // State: [BATCH_RESPONSE_LOOP] - Tag: <searchReponse>
198        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "searchResponse", Tag.START ),
199            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.SEARCH_RESPONSE,
200                searchResponseCreation ) );
201
202        // State: [BATCH_RESPONSE_LOOP] - Tag: </batchResponse>
203        super.transitions[Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP.ordinal()].put( new Tag( "batchResponse", Tag.END ),
204            new GrammarTransition( Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, Dsmlv2StatesEnum.GRAMMAR_END, null ) );
205
206        //====================================================
207        //  Transitions concerning : ERROR RESPONSE
208        //====================================================
209        super.transitions[Dsmlv2StatesEnum.ERROR_RESPONSE.ordinal()] = new HashMap<Tag, GrammarTransition>();
210        super.transitions[Dsmlv2StatesEnum.MESSAGE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
211        super.transitions[Dsmlv2StatesEnum.DETAIL_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
212        super.transitions[Dsmlv2StatesEnum.DETAIL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
213
214        // State: [ERROR_RESPONSE] - Tag: <message>
215        super.transitions[Dsmlv2StatesEnum.ERROR_RESPONSE.ordinal()].put( new Tag( "message", Tag.START ),
216            new GrammarTransition(
217                Dsmlv2StatesEnum.ERROR_RESPONSE, Dsmlv2StatesEnum.MESSAGE_END, errorResponseAddMessage ) );
218
219        // State: [ERROR_RESPONSE] - Tag: <detail>
220        super.transitions[Dsmlv2StatesEnum.ERROR_RESPONSE.ordinal()].put( new Tag( "detail", Tag.START ),
221            new GrammarTransition(
222                Dsmlv2StatesEnum.ERROR_RESPONSE, Dsmlv2StatesEnum.DETAIL_START, errorResponseAddDetail ) );
223
224        // State: [MESSAGE_END] - Tag: </errorResponse>
225        super.transitions[Dsmlv2StatesEnum.MESSAGE_END.ordinal()].put( new Tag( "errorResponse", Tag.END ),
226            new GrammarTransition( Dsmlv2StatesEnum.MESSAGE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
227
228        // State: [MESSAGE_END] - Tag: <detail>
229        super.transitions[Dsmlv2StatesEnum.MESSAGE_END.ordinal()].put( new Tag( "detail", Tag.START ),
230            new GrammarTransition(
231                Dsmlv2StatesEnum.MESSAGE_END, Dsmlv2StatesEnum.DETAIL_START, errorResponseAddDetail ) );
232
233        // State: [DETAIL_START] - Tag: </detail>
234        super.transitions[Dsmlv2StatesEnum.DETAIL_START.ordinal()].put( new Tag( "detail", Tag.END ),
235            new GrammarTransition(
236                Dsmlv2StatesEnum.DETAIL_START, Dsmlv2StatesEnum.DETAIL_END, null ) );
237
238        // State: [DETAIL_END] - Tag: <detail>
239        super.transitions[Dsmlv2StatesEnum.DETAIL_END.ordinal()].put( new Tag( "detail", Tag.END ),
240            new GrammarTransition(
241                Dsmlv2StatesEnum.DETAIL_END, Dsmlv2StatesEnum.DETAIL_END, errorResponseAddDetail ) );
242
243        // State: [ERROR_RESPONSE] - Tag: </errorResponse>
244        super.transitions[Dsmlv2StatesEnum.ERROR_RESPONSE.ordinal()].put( new Tag( "errorResponse", Tag.END ),
245            new GrammarTransition( Dsmlv2StatesEnum.ERROR_RESPONSE, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
246
247        //====================================================
248        //  Transitions concerning : EXTENDED RESPONSE
249        //====================================================
250        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE.ordinal()] = new HashMap<Tag, GrammarTransition>();
251        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
252        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
253        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_VALUE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
254        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
255        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
256        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
257        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
258        super.transitions[Dsmlv2StatesEnum.RESPONSE_NAME_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
259        super.transitions[Dsmlv2StatesEnum.RESPONSE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
260
261        // State: [EXTENDED_RESPONSE] - Tag: <control>
262        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE.ordinal()].put( new Tag( "control", Tag.START ),
263            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE,
264                Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START, ldapResultControlCreation ) );
265
266        // State: [EXTENDED_RESPONSE_CONTROL_START] - Tag: <controlValue>
267        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START.ordinal()].put( new Tag( "controlValue",
268            Tag.START ),
269            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START,
270                Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_VALUE_END, ldapResultControlValueCreation ) );
271
272        // State: [EXTENDED_RESPONSE_CONTROL_VALUE_END] - Tag: </control>
273        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_VALUE_END.ordinal()].put( new Tag( "control",
274            Tag.END ),
275            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_VALUE_END,
276                Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END, null ) );
277
278        // State: [EXTENDED_RESPONSE_CONTROL_START] - Tag: </control>
279        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START.ordinal()].put(
280            new Tag( "control", Tag.END ),
281            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START,
282                Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END, null ) );
283
284        // State: [EXTENDED_RESPONSE_CONTROL_END] - Tag: <control>
285        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END.ordinal()].put(
286            new Tag( "control", Tag.START ),
287            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END,
288                Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_START, ldapResultControlCreation ) );
289
290        // State: [EXTENDED_RESPONSE_CONTROL_END] - Tag: <resultCode>
291        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END.ordinal()].put( new Tag( "resultCode",
292            Tag.START ),
293            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_CONTROL_END,
294                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_START, extendedResponseAddResultCode ) );
295
296        // State: [EXTENDED_RESPONSE] - Tag: <resultCode>
297        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE.ordinal()].put( new Tag( "resultCode", Tag.START ),
298            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE,
299                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_START, extendedResponseAddResultCode ) );
300
301        // State: [EXTENDED_RESPONSE_RESULT_CODE_START] - Tag: </resultCode>
302        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_START.ordinal()].put( new Tag( "resultCode",
303            Tag.END ),
304            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_START,
305                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END, null ) );
306
307        // State: [EXTENDED_RESPONSE_RESULT_CODE_END] - Tag: <errorMessage>
308        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()].put(
309            new Tag( "errorMessage", Tag.START ), new GrammarTransition(
310                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END,
311                Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END, extendedResponseAddErrorMessage ) );
312
313        // State: [EXTENDED_RESPONSE_RESULT_CODE_END] - Tag: <referral>
314        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()].put( new Tag( "referral",
315            Tag.START ),
316            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END,
317                Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END, extendedResponseAddReferral ) );
318
319        // State: [EXTENDED_RESPONSE_RESULT_CODE_END] - Tag: <responseName>
320        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()].put(
321            new Tag( "responseName", Tag.START ), new GrammarTransition(
322                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END, Dsmlv2StatesEnum.RESPONSE_NAME_END,
323                extendedResponseAddResponseName ) );
324
325        // State: [EXTENDED_RESPONSE_RESULT_CODE_END] - Tag: <response>
326        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()].put( new Tag( "response",
327            Tag.START ),
328            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END, Dsmlv2StatesEnum.RESPONSE_END,
329                extendedResponseAddResponse ) );
330
331        // State: [EXTENDED_RESPONSE_RESULT_CODE_END] - Tag: </extendedResponse>
332        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END.ordinal()].put(
333            new Tag( "extendedResponse", Tag.END ), new GrammarTransition(
334                Dsmlv2StatesEnum.EXTENDED_RESPONSE_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
335
336        // State: [EXTENDED_RESPONSE_ERROR_MESSAGE_END] - Tag: <referral>
337        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END.ordinal()].put( new Tag( "referral",
338            Tag.START ),
339            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END,
340                Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END, extendedResponseAddReferral ) );
341
342        // State: [EXTENDED_RESPONSE_ERROR_MESSAGE_END] - Tag: <responseName>
343        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END.ordinal()].put(
344            new Tag( "responseName", Tag.START ), new GrammarTransition(
345                Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END, Dsmlv2StatesEnum.RESPONSE_NAME_END,
346                extendedResponseAddResponseName ) );
347
348        // State: [EXTENDED_RESPONSE_ERROR_MESSAGE_END] - Tag: <response>
349        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END.ordinal()].put( new Tag( "response",
350            Tag.START ),
351            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END, Dsmlv2StatesEnum.RESPONSE_END,
352                extendedResponseAddResponse ) );
353
354        // State: [EXTENDED_RESPONSE_ERROR_MESSAGE_END] - Tag: </extendedResponse>
355        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END.ordinal()].put( new Tag(
356            "extendedResponse",
357            Tag.END ), new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_ERROR_MESSAGE_END,
358            Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
359
360        // State: [EXTENDED_RESPONSE_REFERRAL_END] - Tag: <referral>
361        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END.ordinal()].put( new Tag( "referral",
362            Tag.START ),
363            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END,
364                Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END, extendedResponseAddReferral ) );
365
366        // State: [EXTENDED_RESPONSE_REFERRAL_END] - Tag: <responseName>
367        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END.ordinal()].put( new Tag( "responseName",
368            Tag.START ),
369            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END, Dsmlv2StatesEnum.RESPONSE_NAME_END,
370                extendedResponseAddResponseName ) );
371
372        // State: [EXTENDED_RESPONSE_REFERRAL_END] - Tag: <reponse>
373        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END.ordinal()].put(
374            new Tag( "reponse", Tag.START ),
375            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END, Dsmlv2StatesEnum.RESPONSE_END,
376                extendedResponseAddResponse ) );
377
378        // State: [EXTENDED_RESPONSE_REFERRAL_END] - Tag: </extendedResponse>
379        super.transitions[Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END.ordinal()].put( new Tag( "extendedResponse",
380            Tag.END ),
381            new GrammarTransition( Dsmlv2StatesEnum.EXTENDED_RESPONSE_REFERRAL_END,
382                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
383
384        // State: [RESPONSE_NAME_END] - Tag: <response>
385        super.transitions[Dsmlv2StatesEnum.RESPONSE_NAME_END.ordinal()].put( new Tag( "response", Tag.START ),
386            new GrammarTransition( Dsmlv2StatesEnum.RESPONSE_NAME_END, Dsmlv2StatesEnum.RESPONSE_END,
387                extendedResponseAddResponse ) );
388
389        // State: [RESPONSE_NAME_END] - Tag: </extendedResponse>
390        super.transitions[Dsmlv2StatesEnum.RESPONSE_NAME_END.ordinal()].put( new Tag( "extendedResponse", Tag.END ),
391            new GrammarTransition( Dsmlv2StatesEnum.RESPONSE_NAME_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
392
393        // State: [RESPONSE_END] - Tag: </extendedResponse>
394        super.transitions[Dsmlv2StatesEnum.RESPONSE_END.ordinal()].put( new Tag( "extendedResponse", Tag.END ),
395            new GrammarTransition( Dsmlv2StatesEnum.RESPONSE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
396
397        //====================================================
398        //  Transitions concerning : LDAP RESULT
399        //====================================================
400        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT.ordinal()] = new HashMap<Tag, GrammarTransition>();
401        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
402        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
403        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_VALUE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
404        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
405        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
406        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
407        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
408        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
409
410        // State: [LDAP_RESULT] - Tag: <control>
411        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT.ordinal()].put( new Tag( "control", Tag.START ),
412            new GrammarTransition(
413                Dsmlv2StatesEnum.LDAP_RESULT, Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START, ldapResultControlCreation ) );
414
415        // State: [LDAP_RESULT] - Tag: <resultCode>
416        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT.ordinal()]
417            .put( new Tag( "resultCode", Tag.START ), new GrammarTransition(
418                Dsmlv2StatesEnum.LDAP_RESULT, Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_START, ldapResultAddResultCode ) );
419
420        // State: [LDAP_RESULT_CONTROL_START] - Tag: <controlValue>
421        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START.ordinal()].put(
422            new Tag( "controlValue", Tag.START ),
423            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START,
424                Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_VALUE_END, ldapResultControlValueCreation ) );
425
426        // State: [LDAP_RESULT_CONTROL_VALUE_END] - Tag: </control>
427        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_VALUE_END.ordinal()].put( new Tag( "control", Tag.END ),
428            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_VALUE_END,
429                Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END, null ) );
430
431        // State: [LDAP_RESULT_CONTROL_START] - Tag: </control>
432        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START.ordinal()].put( new Tag( "control", Tag.END ),
433            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START,
434                Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END, null ) );
435
436        // State: [LDAP_RESULT_CONTROL_END] - Tag: <control>
437        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END.ordinal()].put( new Tag( "control", Tag.START ),
438            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END,
439                Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_START, ldapResultControlCreation ) );
440
441        // State: [LDAP_RESULT_CONTROL_END] - Tag: <resultCode>
442        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END.ordinal()].put( new Tag( "resultCode", Tag.START ),
443            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_CONTROL_END,
444                Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_START, ldapResultAddResultCode ) );
445
446        // State: [LDAP_RESULT_RESULT_CODE_START] - Tag: </resultCode>
447        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_START.ordinal()].put(
448            new Tag( "resultCode", Tag.END ),
449            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_START,
450                Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, null ) );
451
452        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: <errorMessage>
453        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put( new Tag( "errorMessage",
454            Tag.START ),
455            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END,
456                Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END, ldapResultAddErrorMessage ) );
457
458        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: <referral>
459        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put(
460            new Tag( "referral", Tag.START ),
461            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END,
462                Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, ldapResultAddReferral ) );
463
464        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </addResponse>
465        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put(
466            new Tag( "addResponse", Tag.END ),
467            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
468                null ) );
469
470        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </authResponse>
471        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put(
472            new Tag( "authResponse", Tag.END ),
473            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
474                null ) );
475
476        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </compareResponse>
477        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put( new Tag( "compareResponse",
478            Tag.END ),
479            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
480                null ) );
481
482        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </delResponse>
483        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put(
484            new Tag( "delResponse", Tag.END ),
485            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
486                null ) );
487
488        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </modifyResponse>
489        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put( new Tag( "modifyResponse",
490            Tag.END ),
491            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
492                null ) );
493
494        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </modDNResponse>
495        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put( new Tag( "modDNResponse",
496            Tag.END ),
497            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
498                null ) );
499
500        // State: [LDAP_RESULT_RESULT_CODE_END] - Tag: </searchResultDone>
501        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END.ordinal()].put( new Tag( "searchResultDone",
502            Tag.END ),
503            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_RESULT_CODE_END,
504                Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END, null ) );
505
506        // State: [SEARCH_RESULT_DONE_END] - Tag: </searchResponse>
507        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END.ordinal()]
508            .put( new Tag( "searchResponse", Tag.END ), new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END,
509                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
510
511        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: <referral>
512        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put(
513            new Tag( "referral", Tag.START ),
514            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
515                Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, ldapResultAddReferral ) );
516
517        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </addResponse>
518        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "addResponse",
519            Tag.END ),
520            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
521                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
522
523        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </authResponse>
524        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "authResponse",
525            Tag.END ),
526            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
527                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
528
529        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </compareResponse>
530        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "compareResponse",
531            Tag.END ),
532            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
533                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
534
535        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </delResponse>
536        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "delResponse",
537            Tag.END ),
538            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
539                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
540
541        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </modifyResponse>
542        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "modifyResponse",
543            Tag.END ),
544            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
545                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
546
547        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </modDNResponse>
548        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "modDNResponse",
549            Tag.END ),
550            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
551                Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP, null ) );
552
553        // State: [LDAP_RESULT_ERROR_MESSAGE_END] - Tag: </searchResultDone>
554        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END.ordinal()].put( new Tag( "searchResultDone",
555            Tag.END ),
556            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_ERROR_MESSAGE_END,
557                Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END, null ) );
558
559        // State: [LDAP_RESULT_REFERRAL_END] - Tag: <referral>
560        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put( new Tag( "referral", Tag.START ),
561            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END,
562                Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, ldapResultAddReferral ) );
563
564        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </addResponse>
565        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put( new Tag( "addResponse", Tag.END ),
566            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
567                null ) );
568
569        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </authResponse>
570        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put( new Tag( "authResponse", Tag.END ),
571            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
572                null ) );
573
574        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </compareResponse>
575        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put(
576            new Tag( "compareResponse", Tag.END ),
577            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
578                null ) );
579
580        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </delResponse>
581        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put( new Tag( "delResponse", Tag.END ),
582            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
583                null ) );
584
585        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </modifyResponse>
586        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put(
587            new Tag( "modifyResponse", Tag.END ),
588            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
589                null ) );
590
591        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </modDNResponse>
592        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put(
593            new Tag( "modDNResponse", Tag.END ),
594            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
595                null ) );
596
597        // State: [LDAP_RESULT_REFERRAL_END] - Tag: </searchResultDone>
598        super.transitions[Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END.ordinal()].put( new Tag( "searchResultDone",
599            Tag.END ),
600            new GrammarTransition( Dsmlv2StatesEnum.LDAP_RESULT_REFERRAL_END, Dsmlv2StatesEnum.SEARCH_RESULT_DONE_END,
601                null ) );
602
603        //====================================================
604        //  Transitions concerning : SEARCH RESPONSE
605        //====================================================
606        super.transitions[Dsmlv2StatesEnum.SEARCH_RESPONSE.ordinal()] = new HashMap<Tag, GrammarTransition>();
607
608        // State: [SEARCH_REPONSE] - Tag: <searchResultEntry>
609        super.transitions[Dsmlv2StatesEnum.SEARCH_RESPONSE.ordinal()].put( new Tag( "searchResultEntry", Tag.START ),
610            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESPONSE, Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY,
611                searchResultEntryCreation ) );
612
613        // State: [SEARCH_REPONSE] - Tag: <searchResultReference>
614        super.transitions[Dsmlv2StatesEnum.SEARCH_RESPONSE.ordinal()].put(
615            new Tag( "searchResultReference", Tag.START ),
616            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESPONSE, Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE,
617                searchResultReferenceCreation ) );
618
619        // State: [SEARCH_REPONSE] - Tag: <searchResultDone>
620        super.transitions[Dsmlv2StatesEnum.SEARCH_RESPONSE.ordinal()].put( new Tag( "searchResultDone", Tag.START ),
621            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESPONSE, Dsmlv2StatesEnum.LDAP_RESULT,
622                searchResultDoneCreation ) );
623
624        //====================================================
625        //  Transitions concerning : SEARCH RESULT ENTRY
626        //====================================================
627        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY.ordinal()] = new HashMap<Tag, GrammarTransition>();
628        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
629        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
630        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_VALUE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
631        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
632        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
633        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
634
635        // State: [SEARCH_RESULT_ENTRY] - Tag: <control>
636        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY.ordinal()].put( new Tag( "control", Tag.START ),
637            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY,
638                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START, searchResultEntryControlCreation ) );
639
640        // State: [SEARCH_RESULT_ENTRY] - Tag: <attr>
641        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY.ordinal()].put( new Tag( "attr", Tag.START ),
642            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY,
643                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START, searchResultEntryAddAttr ) );
644
645        // State: [SEARCH_RESULT_ENTRY] - Tag: </searchResultEntry>
646        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY.ordinal()].put( new Tag( "searchResultEntry", Tag.END ),
647            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY, Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP,
648                null ) );
649
650        // State: [SEARCH_RESULT_ENTRY_CONTROL_START] - Tag: <controlValue>
651        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START.ordinal()].put(
652            new Tag( "controlValue", Tag.START ), new GrammarTransition(
653                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START,
654                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_VALUE_END, searchResultEntryControlValueCreation ) );
655
656        // State: [SEARCH_RESULT_ENTRY_CONTROL_VALUE_END] - Tag: </control>
657        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_VALUE_END.ordinal()].put( new Tag( "control",
658            Tag.END ),
659            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_VALUE_END,
660                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END, null ) );
661
662        // State: [SEARCH_RESULT_ENTRY_CONTROL_START] - Tag: </control>
663        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START.ordinal()].put( new Tag( "control",
664            Tag.END ),
665            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START,
666                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END, null ) );
667
668        // State: [SEARCH_RESULT_ENTRY_CONTROL_END] - Tag: <control>
669        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END.ordinal()].put( new Tag( "control",
670            Tag.START ),
671            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END,
672                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_START, searchResultEntryControlCreation ) );
673
674        // State: [SEARCH_RESULT_ENTRY_CONTROL_END] - Tag: </searchResultEntry>
675        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END.ordinal()].put(
676            new Tag( "searchResultEntry", Tag.END ), new GrammarTransition(
677                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END, Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP, null ) );
678
679        // State: [SEARCH_RESULT_ENTRY_CONTROL_END] - Tag: <attr>
680        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END.ordinal()].put(
681            new Tag( "attr", Tag.START ),
682            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_CONTROL_END,
683                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START, null ) );
684
685        // State: [SEARCH_RESULT_ENTRY_ATTR_START] - Tag: </attr>
686        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START.ordinal()].put( new Tag( "attr", Tag.END ),
687            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START,
688                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END, null ) );
689
690        // State: [SEARCH_RESULT_ENTRY_ATTR_START] - Tag: <value>
691        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START.ordinal()].put(
692            new Tag( "value", Tag.START ),
693            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START,
694                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END, searchResultEntryAddValue ) );
695
696        // State: [SEARCH_RESULT_ENTRY_ATTR_END] - Tag: <attr>
697        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END.ordinal()].put( new Tag( "attr", Tag.START ),
698            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END,
699                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_START, searchResultEntryAddAttr ) );
700
701        // State: [SEARCH_RESULT_ENTRY_ATTR_END] - Tag: </searchResultEntry>
702        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END.ordinal()].put( new Tag( "searchResultEntry",
703            Tag.END ),
704            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END,
705                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP, null ) );
706
707        // State: [SEARCH_RESULT_ENTRY_VALUE_END] - Tag: <value>
708        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END.ordinal()].put( new Tag( "value", Tag.START ),
709            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END,
710                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END, searchResultEntryAddValue ) );
711
712        // State: [SEARCH_RESULT_ENTRY_VALUE_END] - Tag: </attr>
713        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END.ordinal()].put( new Tag( "attr", Tag.END ),
714            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_VALUE_END,
715                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_ATTR_END, null ) );
716
717        //====================================================
718        //  Transitions concerning : SEARCH RESULT ENTRY LOOP
719        //====================================================
720        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP.ordinal()] = new HashMap<Tag, GrammarTransition>();
721
722        // State: [SEARCH_RESULT_ENTRY_LOOP] - Tag: <searchResultEntry>
723        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP.ordinal()].put( new Tag( "searchResultEntry",
724            Tag.START ),
725            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP, Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY,
726                searchResultEntryCreation ) );
727
728        // State: [SEARCH_RESULT_ENTRY_LOOP] - Tag: <searchResultReference>
729        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP.ordinal()].put(
730            new Tag( "searchResultReference", Tag.START ), new GrammarTransition(
731                Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP, Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE,
732                searchResultReferenceCreation ) );
733
734        // State: [SEARCH_RESULT_ENTRY_LOOP] - Tag: <searchResultDone>
735        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP.ordinal()].put( new Tag( "searchResultDone",
736            Tag.START ),
737            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_ENTRY_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
738                searchResultDoneCreation ) );
739
740        //====================================================
741        //  Transitions concerning : SEARCH RESULT REFERENCE
742        //====================================================
743        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE.ordinal()] = new HashMap<Tag, GrammarTransition>();
744        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START.ordinal()] = new HashMap<Tag, GrammarTransition>();
745        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
746        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_VALUE_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
747        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
748
749        // State: [SEARCH_RESULT_REFERENCE] - Tag: <control>
750        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE.ordinal()].put( new Tag( "control", Tag.START ),
751            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE,
752                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START, searchResultReferenceControlCreation ) );
753
754        // State: [SEARCH_RESULT_REFERENCE] - Tag: <ref>
755        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE.ordinal()].put( new Tag( "ref", Tag.START ),
756            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE,
757                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END, searchResultReferenceAddRef ) );
758
759        // State: [SEARCH_RESULT_REFERENCE_CONTROL_START] - Tag: <controlValue>
760        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START.ordinal()].put( new Tag(
761            "controlValue",
762            Tag.START ), new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START,
763            Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_VALUE_END, searchResultReferenceControlValueCreation ) );
764
765        // State: [sEARCH_RESULT_REFERENCE_CONTROL_VALUE_END] - Tag: </control>
766        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_VALUE_END.ordinal()].put(
767            new Tag( "control", Tag.END ), new GrammarTransition(
768                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_VALUE_END,
769                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END, null ) );
770
771        // State: [SEARCH_RESULT_REFERENCE_CONTROL_START] - Tag: </control>
772        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START.ordinal()].put( new Tag( "control",
773            Tag.END ),
774            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START,
775                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END, null ) );
776
777        // State: [SEARCH_RESULT_REFERENCE_CONTROL_END] - Tag: <control>
778        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END.ordinal()].put( new Tag( "control",
779            Tag.START ),
780            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END,
781                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_START, searchResultReferenceControlCreation ) );
782
783        // State: [SEARCH_RESULT_REFERENCE_CONTROL_END] - Tag: <ref>
784        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END.ordinal()].put( new Tag( "ref",
785            Tag.START ),
786            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_CONTROL_END,
787                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END, searchResultReferenceAddRef ) );
788
789        // State: [SEARCH_RESULT_REFERENCE_REF_END] - Tag: <ref>
790        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END.ordinal()].put( new Tag( "ref", Tag.START ),
791            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END,
792                Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END, searchResultReferenceAddRef ) );
793
794        // State: [SEARCH_RESULT_REFERENCE_REF_END] - Tag: </searchResultReference>
795        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END.ordinal()].put( new Tag(
796            "searchResultReference",
797            Tag.END ), new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_REF_END,
798            Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP, null ) );
799
800        //==========================================================
801        //  Transitions concerning : SEARCH RESULT REFERENCE LOOP
802        //==========================================================
803        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP.ordinal()] = new HashMap<Tag, GrammarTransition>();
804
805        // State: [SEARCH_RESULT_REFERENCE_LOOP] - Tag: <searchResultReference>
806        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP.ordinal()].put( new Tag(
807            "searchResultReference",
808            Tag.START ), new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP,
809            Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE, searchResultReferenceCreation ) );
810
811        // State: [SEARCH_RESULT_REFERENCE_LOOP] - Tag: <searchResultDone>
812        super.transitions[Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP.ordinal()].put( new Tag( "searchResultDone",
813            Tag.START ),
814            new GrammarTransition( Dsmlv2StatesEnum.SEARCH_RESULT_REFERENCE_LOOP, Dsmlv2StatesEnum.LDAP_RESULT,
815                searchResultDoneCreation ) );
816        
817        //------------------------------------------ handle SOAP envelopes --------------------------
818        super.transitions[Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG.ordinal()] = new HashMap<Tag, GrammarTransition>();
819        super.transitions[Dsmlv2StatesEnum.SOAP_HEADER_START_TAG.ordinal()] = new HashMap<Tag, GrammarTransition>();
820        super.transitions[Dsmlv2StatesEnum.SOAP_HEADER_END_TAG.ordinal()] = new HashMap<Tag, GrammarTransition>();
821        super.transitions[Dsmlv2StatesEnum.SOAP_BODY_START_TAG.ordinal()] = new HashMap<Tag, GrammarTransition>();
822        super.transitions[Dsmlv2StatesEnum.SOAP_BODY_END_TAG.ordinal()] = new HashMap<Tag, GrammarTransition>();
823
824        super.transitions[Dsmlv2StatesEnum.GRAMMAR_END.ordinal()] = new HashMap<Tag, GrammarTransition>();
825
826        // State: [INIT_GRAMMAR_STATE] - Tag: <envelope>
827        super.transitions[Dsmlv2StatesEnum.INIT_GRAMMAR_STATE.ordinal()].put( new Tag( "envelope", Tag.START ),
828            new GrammarTransition( Dsmlv2StatesEnum.INIT_GRAMMAR_STATE, Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG,
829                null ) );
830
831        // state: [SOAP_ENVELOPE_START_TAG] -> Tag: <header>
832        super.transitions[Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG.ordinal()].put( new Tag( "header", Tag.START ),
833            new GrammarTransition( Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG, Dsmlv2StatesEnum.SOAP_HEADER_START_TAG,
834                    ParserUtils.readSoapHeader ) );
835
836        // state: [SOAP_HEADER_START_TAG] -> Tag: </header>
837        super.transitions[Dsmlv2StatesEnum.SOAP_HEADER_START_TAG.ordinal()]
838            .put( new Tag( "header", Tag.END ),
839                new GrammarTransition( Dsmlv2StatesEnum.SOAP_HEADER_START_TAG, Dsmlv2StatesEnum.SOAP_HEADER_END_TAG,
840                    null ) );
841
842        // state: [SOAP_HEADER_END_TAG] -> Tag: <body>
843        super.transitions[Dsmlv2StatesEnum.SOAP_HEADER_END_TAG.ordinal()].put( new Tag( "body", Tag.START ),
844            new GrammarTransition( Dsmlv2StatesEnum.SOAP_HEADER_END_TAG, Dsmlv2StatesEnum.SOAP_BODY_START_TAG, null ) );
845
846        // state: [SOAP_BODY_START_TAG] -> Tag: <batchResponse>
847        super.transitions[Dsmlv2StatesEnum.SOAP_BODY_START_TAG.ordinal()].put( new Tag( "batchResponse", Tag.START ),
848            new GrammarTransition( Dsmlv2StatesEnum.SOAP_BODY_START_TAG, Dsmlv2StatesEnum.BATCH_RESPONSE_LOOP,
849                batchResponseCreation ) );
850
851        // the optional transition if no soap header is present
852        // state: [SOAP_ENVELOPE_START_TAG] -> Tag: <body>
853        super.transitions[Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG.ordinal()]
854            .put( new Tag( "body", Tag.START ),
855                new GrammarTransition( Dsmlv2StatesEnum.SOAP_ENVELOPE_START_TAG, Dsmlv2StatesEnum.SOAP_BODY_START_TAG,
856                    null ) );
857
858        // the below two transitions are a bit unconventional, technically the container's state is set to GRAMMAR_END
859        // when the </batchRequest> tag is encountered by the parser and the corresponding action gets executed but in
860        // a SOAP envelop we still have two more end tags(</body> and </envelope>) are left so we set those corresponding
861        // current and next transition states always to GRAMMAR_END
862        super.transitions[Dsmlv2StatesEnum.GRAMMAR_END.ordinal()].put( new Tag( "body", Tag.END ),
863            new GrammarTransition( Dsmlv2StatesEnum.GRAMMAR_END, Dsmlv2StatesEnum.GRAMMAR_END, null ) );
864
865        super.transitions[Dsmlv2StatesEnum.GRAMMAR_END.ordinal()].put( new Tag( "envelope", Tag.END ),
866            new GrammarTransition( Dsmlv2StatesEnum.GRAMMAR_END, Dsmlv2StatesEnum.GRAMMAR_END, null ) );
867
868        //------------------------------------------
869    }
870
871    /**
872     * GrammarAction that creates the Batch Response
873     */
874    private final GrammarAction batchResponseCreation = new GrammarAction( "Create Batch Response" )
875    {
876        public void action( Dsmlv2Container container ) throws XmlPullParserException
877        {
878            BatchResponseDsml batchResponse = new BatchResponseDsml();
879
880            container.setBatchResponse( batchResponse );
881
882            XmlPullParser xpp = container.getParser();
883
884            // Checking and adding the batchRequest's attributes
885            String attributeValue;
886            // requestID
887            attributeValue = xpp.getAttributeValue( "", "requestID" );
888
889            if ( attributeValue != null )
890            {
891                batchResponse.setRequestID( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
892            }
893        }
894    };
895
896    /**
897     * GrammarAction that creates the Add Response
898     */
899    private final GrammarAction addResponseCreation = new GrammarAction( "Create Add Response" )
900    {
901        public void action( Dsmlv2Container container ) throws XmlPullParserException
902        {
903            AddResponseDsml addResponse = new AddResponseDsml(
904                container.getLdapCodecService(), new AddResponseImpl() );
905            container.getBatchResponse().addResponse( addResponse );
906
907            LdapResult ldapResult = addResponse.getLdapResult();
908
909            XmlPullParser xpp = container.getParser();
910
911            // Checking and adding the batchRequest's attributes
912            String attributeValue;
913            // requestID
914            attributeValue = xpp.getAttributeValue( "", "requestID" );
915
916            if ( attributeValue != null )
917            {
918                addResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
919            }
920
921            // MatchedDN
922            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
923
924            if ( attributeValue != null )
925            {
926                try
927                {
928                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
929                }
930                catch ( LdapInvalidDnException e )
931                {
932                    throw new XmlPullParserException( "" + e.getMessage(), xpp, null );
933                }
934            }
935        }
936    };
937
938    /**
939     * GrammarAction that creates the Auth Response
940     */
941    private final GrammarAction authResponseCreation = new GrammarAction( "Create Auth Response" )
942    {
943        public void action( Dsmlv2Container container ) throws XmlPullParserException
944        {
945            BindResponseDsml bindResponse = new BindResponseDsml(
946                container.getLdapCodecService(), new BindResponseImpl() );
947            container.getBatchResponse().addResponse( bindResponse );
948
949            LdapResult ldapResult = bindResponse.getLdapResult();
950
951            XmlPullParser xpp = container.getParser();
952
953            // Checking and adding the batchRequest's attributes
954            String attributeValue;
955            // requestID
956            attributeValue = xpp.getAttributeValue( "", "requestID" );
957
958            if ( attributeValue != null )
959            {
960                bindResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
961
962            }
963
964            // MatchedDN
965            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
966
967            if ( attributeValue != null )
968            {
969                try
970                {
971                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
972                }
973                catch ( LdapInvalidDnException e )
974                {
975                    throw new XmlPullParserException( "" + e.getMessage(), xpp, null );
976                }
977            }
978        }
979    };
980
981    /**
982     * GrammarAction that creates the Compare Response
983     */
984    private final GrammarAction compareResponseCreation = new GrammarAction( "Create Compare Response" )
985    {
986        public void action( Dsmlv2Container container ) throws XmlPullParserException
987        {
988            CompareResponseDsml compareResponse = new CompareResponseDsml(
989                container.getLdapCodecService(), new CompareResponseImpl() );
990            container.getBatchResponse().addResponse( compareResponse );
991
992            LdapResult ldapResult = compareResponse.getLdapResult();
993
994            XmlPullParser xpp = container.getParser();
995
996            // Checking and adding the batchRequest's attributes
997            String attributeValue;
998            // requestID
999            attributeValue = xpp.getAttributeValue( "", "requestID" );
1000
1001            if ( attributeValue != null )
1002            {
1003                compareResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
1004            }
1005
1006            // MatchedDN
1007            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
1008
1009            if ( attributeValue != null )
1010            {
1011                try
1012                {
1013                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
1014                }
1015                catch ( LdapInvalidDnException e )
1016                {
1017                    throw new XmlPullParserException( "" + e.getMessage(), xpp, null );
1018                }
1019            }
1020        }
1021    };
1022
1023    /**
1024     * GrammarAction that creates the Del Response
1025     */
1026    private final GrammarAction delResponseCreation = new GrammarAction( "Create Del Response" )
1027    {
1028        public void action( Dsmlv2Container container ) throws XmlPullParserException
1029        {
1030            DelResponseDsml delResponse = new DelResponseDsml(
1031                container.getLdapCodecService(), new DeleteResponseImpl() );
1032            container.getBatchResponse().addResponse( delResponse );
1033
1034            LdapResult ldapResult = delResponse.getLdapResult();
1035
1036            XmlPullParser xpp = container.getParser();
1037
1038            // Checking and adding the batchRequest's attributes
1039            String attributeValue;
1040            // requestID
1041            attributeValue = xpp.getAttributeValue( "", "requestID" );
1042
1043            if ( attributeValue != null )
1044            {
1045                delResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
1046            }
1047
1048            // MatchedDN
1049            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
1050
1051            if ( attributeValue != null )
1052            {
1053                try
1054                {
1055                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
1056                }
1057                catch ( LdapInvalidDnException e )
1058                {
1059                    throw new XmlPullParserException( "" + e.getMessage(), xpp, null );
1060                }
1061            }
1062        }
1063    };
1064
1065    /**
1066     * GrammarAction that creates the Modify Response
1067     */
1068    private final GrammarAction modifyResponseCreation = new GrammarAction( "Create Modify Response" )
1069    {
1070        public void action( Dsmlv2Container container ) throws XmlPullParserException
1071        {
1072            ModifyResponseDsml modifyResponse = new ModifyResponseDsml(
1073                container.getLdapCodecService(), new ModifyResponseImpl() );
1074            container.getBatchResponse().addResponse( modifyResponse );
1075
1076            LdapResult ldapResult = modifyResponse.getLdapResult();
1077
1078            XmlPullParser xpp = container.getParser();
1079
1080            // Checking and adding the batchRequest's attributes
1081            String attributeValue;
1082            // requestID
1083            attributeValue = xpp.getAttributeValue( "", "requestID" );
1084
1085            if ( attributeValue != null )
1086            {
1087                modifyResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
1088            }
1089
1090            // MatchedDN
1091            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
1092
1093            if ( attributeValue != null )
1094            {
1095                try
1096                {
1097                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
1098                }
1099                catch ( LdapInvalidDnException e )
1100                {
1101                    throw new XmlPullParserException( "" + e.getMessage(), xpp, null );
1102                }
1103            }
1104        }
1105    };
1106
1107    /**
1108     * GrammarAction that creates the Mod Dn Response
1109     */
1110    private final GrammarAction modDNResponseCreation = new GrammarAction( "Create Mod Dn Response" )
1111    {
1112        public void action( Dsmlv2Container container ) throws XmlPullParserException
1113        {
1114            ModDNResponseDsml modDNResponse = new ModDNResponseDsml(
1115                container.getLdapCodecService(), new ModifyDnResponseImpl() );
1116            container.getBatchResponse().addResponse( modDNResponse );
1117
1118            LdapResult ldapResult = modDNResponse.getLdapResult();
1119
1120            XmlPullParser xpp = container.getParser();
1121
1122            // Checking and adding the batchRequest's attributes
1123            String attributeValue;
1124            // requestID
1125            attributeValue = xpp.getAttributeValue( "", "requestID" );
1126
1127            if ( attributeValue != null )
1128            {
1129                modDNResponse.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
1130            }
1131
1132            // MatchedDN
1133            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
1134
1135            if ( attributeValue != null )
1136            {
1137                try
1138                {
1139                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
1140                }
1141                catch ( LdapInvalidDnException e )
1142                {
1143                    throw new XmlPullParserException( "" + e.getMessage(), xpp, null );
1144                }
1145            }
1146        }
1147    };
1148
1149    /**
1150     * GrammarAction that creates the Extended Response
1151     */
1152    private final GrammarAction extendedResponseCreation = new GrammarAction( "Create Extended Response" )
1153    {
1154        public void action( Dsmlv2Container container ) throws XmlPullParserException
1155        {
1156            ExtendedResponseDsml extendedResponse = null;
1157
1158            // Checking and adding the batchRequest's attributes
1159            String attributeValue;
1160
1161            XmlPullParser xpp = container.getParser();
1162
1163            // requestID
1164            attributeValue = xpp.getAttributeValue( "", "requestID" );
1165
1166            if ( attributeValue != null )
1167            {
1168                extendedResponse = new ExtendedResponseDsml(
1169                    container.getLdapCodecService(), new ExtendedResponseImpl(
1170                        ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) ) );
1171            }
1172            else
1173            {
1174                extendedResponse = new ExtendedResponseDsml(
1175                    container.getLdapCodecService(), new ExtendedResponseImpl( -1 ) );
1176            }
1177
1178            container.getBatchResponse().addResponse( extendedResponse );
1179
1180            LdapResult ldapResult = extendedResponse.getLdapResult();
1181
1182            // MatchedDN
1183            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
1184
1185            if ( attributeValue != null )
1186            {
1187                try
1188                {
1189                    ldapResult.setMatchedDn( new Dn( attributeValue ) );
1190                }
1191                catch ( LdapInvalidDnException e )
1192                {
1193                    throw new XmlPullParserException( "" + e.getMessage(), xpp, null );
1194                }
1195            }
1196        }
1197    };
1198
1199    /**
1200     * GrammarAction that creates the Error Response
1201     */
1202    private final GrammarAction errorResponseCreation = new GrammarAction( "Create Error Response" )
1203    {
1204        public void action( Dsmlv2Container container ) throws XmlPullParserException
1205        {
1206            ErrorResponse errorResponse = null;
1207            XmlPullParser xpp = container.getParser();
1208
1209            // Checking and adding the batchRequest's attributes
1210            String attributeValue;
1211            // requestID
1212            attributeValue = xpp.getAttributeValue( "", "requestID" );
1213
1214            if ( attributeValue != null )
1215            {
1216                errorResponse = new ErrorResponse( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ), null );
1217
1218                container.getBatchResponse().addResponse( errorResponse );
1219            }
1220            // type
1221            attributeValue = xpp.getAttributeValue( "", "type" );
1222            if ( attributeValue != null )
1223            {
1224                if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.NOT_ATTEMPTED ) ) )
1225                {
1226                    errorResponse.setErrorType( ErrorResponseType.NOT_ATTEMPTED );
1227                }
1228                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.COULD_NOT_CONNECT ) ) )
1229                {
1230                    errorResponse.setErrorType( ErrorResponseType.COULD_NOT_CONNECT );
1231                }
1232                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.CONNECTION_CLOSED ) ) )
1233                {
1234                    errorResponse.setErrorType( ErrorResponseType.CONNECTION_CLOSED );
1235                }
1236                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.MALFORMED_REQUEST ) ) )
1237                {
1238                    errorResponse.setErrorType( ErrorResponseType.MALFORMED_REQUEST );
1239                }
1240                else if ( attributeValue
1241                    .equals( errorResponse.getTypeDescr( ErrorResponseType.GATEWAY_INTERNAL_ERROR ) ) )
1242                {
1243                    errorResponse.setErrorType( ErrorResponseType.GATEWAY_INTERNAL_ERROR );
1244                }
1245                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.AUTHENTICATION_FAILED ) ) )
1246                {
1247                    errorResponse.setErrorType( ErrorResponseType.AUTHENTICATION_FAILED );
1248                }
1249                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.UNRESOLVABLE_URI ) ) )
1250                {
1251                    errorResponse.setErrorType( ErrorResponseType.UNRESOLVABLE_URI );
1252                }
1253                else if ( attributeValue.equals( errorResponse.getTypeDescr( ErrorResponseType.OTHER ) ) )
1254                {
1255                    errorResponse.setErrorType( ErrorResponseType.OTHER );
1256                }
1257                else
1258                {
1259                    throw new XmlPullParserException( I18n.err( I18n.ERR_03004 ), xpp, null );
1260                }
1261            }
1262            else
1263            {
1264                throw new XmlPullParserException( I18n.err( I18n.ERR_03005 ), xpp, null );
1265            }
1266        }
1267    };
1268
1269    /**
1270     * GrammarAction that adds Message to an Error Response
1271     */
1272    private final GrammarAction errorResponseAddMessage = new GrammarAction( "Add Message to Error Response" )
1273    {
1274        public void action( Dsmlv2Container container ) throws XmlPullParserException
1275        {
1276            ErrorResponse errorResponse = ( ErrorResponse ) container.getBatchResponse().getCurrentResponse();
1277
1278            XmlPullParser xpp = container.getParser();
1279            try
1280            {
1281                String nextText = xpp.nextText();
1282                if ( !nextText.equals( "" ) )
1283                {
1284                    errorResponse.setMessage( nextText.trim() );
1285                }
1286            }
1287            catch ( IOException e )
1288            {
1289                throw new XmlPullParserException( e.getMessage(), xpp, null );
1290            }
1291        }
1292    };
1293
1294    /**
1295     * GrammarAction that adds Detail to an Error Response
1296     */
1297    private final GrammarAction errorResponseAddDetail = null; // TODO Look for documentation about this Detail element (the DSML documentation doesn't give enough information)
1298
1299
1300    /**
1301     * Creates a Control parsing the current node and adds it to the given parent 
1302     * @param container the DSMLv2Container
1303     * @param parent the parent 
1304     * @throws XmlPullParserException
1305     */
1306    private void createAndAddControl( Dsmlv2Container container,
1307        AbstractDsmlMessageDecorator<? extends Message> parent ) throws XmlPullParserException
1308    {
1309        CodecControl<? extends Control> control = null;
1310
1311        XmlPullParser xpp = container.getParser();
1312
1313        // Checking and adding the Control's attributes
1314        String attributeValue;
1315        // TYPE
1316        attributeValue = xpp.getAttributeValue( "", "type" );
1317
1318        if ( attributeValue != null )
1319        {
1320            if ( !Oid.isOid( attributeValue ) )
1321            {
1322                throw new XmlPullParserException( I18n.err( I18n.ERR_03006 ), xpp, null );
1323            }
1324
1325            control = container.getLdapCodecService().newControl( new OpaqueControl( attributeValue ) );
1326            parent.addControl( control );
1327        }
1328        else
1329        {
1330            throw new XmlPullParserException( I18n.err( I18n.ERR_03005 ), xpp, null );
1331        }
1332        // CRITICALITY
1333        attributeValue = xpp.getAttributeValue( "", "criticality" );
1334
1335        if ( attributeValue != null )
1336        {
1337            if ( attributeValue.equals( "true" ) )
1338            {
1339                control.setCritical( true );
1340            }
1341            else if ( attributeValue.equals( "false" ) )
1342            {
1343                control.setCritical( false );
1344            }
1345            else
1346            {
1347                throw new XmlPullParserException( I18n.err( I18n.ERR_03007 ), xpp, null );
1348            }
1349        }
1350    }
1351
1352    /**
1353     * GrammarAction that creates a Control for LDAP Result
1354     */
1355    private final GrammarAction ldapResultControlCreation = new GrammarAction( "Create Control for LDAP Result" )
1356    {
1357        public void action( Dsmlv2Container container ) throws XmlPullParserException
1358        {
1359            AbstractDsmlMessageDecorator<? extends Message> message =
1360                ( AbstractDsmlMessageDecorator<? extends Message> )
1361                container.getBatchResponse().getCurrentResponse();
1362
1363            if ( message instanceof SearchResponseDsml )
1364            {
1365                createAndAddControl( container,
1366                    ( ( SearchResponse ) ( ( SearchResponseDsml ) message ).getDecorated() ).getSearchResultDone() );
1367            }
1368            else
1369            {
1370                createAndAddControl( container, message );
1371            }
1372        }
1373    };
1374
1375    /**
1376     * GrammarAction that creates a Control for Search Result Entry
1377     */
1378    private final GrammarAction searchResultEntryControlCreation = new GrammarAction(
1379        "Create Control for Search Result Entry" )
1380    {
1381        public void action( Dsmlv2Container container ) throws XmlPullParserException
1382        {
1383            SearchResponse response = ( SearchResponse )
1384                ( ( SearchResponseDsml ) container.getBatchResponse()
1385                    .getCurrentResponse() ).getDecorated();
1386
1387            createAndAddControl( container, response.getCurrentSearchResultEntry() );
1388        }
1389    };
1390
1391    /**
1392     * GrammarAction that creates a Control for Search Result Entry
1393     */
1394    private final GrammarAction searchResultReferenceControlCreation = new GrammarAction(
1395        "Create Control for Search Result Reference" )
1396    {
1397        public void action( Dsmlv2Container container ) throws XmlPullParserException
1398        {
1399            SearchResponse response = ( SearchResponse )
1400                ( ( SearchResponseDsml ) container.getBatchResponse()
1401                    .getCurrentResponse() ).getDecorated();
1402
1403            createAndAddControl( container, response.getCurrentSearchResultReference() );
1404        }
1405    };
1406
1407
1408    /**
1409     * Creates a Control Value parsing the current node and adds it to the given parent 
1410     * @param container the DSMLv2Container
1411     * @param parent the parent 
1412     * @throws XmlPullParserException
1413     */
1414    private void createAndAddControlValue( Dsmlv2Container container,
1415        AbstractDsmlMessageDecorator<? extends Message> parent )
1416        throws XmlPullParserException
1417    {
1418        DsmlControl<? extends Control> control =
1419            ( ( AbstractDsmlMessageDecorator<?> ) parent ).getCurrentControl();
1420
1421        XmlPullParser xpp = container.getParser();
1422        try
1423        {
1424            // We have to catch the type Attribute Value before going to the next Text node
1425            String typeValue = ParserUtils.getXsiTypeAttributeValue( xpp );
1426
1427            // Getting the value
1428            String nextText = xpp.nextText();
1429
1430            if ( !nextText.equals( "" ) )
1431            {
1432                if ( ParserUtils.isBase64BinaryValue( xpp, typeValue ) )
1433                {
1434                    control.setValue( Base64.decode( nextText.trim().toCharArray() ) );
1435                }
1436                else
1437                {
1438                    control.setValue( nextText.trim().getBytes() );
1439                }
1440            }
1441        }
1442        catch ( IOException e )
1443        {
1444            throw new XmlPullParserException( I18n.err( I18n.ERR_03008, e.getMessage() ), xpp, null );
1445        }
1446    }
1447
1448    /**
1449     * GrammarAction that creates a Control Value for LDAP Result
1450     */
1451    private final GrammarAction ldapResultControlValueCreation = new GrammarAction(
1452        "Add ControlValue to Control for LDAP Result" )
1453    {
1454        public void action( Dsmlv2Container container ) throws XmlPullParserException
1455        {
1456            AbstractDsmlMessageDecorator<? extends Response> response
1457            = ( AbstractDsmlMessageDecorator<? extends Response> )
1458                container.getBatchResponse().getCurrentResponse();
1459
1460            if ( response instanceof SearchResponseDsml )
1461            {
1462                SearchResponse searchResponse = ( SearchResponse )
1463                    response.getDecorated();
1464                createAndAddControlValue( container,
1465                    searchResponse.getSearchResultDone() );
1466            }
1467            else
1468            {
1469                createAndAddControlValue( container, response );
1470            }
1471        }
1472    };
1473
1474    /**
1475     * GrammarAction that creates a Control Value for Search Result Entry
1476     */
1477    private final GrammarAction searchResultEntryControlValueCreation = new GrammarAction(
1478        "Add ControlValue to Control for Search Result Entry" )
1479    {
1480        public void action( Dsmlv2Container container ) throws XmlPullParserException
1481        {
1482            SearchResponse response = ( SearchResponse )
1483                container.getBatchResponse().getCurrentResponse().getDecorated();
1484            createAndAddControlValue( container,
1485                response.getCurrentSearchResultEntry() );
1486        }
1487    };
1488
1489    /**
1490     * GrammarAction that creates a Control Value for Search Result Reference
1491     */
1492    private final GrammarAction searchResultReferenceControlValueCreation = new GrammarAction(
1493        "Add ControlValue to Control for Search Result Entry" )
1494    {
1495        public void action( Dsmlv2Container container ) throws XmlPullParserException
1496        {
1497            SearchResponseDsml response = ( SearchResponseDsml )
1498                container.getBatchResponse().getCurrentResponse();
1499            createAndAddControlValue( container,
1500                ( ( SearchResponse ) response.getDecorated() ).getCurrentSearchResultReference() );
1501        }
1502    };
1503
1504    /**
1505     * GrammarAction that adds a Result Code to a LDAP Result
1506     */
1507    private final GrammarAction ldapResultAddResultCode = new GrammarAction( "Add ResultCode to LDAP Result" )
1508    {
1509        public void action( Dsmlv2Container container ) throws XmlPullParserException
1510        {
1511            DsmlDecorator<? extends Response> ldapResponse =
1512                container.getBatchResponse().getCurrentResponse();
1513
1514            LdapResult ldapResult = null;
1515
1516            // Search Response is a special case
1517            // ResultCode can only occur in a case of Search Result Done in a Search Response
1518            if ( ldapResponse.getDecorated() instanceof SearchResponse )
1519            {
1520                SearchResponse searchResponse = ( SearchResponse ) ldapResponse.getDecorated();
1521                ldapResult = searchResponse.getSearchResultDone().getLdapResult();
1522            }
1523            else
1524            {
1525                ldapResult = ( ( ResultResponse ) ldapResponse.getDecorated() ).getLdapResult();
1526            }
1527
1528            XmlPullParser xpp = container.getParser();
1529
1530            // Checking and adding the request's attributes
1531            String attributeValue;
1532            // code
1533            attributeValue = xpp.getAttributeValue( "", "code" );
1534
1535            if ( attributeValue != null )
1536            {
1537                try
1538                {
1539                    ldapResult.setResultCode( ResultCodeEnum.getResultCode( Integer.parseInt( attributeValue ) ) );
1540                }
1541                catch ( NumberFormatException e )
1542                {
1543                    throw new XmlPullParserException( I18n.err( I18n.ERR_03009 ), xpp, null );
1544                }
1545            }
1546            else
1547            {
1548                throw new XmlPullParserException( I18n.err( I18n.ERR_03010 ), xpp, null );
1549            }
1550
1551            // descr
1552            attributeValue = xpp.getAttributeValue( "", "descr" );
1553
1554            if ( ( attributeValue != null ) && !DSMLV2_DESCR_TAGS.contains( attributeValue ) )
1555            {
1556                throw new XmlPullParserException( I18n.err( I18n.ERR_03011, attributeValue ), xpp, null );
1557            }
1558        }
1559    };
1560
1561    /**
1562     * GrammarAction that adds a Error Message to a LDAP Result
1563     */
1564    private final GrammarAction ldapResultAddErrorMessage = new GrammarAction( "Add Error Message to LDAP Result" )
1565    {
1566        public void action( Dsmlv2Container container ) throws XmlPullParserException
1567        {
1568            DsmlDecorator<? extends Response> ldapResponse =
1569                container.getBatchResponse().getCurrentResponse();
1570
1571            LdapResult ldapResult = null;
1572
1573            // Search Response is a special case
1574            // ResultCode can only occur in a case of Search Result Done in a Search Response
1575            if ( ldapResponse.getDecorated() instanceof SearchResponse )
1576            {
1577                SearchResponse searchResponse = ( SearchResponse ) ldapResponse.getDecorated();
1578                ldapResult = searchResponse.getSearchResultDone().getLdapResult();
1579            }
1580            else
1581            {
1582                ldapResult = ( ( ResultResponse ) ldapResponse.getDecorated() ).getLdapResult();
1583            }
1584
1585            XmlPullParser xpp = container.getParser();
1586
1587            try
1588            {
1589                String nextText = xpp.nextText();
1590
1591                if ( !nextText.equals( "" ) )
1592                {
1593                    ldapResult.setDiagnosticMessage( nextText.trim() );
1594                }
1595            }
1596            catch ( IOException e )
1597            {
1598                throw new XmlPullParserException( I18n.err( I18n.ERR_03008, e.getMessage() ), xpp, null );
1599            }
1600        }
1601    };
1602
1603    /**
1604     * GrammarAction that adds a Referral to a LDAP Result
1605     */
1606    private final GrammarAction ldapResultAddReferral = new GrammarAction( "Add Referral to LDAP Result" )
1607    {
1608        public void action( Dsmlv2Container container ) throws XmlPullParserException
1609        {
1610            DsmlDecorator<? extends Response> ldapResponse =
1611                container.getBatchResponse().getCurrentResponse();
1612
1613            LdapResult ldapResult = null;
1614
1615            // Search Response is a special case
1616            // ResultCode can only occur in a case of Search Result Done in a Search Response
1617            if ( ldapResponse.getDecorated() instanceof SearchResponse )
1618            {
1619                SearchResponse searchResponse = ( SearchResponse ) ldapResponse.getDecorated();
1620                ldapResult = searchResponse.getSearchResultDone().getLdapResult();
1621            }
1622            else
1623            {
1624                ldapResult = ( ( ResultResponse ) ldapResponse.getDecorated() ).getLdapResult();
1625            }
1626
1627            // Initialization of the Referrals if needed
1628            if ( ldapResult.getReferral() == null )
1629            {
1630                ldapResult.setReferral( new ReferralImpl() );
1631            }
1632
1633            XmlPullParser xpp = container.getParser();
1634
1635            try
1636            {
1637                String nextText = xpp.nextText();
1638
1639                if ( !nextText.equals( "" ) )
1640                {
1641                    try
1642                    {
1643                        String urlStr = nextText.trim();
1644                        LdapUrl ldapUrl = new LdapUrl( urlStr );
1645                        ldapResult.getReferral().addLdapUrl( ldapUrl.toString() );
1646                    }
1647                    catch ( LdapURLEncodingException e )
1648                    {
1649                        throw new XmlPullParserException( e.getMessage(), xpp, null );
1650                    }
1651                }
1652            }
1653            catch ( IOException e )
1654            {
1655                throw new XmlPullParserException( I18n.err( I18n.ERR_03008, e.getMessage() ), xpp, null );
1656            }
1657        }
1658    };
1659
1660    /**
1661     * GrammarAction that creates the Search Response
1662     */
1663    private final GrammarAction searchResponseCreation = new GrammarAction( "Create Search Response" )
1664    {
1665        public void action( Dsmlv2Container container ) throws XmlPullParserException
1666        {
1667            XmlPullParser xpp = container.getParser();
1668            SearchResponse searchResponse = null;
1669
1670            // Checking and adding the batchRequest's attributes
1671            String attributeValue = xpp.getAttributeValue( "", "requestID" );
1672
1673            if ( attributeValue != null )
1674            {
1675                searchResponse = new SearchResponse(
1676                    ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
1677            }
1678            else
1679            {
1680                searchResponse = new SearchResponse();
1681            }
1682
1683            container.getBatchResponse().addResponse( new SearchResponseDsml(
1684                container.getLdapCodecService(), searchResponse ) );
1685        }
1686    };
1687
1688    /**
1689     * GrammarAction that creates a Search Result Entry
1690     */
1691    private final GrammarAction searchResultEntryCreation = new GrammarAction(
1692        "Add Search Result Entry to Search Response" )
1693    {
1694        public void action( Dsmlv2Container container ) throws XmlPullParserException
1695        {
1696            SearchResultEntryDsml searchResultEntry =
1697                new SearchResultEntryDsml( container.getLdapCodecService(),
1698                    new SearchResultEntryImpl() );
1699            SearchResponseDsml searchResponse = ( SearchResponseDsml )
1700                container.getBatchResponse().getCurrentResponse();
1701            searchResponse.addResponse( searchResultEntry );
1702
1703            XmlPullParser xpp = container.getParser();
1704
1705            // Checking and adding the request's attributes
1706            String attributeValue;
1707            // requestID
1708            attributeValue = xpp.getAttributeValue( "", "requestID" );
1709
1710            if ( attributeValue != null )
1711            {
1712                searchResultEntry.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
1713            }
1714
1715            // dn
1716            attributeValue = xpp.getAttributeValue( "", "dn" );
1717
1718            if ( attributeValue != null )
1719            {
1720                try
1721                {
1722                    searchResultEntry.setObjectName( new Dn( attributeValue ) );
1723                }
1724                catch ( LdapInvalidDnException e )
1725                {
1726                    throw new XmlPullParserException( e.getMessage(), xpp, null );
1727                }
1728            }
1729            else
1730            {
1731                throw new XmlPullParserException( "dn attribute is required", xpp, null );
1732            }
1733        }
1734    };
1735
1736    /**
1737     * GrammarAction that creates a Search Result Reference
1738     */
1739    private final GrammarAction searchResultReferenceCreation = new GrammarAction(
1740        "Add Search Result Reference to Search Response" )
1741    {
1742        public void action( Dsmlv2Container container ) throws XmlPullParserException
1743        {
1744            SearchResultReferenceDsml searchResultReference =
1745                new SearchResultReferenceDsml(
1746                    container.getLdapCodecService(),
1747                    new SearchResultReferenceImpl() );
1748
1749            SearchResponseDsml searchResponseDsml = ( SearchResponseDsml )
1750                container.getBatchResponse().getCurrentResponse();
1751
1752            searchResponseDsml.addResponse( searchResultReference );
1753
1754            XmlPullParser xpp = container.getParser();
1755
1756            // Checking and adding the request's attributes
1757            String attributeValue;
1758            // requestID
1759            attributeValue = xpp.getAttributeValue( "", "requestID" );
1760
1761            if ( attributeValue != null )
1762            {
1763                searchResultReference.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
1764            }
1765        }
1766    };
1767
1768    /**
1769     * GrammarAction that creates a Search Result Done
1770     */
1771    private final GrammarAction searchResultDoneCreation = new GrammarAction(
1772        "Add Search Result Done to Search Response" )
1773    {
1774        public void action( Dsmlv2Container container ) throws XmlPullParserException
1775        {
1776            SearchResultDoneDsml searchResultDone =
1777                new SearchResultDoneDsml( container.getLdapCodecService(),
1778                    new SearchResultDoneImpl() );
1779
1780            SearchResponseDsml searchResponseDsml = ( SearchResponseDsml )
1781                container.getBatchResponse().getCurrentResponse();
1782            searchResponseDsml.addResponse( searchResultDone );
1783
1784            XmlPullParser xpp = container.getParser();
1785
1786            // Checking and adding the batchRequest's attributes
1787            String attributeValue;
1788            // requestID
1789            attributeValue = xpp.getAttributeValue( "", "requestID" );
1790
1791            if ( attributeValue != null )
1792            {
1793                searchResultDone.setMessageId( ParserUtils.parseAndVerifyRequestID( attributeValue, xpp ) );
1794            }
1795
1796            // MatchedDN
1797            attributeValue = xpp.getAttributeValue( "", "matchedDN" );
1798
1799            if ( attributeValue != null )
1800            {
1801                try
1802                {
1803                    searchResultDone.getLdapResult().setMatchedDn( new Dn( attributeValue ) );
1804                }
1805                catch ( LdapInvalidDnException e )
1806                {
1807                    throw new XmlPullParserException( "" + e.getMessage(), xpp, null );
1808                }
1809            }
1810        }
1811    };
1812
1813    /**
1814     * GrammarAction that adds an Attr to a Search Result Entry
1815     */
1816    private final GrammarAction searchResultEntryAddAttr = new GrammarAction( "Add Attr to Search Result Entry" )
1817    {
1818        public void action( Dsmlv2Container container ) throws XmlPullParserException
1819        {
1820            SearchResponse searchResponse = ( SearchResponse )
1821                container.getBatchResponse().getCurrentResponse().getDecorated();
1822
1823            SearchResultEntryDsml searchResultEntry = ( SearchResultEntryDsml )
1824                searchResponse.getCurrentSearchResultEntry();
1825
1826            XmlPullParser xpp = container.getParser();
1827
1828            // Checking and adding the request's attributes
1829            String attributeValue;
1830            // name
1831            attributeValue = xpp.getAttributeValue( "", "name" );
1832
1833            if ( attributeValue != null )
1834            {
1835                try
1836                {
1837                    searchResultEntry.addAttribute( attributeValue );
1838                }
1839                catch ( LdapException le )
1840                {
1841                    throw new XmlPullParserException( I18n.err( I18n.ERR_03012 ), xpp, null );
1842                }
1843            }
1844            else
1845            {
1846                throw new XmlPullParserException( I18n.err( I18n.ERR_03012 ), xpp, null );
1847            }
1848        }
1849    };
1850
1851    /**
1852     * GrammarAction that adds a Value to an Attr of a Search Result Entry
1853     */
1854    private final GrammarAction searchResultEntryAddValue = new GrammarAction(
1855        "Add a Value to an Attr of a Search Result Entry" )
1856    {
1857        public void action( Dsmlv2Container container ) throws XmlPullParserException
1858        {
1859            SearchResponse searchResponse = ( SearchResponse )
1860                container.getBatchResponse().getCurrentResponse().getDecorated();
1861            SearchResultEntryDsml searchResultEntry = ( SearchResultEntryDsml )
1862                searchResponse.getCurrentSearchResultEntry();
1863
1864            XmlPullParser xpp = container.getParser();
1865
1866            try
1867            {
1868                // We have to catch the type Attribute Value before going to the next Text node
1869                String typeValue = ParserUtils.getXsiTypeAttributeValue( xpp );
1870
1871                // Getting the value
1872                String nextText = xpp.nextText();
1873
1874                try
1875                {
1876                    if ( ParserUtils.isBase64BinaryValue( xpp, typeValue ) )
1877                    {
1878                        searchResultEntry.addAttributeValue( Base64.decode( nextText.toCharArray() ) );
1879                    }
1880                    else
1881                    {
1882                        searchResultEntry.addAttributeValue( nextText );
1883                    }
1884                }
1885                catch ( LdapException le )
1886                {
1887                    throw new XmlPullParserException( le.getMessage() );
1888                }
1889            }
1890            catch ( IOException e )
1891            {
1892                throw new XmlPullParserException( I18n.err( I18n.ERR_03008, e.getMessage() ), xpp, null );
1893            }
1894        }
1895    };
1896
1897    /**
1898     * GrammarAction that adds a Ref to a Search Result Reference
1899     */
1900    private final GrammarAction searchResultReferenceAddRef = new GrammarAction(
1901        "Add a Ref to a Search Result Reference" )
1902    {
1903        public void action( Dsmlv2Container container ) throws XmlPullParserException
1904        {
1905            SearchResponse searchResponse = ( SearchResponse )
1906                container.getBatchResponse().getCurrentResponse().getDecorated();
1907            SearchResultReference searchResultReference = searchResponse.getCurrentSearchResultReference();
1908
1909            XmlPullParser xpp = container.getParser();
1910
1911            try
1912            {
1913                String nextText = xpp.nextText();
1914
1915                if ( !nextText.equals( "" ) )
1916                {
1917                    LdapUrl ldapUrl = new LdapUrl( nextText );
1918
1919                    searchResultReference.getReferral().addLdapUrl( ldapUrl.toString() );
1920                }
1921            }
1922            catch ( IOException e )
1923            {
1924                throw new XmlPullParserException( I18n.err( I18n.ERR_03008, e.getMessage() ), xpp, null );
1925            }
1926            catch ( LdapURLEncodingException e )
1927            {
1928                throw new XmlPullParserException( e.getMessage(), xpp, null );
1929            }
1930        }
1931    };
1932
1933    /**
1934     * GrammarAction that adds Result Code to an Extended Response
1935     */
1936    private final GrammarAction extendedResponseAddResultCode = ldapResultAddResultCode;
1937
1938    /**
1939     * GrammarAction that creates the Search Response
1940     */
1941    private final GrammarAction extendedResponseAddErrorMessage = ldapResultAddErrorMessage;
1942
1943    /**
1944     * GrammarAction that adds a Referral to an Extended Response
1945     */
1946    private final GrammarAction extendedResponseAddReferral = ldapResultAddReferral;
1947
1948    /**
1949     * GrammarAction that adds a Response Name to an Extended Response
1950     */
1951    private final GrammarAction extendedResponseAddResponseName = new GrammarAction(
1952        "Add Response Name to Extended Response" )
1953    {
1954        public void action( Dsmlv2Container container ) throws XmlPullParserException
1955        {
1956            ExtendedResponse extendedResponse = ( ExtendedResponse ) container.getBatchResponse().getCurrentResponse();
1957
1958            XmlPullParser xpp = container.getParser();
1959
1960            try
1961            {
1962                String nextText = xpp.nextText();
1963
1964                if ( !nextText.equals( "" ) )
1965                {
1966                    extendedResponse.setResponseName( new Oid( nextText.trim() ).toString() );
1967                }
1968
1969            }
1970            catch ( IOException e )
1971            {
1972                throw new XmlPullParserException( I18n.err( I18n.ERR_03008, e.getMessage() ), xpp, null );
1973            }
1974            catch ( DecoderException e )
1975            {
1976                throw new XmlPullParserException( e.getMessage(), xpp, null );
1977            }
1978        }
1979    };
1980
1981    /**
1982     * GrammarAction that adds a Response to an Extended Response
1983     */
1984    private final GrammarAction extendedResponseAddResponse = new GrammarAction( "Add Response to Extended Response" )
1985    {
1986        public void action( Dsmlv2Container container ) throws XmlPullParserException
1987        {
1988            ExtendedResponseDsml extendedResponse = ( ExtendedResponseDsml ) container.getBatchResponse()
1989                .getCurrentResponse();
1990
1991            XmlPullParser xpp = container.getParser();
1992
1993            try
1994            {
1995                // We have to catch the type Attribute Value before going to the next Text node
1996                String typeValue = ParserUtils.getXsiTypeAttributeValue( xpp );
1997
1998                // Getting the value
1999                String nextText = xpp.nextText();
2000
2001                if ( ParserUtils.isBase64BinaryValue( xpp, typeValue ) )
2002                {
2003                    extendedResponse.setResponseValue( Base64.decode( nextText.trim().toCharArray() ) );
2004                }
2005                else
2006                {
2007                    extendedResponse.setResponseValue( Strings.getBytesUtf8( nextText.trim() ) );
2008                }
2009            }
2010            catch ( IOException e )
2011            {
2012                throw new XmlPullParserException( I18n.err( I18n.ERR_03008, e.getMessage() ), xpp, null );
2013            }
2014        }
2015    };
2016
2017
2018    /**
2019     * Get the instance of this grammar
2020     * 
2021     * @return
2022     *      an instance on this grammar
2023     */
2024    public static Dsmlv2ResponseGrammar getInstance()
2025    {
2026        return instance;
2027    }
2028}