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.ldap.model.message;
021
022
023import java.util.Collections;
024import java.util.HashSet;
025import java.util.Set;
026
027import javax.naming.CommunicationException;
028import javax.naming.LimitExceededException;
029import javax.naming.PartialResultException;
030import javax.naming.SizeLimitExceededException;
031
032import org.apache.directory.api.ldap.model.exception.LdapAdminLimitExceededException;
033import org.apache.directory.api.ldap.model.exception.LdapAffectMultipleDsaException;
034import org.apache.directory.api.ldap.model.exception.LdapAliasDereferencingException;
035import org.apache.directory.api.ldap.model.exception.LdapAliasException;
036import org.apache.directory.api.ldap.model.exception.LdapAttributeInUseException;
037import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
038import org.apache.directory.api.ldap.model.exception.LdapAuthenticationNotSupportedException;
039import org.apache.directory.api.ldap.model.exception.LdapCannotCancelException;
040import org.apache.directory.api.ldap.model.exception.LdapContextNotEmptyException;
041import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
042import org.apache.directory.api.ldap.model.exception.LdapException;
043import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeTypeException;
044import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
045import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
046import org.apache.directory.api.ldap.model.exception.LdapInvalidSearchFilterException;
047import org.apache.directory.api.ldap.model.exception.LdapLoopDetectedException;
048import org.apache.directory.api.ldap.model.exception.LdapNoPermissionException;
049import org.apache.directory.api.ldap.model.exception.LdapNoSuchAttributeException;
050import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
051import org.apache.directory.api.ldap.model.exception.LdapNoSuchOperationException;
052import org.apache.directory.api.ldap.model.exception.LdapOperationErrorException;
053import org.apache.directory.api.ldap.model.exception.LdapOperationException;
054import org.apache.directory.api.ldap.model.exception.LdapOtherException;
055import org.apache.directory.api.ldap.model.exception.LdapProtocolErrorException;
056import org.apache.directory.api.ldap.model.exception.LdapSchemaViolationException;
057import org.apache.directory.api.ldap.model.exception.LdapServiceUnavailableException;
058import org.apache.directory.api.ldap.model.exception.LdapSizeLimitExceededException;
059import org.apache.directory.api.ldap.model.exception.LdapStrongAuthenticationRequiredException;
060import org.apache.directory.api.ldap.model.exception.LdapTimeLimitExceededException;
061import org.apache.directory.api.ldap.model.exception.LdapTooLateException;
062import org.apache.directory.api.ldap.model.exception.LdapUnknownException;
063import org.apache.directory.api.ldap.model.exception.LdapUnwillingToPerformException;
064
065
066/**
067 * Type safe LDAP message envelope result code enumeration. The resultCode is a
068 * parameter of the LDAPResult which is the construct used in this protocol to
069 * return success or failure indications from servers to clients. In response to
070 * various requests servers will return responses containing fields of type
071 * LDAPResult to indicate the final status of a protocol operation request. This
072 * enumeration represents the various status codes associated with an
073 * LDAPResult, hence it is called the ResultCodeEnum. Here are the definitions
074 * and values for error codes from section 4.1.10 of <a
075 * href="http://www.faqs.org/rfcs/rfc2251.html">RFC 2251</a>:
076 * 
077 * <pre><code>
078 *     resultCode
079 *        ENUMERATED {
080 *           success                      (0),
081 *           operationsError              (1),
082 *           protocolError                (2),
083 *           timeLimitExceeded            (3),
084 *           sizeLimitExceeded            (4),
085 *           compareFalse                 (5),
086 *           compareTrue                  (6),
087 *           authMethodNotSupported       (7),
088 *           strongAuthRequired           (8),
089 *           partialResults               (9),   -- new
090 *           referral                     (10),  -- new
091 *           adminLimitExceeded           (11),  -- new
092 *           unavailableCriticalExtension (12),  -- new
093 *           confidentialityRequired      (13),  -- new
094 *           saslBindInProgress           (14),  -- new
095 *           noSuchAttribute              (16),
096 *           undefinedAttributeType       (17),
097 *           inappropriateMatching        (18),
098 *           constraintViolation          (19),
099 *           attributeOrValueExists       (20),
100 *           invalidAttributeSyntax       (21),
101 *           -- 22-31 unused --
102 *           NO_SUCH_OBJECT                 (32),
103 *           aliasProblem                 (33),
104 *           invalidDNSyntax              (34),
105 *           -- 35 reserved for undefined isLeaf --
106 *           aliasDereferencingProblem    (36),
107 *           -- 37-47 unused --
108 *           inappropriateAuthentication  (48),
109 *           invalidCredentials           (49),
110 *           insufficientAccessRights     (50),
111 *           busy                         (51),
112 *           unavailable                  (52),
113 *           unwillingToPerform           (53),
114 *           loopDetect                   (54),
115 *           -- 55-63 unused --
116 *           namingViolation              (64),
117 *           objectClassViolation         (65),
118 *           notAllowedOnNonLeaf          (66),
119 *           notAllowedOnRDN              (67),
120 *           entryAlreadyExists           (68),
121 *           objectClassModsProhibited    (69),
122 *           -- 70 reserved for CLDAP --
123 *           affectsMultipleDSAs          (71), -- new
124 *           -- 72-79 unused --
125 *           other                        (80) },
126 *           -- 81-90 reserved for APIs --
127 * </code></pre>
128 * 
129 * All the result codes with the exception of success, compareFalse and
130 * compareTrue are to be treated as meaning the operation could not be completed
131 * in its entirety. Most of the result codes are based on problem indications
132 * from X.511 error data types. Result codes from 16 to 21 indicate an
133 * AttributeProblem, codes 32, 33, 34 and 36 indicate a NameProblem, codes 48,
134 * 49 and 50 indicate a SecurityProblem, codes 51 to 54 indicate a
135 * ServiceProblem, and codes 64 to 69 and 71 indicates an UpdateProblem. If a
136 * client receives a result code which is not listed above, it is to be treated
137 * as an unknown error condition. The majority of this javadoc was pasted in
138 * from RFC 2251. There's and expired draft out there on error codes which makes
139 * alot of sense: <a
140 * href="http://www.alternic.org/drafts/drafts-j-k/draft-just-ldapv3-rescodes-02.html"> 
141 * ietf (expired) draft</a> on error codes (read at your discretion).
142 * Result codes have been identified and split into categories:
143 * <ul>
144 * <li> Non-Erroneous: Five result codes that may be returned in LDAPResult are
145 * not used to indicate an error. </li>
146 * <li> General: returned only when no suitable specific error exists. </li>
147 * <li> Specific: Specific errors are used to indicate that a particular type of
148 * error has occurred. These error types are:
149 * <ul>
150 * <li> Name, </li>
151 * <li> Update, </li>
152 * <li> Attribute </li>
153 * <li> Security, and </li>
154 * <li> Service </li>
155 * </ul>
156 * </li>
157 * </ul>
158 * The result codes are also grouped according to the following LDAP operations
159 * which return responses:
160 * <ul>
161 * <li> bind </li>
162 * <li> search </li>
163 * <li> modify </li>
164 * <li> modifyDn </li>
165 * <li> add </li>
166 * <li> delete </li>
167 * <li> compare </li>
168 * <li> extended </li>
169 * </ul>
170 * 
171 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
172 */
173public enum ResultCodeEnum
174{
175    // ------------------------------------------------------------------------
176    // Public Static Constants: Enumeration values and names.
177    // ------------------------------------------------------------------------
178    // ------------------------------------------------------------------------
179    // Non Erroneous Codes:
180    //
181    // Five result codes that may be returned in LDAPResult are not used to
182    // indicate an error. These result codes are listed below. The first
183    // three codes, indicate to the client that no further action is required
184    // in order to satisfy their request. In contrast, the last two errors
185    // require further action by the client in order to complete their original
186    // operation request.
187    // ------------------------------------------------------------------------
188
189    /**
190     * It is returned when the client operation completed successfully without
191     * errors. This code is one of 5 result codes that may be returned in the
192     * LDAPResult which are not used to indicate an error. Applicable
193     * operations: all except for Compare. Result code type: Non-Erroneous
194     */
195    SUCCESS(0, "success"),
196
197    /**
198     * Servers sends this result code to LDAP v2 clients to refer them to
199     * another LDAP server. When sending this code to a client, the server
200     * includes a newline-delimited list of LDAP URLs that identify another LDAP
201     * server. If the client identifies itself as an LDAP v3 client in the
202     * request, servers send an REFERRAL result code instead of this result
203     * code.
204     */
205    PARTIAL_RESULTS(9, "partialResults"),
206
207    /**
208     * It is used to indicate that the result of a Compare operation is FALSE
209     * and does not indicate an error. 1 of 5 codes that do not indicate an
210     * error condition. Applicable operations: Compare. Result code type:
211     * Non-Erroneous
212     */
213    COMPARE_FALSE(5, "compareFalse"),
214
215    /**
216     * It is used to indicate that the result of a Compare operation is TRUE and
217     * does not indicate an error. 1 of 5 codes that do not indicate an error
218     * condition. Applicable operations: Compare. Result code type:
219     * Non-Erroneous
220     */
221    COMPARE_TRUE(6, "compareTrue"),
222
223    /**
224     * Rather than indicating an error, this result code is used to indicate
225     * that the server does not hold the target entry of the request but is able
226     * to provide alternative servers that may. A set of server(s) URLs may be
227     * returned in the referral field, which the client may subsequently query
228     * to attempt to complete their operation. 1 of 5 codes that do not indicate
229     * an error condition yet requires further action on behalf of the client to
230     * complete the request. This result code is new in LDAPv3. Applicable
231     * operations: all. Result code type: Non-Erroneous
232     */
233    REFERRAL(10, "referral"),
234
235    /**
236     * This result code is not an error response from the server, but rather, is
237     * a request for bind continuation. The server requires the client to send a
238     * new bind request, with the same SASL mechanism, to continue the
239     * authentication process [RFC2251, Section 4.2.3]. This result code is new
240     * in LDAPv3. Applicable operations: Bind. Result code type: Non-Erroneous
241     */
242    SASL_BIND_IN_PROGRESS(14, "saslBindInProgress"),
243
244    // ------------------------------------------------------------------------
245    // Problem Specific Error Codes:
246    //
247    // Specific errors are used to indicate that a particular type of error
248    // has occurred. These error types are Name, Update, Attribute, Security,
249    // and Service.
250    // ------------------------------------------------------------------------
251    // ------------------------------------------------------------------------
252    // Security Problem Specific Error Codes:
253    //
254    // A security error reports a problem in carrying out an operation for
255    // security reasons [X511, Section 12.7].
256    // ------------------------------------------------------------------------
257
258    /**
259     * This error code should be returned if the client requests, in a Bind
260     * request, an authentication method which is not supported or recognized by
261     * the server. Applicable operations: Bind. Result code type: Specific
262     * (Security)
263     */
264    AUTH_METHOD_NOT_SUPPORTED(7, "authMethodNotSupported"),
265
266    /**
267     * This error may be returned on a bind request if the server only accepts
268     * strong authentication or it may be returned when a client attempts an
269     * operation which requires the client to be strongly authenticated - for
270     * example Delete. This result code may also be returned in an unsolicited
271     * notice of disconnection if the server detects that an established
272     * underlying security association protecting communication between the
273     * client and server has unexpectedly failed or been compromised. [RFC2251,
274     * Section 4.4.1] Applicable operations: all. Result code type: Specific
275     * (Security)
276     */
277    STRONG_AUTH_REQUIRED(8, "strongAuthRequired"),
278
279    /**
280     * This error code may be returned if the session is not protected by a
281     * protocol which provides session confidentiality. For example, if the
282     * client did not establish a TLS connection using a cipher suite which
283     * provides confidentiality of the session before sending any other
284     * requests, and the server requires session confidentiality then the server
285     * may reject that request with a result code of confidentialityRequired.
286     * This error code is new in LDAPv3. Applicable operations: all. Result code
287     * type: Specific (Security)
288     */
289    CONFIDENTIALITY_REQUIRED(13, "confidentialityRequired"),
290
291    /**
292     * An alias was encountered in a situation where it was not allowed or where
293     * access was denied [X511, Section 12.5]. For example, if the client does
294     * not have read permission for the aliasedObjectName attribute and its
295     * value then the error aliasDereferencingProblem should be returned. [X511,
296     * Section 7.11.1.1] Notice that this error has similar meaning to
297     * INSUFFICIENT_ACCESS_RIGHTS (50), but is specific to Searching on an alias.
298     * Applicable operations: Search. Result code type: Specific (Security)
299     */
300    ALIAS_DEREFERENCING_PROBLEM(36, "aliasDereferencingProblem"),
301
302    /**
303     * This error should be returned by the server when the client has tried to
304     * use a method of authentication that is inappropriate, that is a method of
305     * authentication which the client is unable to use correctly. In other
306     * words, the level of security associated with the requestor's credentials
307     * is inconsistent with the level of protection requested, e.g. simple
308     * credentials were supplied while strong credentials were required [X511,
309     * Section 12.7]. Applicable operations: Bind. Result code type: Specific
310     * (Security)
311     */
312    INAPPROPRIATE_AUTHENTICATION(48, "inappropriateAuthentication"),
313
314    /**
315     * This error code is returned if the Dn or password used in a simple bind
316     * operation is incorrect, or if the Dn or password is incorrect for some
317     * other reason, e.g. the password has expired. This result code only
318     * applies to Bind operations -- it should not be returned for other
319     * operations if the client does not have sufficient permission to perform
320     * the requested operation - in this case the return code should be
321     * insufficientAccessRights. Applicable operations: Bind. Result code type:
322     * Specific (Security)
323     */
324    INVALID_CREDENTIALS(49, "invalidCredentials"),
325
326    /**
327     * The requestor does not have the right to carry out the requested
328     * operation [X511, Section 12.7]. Note that the more specific
329     * aliasDereferencingProblem is returned in case of a Search on an alias
330     * where the requestor has insufficientAccessRights. Applicable operations:
331     * all except for Bind. Result code type: Specific (Security)
332     */
333    INSUFFICIENT_ACCESS_RIGHTS(50, "insufficientAccessRights"),
334
335    // ------------------------------------------------------------------------
336    // Service Problem Specific Error Codes:
337    //
338    // A service error reports a problem related to the provision of the
339    // service [X511, Section 12.8].
340    // ------------------------------------------------------------------------
341
342    /**
343     * If the server requires that the client bind before browsing or modifying
344     * the directory, the server MAY reject a request other than binding,
345     * unbinding or an extended request with the "operationsError" result.
346     * [RFC2251, Section 4.2.1] Applicable operations: all except Bind. Result
347     * code type: Specific (Service)
348     */
349    OPERATIONS_ERROR(1, "operationsError"),
350
351    /**
352     * A protocol error should be returned by the server when an invalid or
353     * malformed request is received from the client. This may be a request that
354     * is not recognized as an LDAP request, for example, if a nonexistent
355     * operation were specified in LDAPMessage. As well, it may be the result of
356     * a request that is missing a required parameter, such as a search filter
357     * in a search request. If the server can return an error, which is more
358     * specific than protocolError, then this error should be returned instead.
359     * For example if the server does not recognize the authentication method
360     * requested by the client then the error authMethodNotSupported should be
361     * returned instead of protocolError. The server may return details of the
362     * error in the error string. Applicable operations: all. Result code type:
363     * Specific (Service)
364     */
365    PROTOCOL_ERROR(2, "protocolError"),
366
367    /**
368     * This error should be returned when the time to perform an operation has
369     * exceeded either the time limit specified by the client (which may only be
370     * set by the client in a search operation) or the limit specified by the
371     * server. If the time limit is exceeded on a search operation then the
372     * result is an arbitrary selection of the accumulated results [X511,
373     * Section 7.5]. Note that an arbitrary selection of results may mean that
374     * no results are returned to the client. If the LDAP server is a front end
375     * for an X.500 server, any operation that is chained may exceed the
376     * timelimit, therefore clients can expect to receive timelimitExceeded for
377     * all operations. For stand alone LDAP- Servers that do not implement
378     * chaining it is unlikely that operations other than search operations will
379     * exceed the defined timelimit. Applicable operations: all. Result code
380     * type: Specific (Service)
381     */
382    TIME_LIMIT_EXCEEDED(3, "timeLimitExceeded"),
383
384    /**
385     * This error should be returned when the number of results generated by a
386     * search exceeds the maximum number of results specified by either the
387     * client or the server. If the size limit is exceeded then the results of a
388     * search operation will be an arbitrary selection of the accumulated
389     * results, equal in number to the size limit [X511, Section 7.5].
390     * Applicable operations: Search. Result code type: Specific (Service)
391     */
392    SIZE_LIMIT_EXCEEDED(4, "sizeLimitExceeded"),
393
394    /**
395     * The server has reached some limit set by an administrative authority, and
396     * no partial results are available to return to the user [X511, Section
397     * 12.8]. For example, there may be an administrative limit to the number of
398     * entries a server will check when gathering potential search result
399     * candidates [Net]. This error code is new in LDAPv3. Applicable
400     * operations: all. Result code type: Specific (Service)
401     */
402    ADMIN_LIMIT_EXCEEDED(11, "adminLimitExceeded"),
403
404    /**
405     * The server was unable to satisfy the request because one or more critical
406     * extensions were not available [X511, Section 12.8]. This error is
407     * returned, for example, when a control submitted with a request is marked
408     * critical but is not recognized by a server or when such a control is not
409     * appropriate for the operation type. [RFC2251 section 4.1.12]. This error
410     * code is new in LDAPv3. Applicable operations: all. Result code type:
411     * Specific (Service)
412     */
413    UNAVAILABLE_CRITICAL_EXTENSION(12, "unavailableCriticalExtension"),
414
415    /**
416     * This error code may be returned if the server is unable to process the
417     * client's request at this time. This implies that if the client retries
418     * the request shortly the server will be able to process it then.
419     * Applicable operations: all. Result code type: Specific (Service)
420     */
421    BUSY(51, "busy"),
422
423    /**
424     * This error code is returned when the server is unavailable to process the
425     * client's request. This usually means that the LDAP server is shutting
426     * down [RFC2251, Section 4.2.3]. Applicable operations: all. Result code
427     * type: Specific (Service)
428     */
429    UNAVAILABLE(52, "unavailable"),
430
431    /**
432     * This error code should be returned by the server when a client request is
433     * properly formed but which the server is unable to complete due to
434     * server-defined restrictions. For example, the server, or some part of it,
435     * is not prepared to execute this request, e.g. because it would lead to
436     * excessive consumption of resources or violates the policy of an
437     * Administrative Authority involved [X511, Section 12.8]. If the server is
438     * able to return a more specific error code such as adminLimitExceeded it
439     * should. This error may also be returned if the client attempts to modify
440     * attributes which can not be modified by users, e.g., operational
441     * attributes such as creatorsName or createTimestamp [X511, Section 7.12].
442     * If appropriate, details of the error should be provided in the error
443     * message. Applicable operations: all. Result code type: Specific (Service)
444     */
445    UNWILLING_TO_PERFORM(53, "unwillingToPerform"),
446
447    /**
448     * This error may be returned by the server if it detects an alias or
449     * referral loop, and is unable to satisfy the client's request. Applicable
450     * operations: all. Result code type: Specific (Service)
451     */
452    LOOP_DETECT(54, "loopDetect"),
453
454    // ------------------------------------------------------------------------
455    // Attribute Problem Specific Error Codes:
456    //
457    // An attribute error reports a problem related to an attribute specified
458    // by the client in their request message.
459    // ------------------------------------------------------------------------
460
461    /**
462     * This error may be returned if the attribute specified as an argument of
463     * the operation does not exist in the entry. Applicable operations: Modify,
464     * Compare. Result code type: Specific (Attribute)
465     */
466    NO_SUCH_ATTRIBUTE(16, "noSuchAttribute"),
467
468    /**
469     * This error may be returned if the specified attribute is unrecognized by
470     * the server, since it is not present in the server's defined schema. If
471     * the server doesn't recognize an attribute specified in a search request
472     * as the attribute to be returned the server should not return an error in
473     * this case - it should just return values for the requested attributes it
474     * does recognize. Note that this result code only applies to the Add and
475     * Modify operations [X.511, Section 12.4]. Applicable operations: Modify,
476     * Add. Result code type: Specific (Attribute)
477     */
478    UNDEFINED_ATTRIBUTE_TYPE(17, "undefinedAttributeType"),
479
480    /**
481     * An attempt was made, e.g., in a filter, to use a matching rule not
482     * defined for the attribute type concerned [X511, Section 12.4]. Applicable
483     * operations: Search. Result code type: Specific (Attribute)
484     */
485    INAPPROPRIATE_MATCHING(18, "inappropriateMatching"),
486
487    /**
488     * This error should be returned by the server if an attribute value
489     * specified by the client violates the constraints placed on the attribute
490     * as it was defined in the DSA - this may be a size constraint or a
491     * constraint on the content. Applicable operations: Modify, Add, ModifyDN.
492     * Result code type: Specific (Attribute)
493     */
494    CONSTRAINT_VIOLATION(19, "constraintViolation"),
495
496    /**
497     * This error should be returned by the server if the value specified by the
498     * client already exists within the attribute. Applicable operations:
499     * Modify, Add. Result code type: Specific (Attribute)
500     */
501    ATTRIBUTE_OR_VALUE_EXISTS(20, "attributeOrValueExists"),
502
503    /**
504     * This error should be returned by the server if the attribute syntax for
505     * the attribute value, specified as an argument of the operation, is
506     * unrecognized or invalid. Applicable operations: Modify, Add. Result code
507     * type: Specific (Attribute)
508     */
509    INVALID_ATTRIBUTE_SYNTAX(21, "invalidAttributeSyntax"),
510
511    // ------------------------------------------------------------------------
512    // Name Problem Specific Error Codes:
513    //
514    // A name error reports a problem related to the distinguished name
515    // provided as an argument to an operation [X511, Section 12.5].
516    //
517    // For result codes of noSuchObject, aliasProblem, invalidDNSyntax and
518    // aliasDereferencingProblem (see Section 5.2.2.3.7), the matchedDN
519    // field is set to the name of the lowest entry (object or alias) in the
520    // directory that was matched. If no aliases were dereferenced while
521    // attempting to locate the entry, this will be a truncated form of the
522    // name provided, or if aliases were dereferenced, of the resulting
523    // name, as defined in section 12.5 of X.511 [X511]. The matchedDN field
524    // is to be set to a zero length string with all other result codes
525    // [RFC2251, Section 4.1.10].
526    // ------------------------------------------------------------------------
527
528    /**
529     * This error should only be returned if the target object cannot be found.
530     * For example, in a search operation if the search base can not be located
531     * in the DSA the server should return NO_SUCH_OBJECT. If, however, the search
532     * base is found but does not match the search filter, success, with no
533     * resultant objects, should be returned instead of NO_SUCH_OBJECT. If the
534     * LDAP server is a front end for an X.500 DSA then NO_SUCH_OBJECT may also be
535     * returned if discloseOnError is not granted for an entry and the client
536     * does not have permission to view or modify the entry. Applicable
537     * operations: all except for Bind. Result code type: Specific (Name)
538     */
539    NO_SUCH_OBJECT(32, "noSuchObject"),
540
541    /**
542     * An alias has been dereferenced which names no object [X511, Section 12.5]
543     * Applicable operations: Search. Result code type: Specific (Name)
544     */
545    ALIAS_PROBLEM(33, "aliasProblem"),
546
547    /**
548     * This error should be returned by the server if the Dn syntax is
549     * incorrect. It should not be returned if the Dn is correctly formed but
550     * represents an entry which is not permitted by the structure rules at the
551     * DSA ; in this case namingViolation should be returned instead. Applicable
552     * operations: all. Result code type: Specific (Name)
553     */
554    INVALID_DN_SYNTAX(34, "invalidDNSyntax"),
555
556    // ------------------------------------------------------------------------
557    // Update Problem Specific Error Codes:
558    //
559    // An update error reports problems related to attempts to add, delete, or
560    // modify information in the DIB [X511, Section 12.9].
561    // ------------------------------------------------------------------------
562
563    /**
564     * The attempted addition or modification would violate the structure rules
565     * of the DIT as defined in the directory schema and X.501. That is, it
566     * would place an entry as the subordinate of an alias entry, or in a region
567     * of the DIT not permitted to a member of its object class, or would define
568     * an Rdn for an entry to include a forbidden attribute type [X511, Section
569     * 12.9]. Applicable operations: Add, ModifyDN. Result code type: Specific
570     * (Update)
571     */
572    NAMING_VIOLATION(64, "namingViolation"),
573
574    /**
575     * This error should be returned if the operation requested by the user
576     * would violate the objectClass requirements for the entry if carried out.
577     * On an add or modify operation this would result from trying to add an
578     * object class without a required attribute, or by trying to add an
579     * attribute which is not permitted by the current object class set in the
580     * entry. On a modify operation this may result from trying to remove a
581     * required attribute without removing the associated auxiliary object
582     * class, or by attempting to remove an object class while the attributes it
583     * permits are still present. Applicable operations: Add, Modify, ModifyDN.
584     * Result code type: Specific (Update)
585     */
586    OBJECT_CLASS_VIOLATION(65, "objectClassViolation"),
587
588    /**
589     * This error should be returned if the client attempts to perform an
590     * operation which is permitted only on leaf entries - e.g., if the client
591     * attempts to delete a non-leaf entry. If the directory does not permit
592     * ModifyDN for non-leaf entries then this error may be returned if the
593     * client attempts to change the Dn of a non-leaf entry. (Note that 1988
594     * edition X.500 servers only permitted change of the Rdn of an entry's Dn
595     * [X.511, Section 11.4.1]). Applicable operations: Delete, ModifyDN. Result
596     * code type: Specific (Update)
597     */
598    NOT_ALLOWED_ON_NON_LEAF(66, "notAllowedOnNonLeaf"),
599
600    /**
601     * The attempted operation would affect the Rdn (e.g., removal of an
602     * attribute which is a part of the Rdn) [X511, Section 12.9]. If the client
603     * attempts to remove from an entry any of its distinguished values, those
604     * values which form the entry's relative distinguished name the server
605     * should return the error notAllowedOnRDN. [RFC2251, Section 4.6]
606     * Applicable operations: Modify. Result code type: Specific (Update)
607     */
608    NOT_ALLOWED_ON_RDN(67, "notAllowedOnRDN"),
609
610    /**
611     * This error should be returned by the server when the client attempts to
612     * add an entry which already exists, or if the client attempts to rename an
613     * entry with the name of an entry which exists. Applicable operations: Add,
614     * ModifyDN. Result code type: Specific (Update)
615     */
616    ENTRY_ALREADY_EXISTS(68, "entryAlreadyExists"),
617
618    /**
619     * An operation attempted to modify an object class that should not be
620     * modified, e.g., the structural object class of an entry. Some servers may
621     * not permit object class modifications, especially modifications to the
622     * structural object class since this may change the entry entirely, name
623     * forms, structure rules etc. [X.511, Section 12.9]. Applicable operations:
624     * Modify. Result code type: Specific (Update)
625     */
626    OBJECT_CLASS_MODS_PROHIBITED(69, "objectClassModsProhibited"),
627
628    /**
629     * This error code should be returned to indicate that the operation could
630     * not be performed since it affects more than one DSA. This error code is
631     * new for LDAPv3. X.500 restricts the ModifyDN operation to only affect
632     * entries that are contained within a single server. If the LDAP server is
633     * mapped onto DAP, then this restriction will apply, and the resultCode
634     * affectsMultipleDSAs will be returned if this error occurred. In general
635     * clients MUST NOT expect to be able to perform arbitrary movements of
636     * entries and subtrees between servers [RFC2251, Section 4.9]. Applicable
637     * operations: ModifyDN. Result code type: Specific (Update)
638     */
639    AFFECTS_MULTIPLE_DSAS(71, "affectsMultipleDSAs"),
640
641    // ------------------------------------------------------------------------
642    // General Error Codes:
643    //
644    // A general error code typically specifies an error condition for which
645    // there is no suitable specific error code. If the server can return an
646    // error, which is more specific than the following general errors, then
647    // the specific error should be returned instead.
648    // ------------------------------------------------------------------------
649
650    /**
651     * This error code should be returned only if no other error code is
652     * suitable. Use of this error code should be avoided if possible. Details
653     * of the error should be provided in the error message. Applicable
654     * operations: all. Result code type: General
655     */
656    OTHER(80, "other"),
657
658    /**
659     * This error code is returned when an operation has been canceled using
660     * the Cancel extended operation. 
661     */
662    CANCELED(118, "canceled"),
663
664    /**
665     * This error code is returned if the server has no knowledge of
666     * the operation requested for cancelation.
667     */
668    NO_SUCH_OPERATION(119, "noSuchOperation"),
669
670    /**
671     * The tooLate resultCode is returned to indicate that it is too late to
672     * cancel the outstanding operation.  For example, the server may return
673     * tooLate for a request to cancel an outstanding modify operation which
674     * has already committed updates to the underlying data store.
675     */
676    TOO_LATE(120, "tooLate"),
677
678    /**
679     * The cannotCancel resultCode is returned if the identified operation
680     * does not support cancelation or the cancel operation could not be
681     * performed.  The following classes of operations are not cancelable:
682     *
683     * -  operations which have no response,
684     *
685     * -  operations which create, alter, or destroy authentication and/or
686     *    authorization associations,
687     *
688     * -  operations which establish, alter, or tear-down security services,
689     *    and
690     *
691     * -  operations which abandon or cancel other operations.
692     */
693    CANNOT_CANCEL(121, "cannotCancel"),
694
695    /**
696     * The server may return this result code on the initial content poll
697     * if it is safe to do so when it is unable to perform the operation
698     * due to various reasons. For more detailed explanation refer 
699     * <a href="http://www.faqs.org/rfcs/rfc4533.html">RFC 4533 (a.k.a syncrepl)</a>
700     */
701    E_SYNC_REFRESH_REQUIRED(4096, "eSyncRefreshRequired"),
702
703    /**
704     * A unknown result code to cover all the other cases
705     */
706    // -- 15 unused --
707    // -- 22-31 unused --
708    // -- 35 reserved for undefined isLeaf --
709    // -- 37-47 unused --
710    // -- 55-63 unused --
711    // -- 70 reserved for CLDAP --
712    // -- 72-79 unused --
713    // -- 81-90 reserved for APIs --
714    UNKNOWN(122, "unknown");
715
716    /** Stores the integer value of each element of the enumeration */
717    private int value;
718
719    /** Stores the description of each element of the enumeration */
720    private String message;
721
722
723    /**
724     * Private construct so no other instances can be created other than the
725     * public static constants in this class.
726     * 
727     * @param value the integer value of the enumeration.
728     * @param message the description of the enumeration.
729     */
730    private ResultCodeEnum( int value, String message )
731    {
732        this.value = value;
733        this.message = message;
734    }
735
736
737    /**
738     * @return The value associated with the current element.
739     */
740    public int getValue()
741    {
742        return value;
743    }
744
745
746    /**
747     * @return The description associated with the current element.
748     */
749    public String getMessage()
750    {
751        return message;
752    }
753
754    private static final Set<ResultCodeEnum> EMPTY_RESULT_CODE_SET = new HashSet<ResultCodeEnum>();
755
756    // ------------------------------------------------------------------------
757    // Error Codes Grouped Into Categories & Static Accessors
758    // ------------------------------------------------------------------------
759
760    /**
761     * Five result codes that may be returned in LDAPResult are not used to
762     * indicate an error. The first three codes, indicate to the client that no
763     * further action is required in order to satisfy their request. In
764     * contrast, the last two errors require further action by the client in
765     * order to complete their original operation request. The set contains:
766     * <ul>
767     * <li><a href="#SUCCESS">SUCCESS</a></li>
768     * <li><a href="#COMPARETRUE">COMPARETRUE</a></li>
769     * <li><a href="#COMPAREFALSE">COMPAREFALSE</a></li>
770     * <li><a href="#REFERRAL">REFERRAL</a></li>
771     * <li><a href="#SASL_BIND_IN_PROGRESS">SASL_BIND_IN_PROGRESS</a></li>
772     * </ul>
773     */
774    private static final Set<ResultCodeEnum> NON_ERRONEOUS_CODES;
775
776    static
777    {
778        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
779        set.add( ResultCodeEnum.SUCCESS );
780        set.add( ResultCodeEnum.COMPARE_TRUE );
781        set.add( ResultCodeEnum.COMPARE_FALSE );
782        set.add( ResultCodeEnum.REFERRAL );
783        set.add( ResultCodeEnum.SASL_BIND_IN_PROGRESS );
784        set.add( ResultCodeEnum.CANCELED );
785        NON_ERRONEOUS_CODES = Collections.unmodifiableSet( set );
786    }
787
788    /**
789     * A set of result code enumerations that may result from bind operations.
790     * The set contains:
791     * <ul>
792     * <li><a href="#BUSY">BUSY</a></li>
793     * <li><a href="#OTHER">OTHER</a></li>
794     * <li><a href="#SUCCESS">SUCCESS</a></li>
795     * <li><a href="#REFERRAL">REFERRAL</a></li>
796     * <li><a href="#LOOP_DETECT">LOOP_DETECT</a></li>
797     * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
798     * <li><a href="#PROTOCOL_ERROR">PROTOCOL_ERROR</a></li>
799     * <li><a href="#INVALID_DN_SYNTAX">INVALID_DN_SYNTAX</a></li>
800     * <li><a href="#TIME_LIMIT_EXCEEDED">TIME_LIMIT_EXCEEDED</a></li>
801     * <li><a href="#ADMIN_LIMIT_EXCEEDED">ADMIN_LIMIT_EXCEEDED</a></li>
802     * <li><a href="#UNWILLING_TO_PERFORM">UNWILLING_TO_PERFORM</a></li>
803     * <li><a href="#SASL_BIND_IN_PROGRESS">SASL_BIND_IN_PROGRESS</a></li>
804     * <li><a href="#STRONG_AUTH_REQUIRED">STRONG_AUTH_REQUIRED</a></li>
805     * <li><a href="#INVALID_CREDENTIALS">INVALID_CREDENTIALS</a></li>
806     * <li><a href="#AUTH_METHOD_NOT_SUPPORTED">AUTH_METHOD_NOT_SUPPORTED</a></li>
807     * <li><a href="#CONFIDENTIALITY_REQUIRED">CONFIDENTIALITY_REQUIRED</a></li>
808     * <li><a href="#INAPPROPRIATE_AUTHENTICATION">INAPPROPRIATE_AUTHENTICATION</a></li>
809     * <li><a href="#UNAVAILABLE_CRITICAL_EXTENSION">UNAVAILABLE_CRITICAL_EXTENSION</a></li>
810     * </ul>
811     */
812    private static final Set<ResultCodeEnum> BIND_CODES;
813
814    static
815    {
816        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
817        set.add( ResultCodeEnum.BUSY );
818        set.add( ResultCodeEnum.OTHER );
819        set.add( ResultCodeEnum.SUCCESS );
820        set.add( ResultCodeEnum.REFERRAL );
821        set.add( ResultCodeEnum.LOOP_DETECT );
822        set.add( ResultCodeEnum.UNAVAILABLE );
823        set.add( ResultCodeEnum.PROTOCOL_ERROR );
824        set.add( ResultCodeEnum.INVALID_DN_SYNTAX );
825        set.add( ResultCodeEnum.TIME_LIMIT_EXCEEDED );
826        set.add( ResultCodeEnum.ADMIN_LIMIT_EXCEEDED );
827        set.add( ResultCodeEnum.UNWILLING_TO_PERFORM );
828        set.add( ResultCodeEnum.SASL_BIND_IN_PROGRESS );
829        set.add( ResultCodeEnum.STRONG_AUTH_REQUIRED );
830        set.add( ResultCodeEnum.INVALID_CREDENTIALS );
831        set.add( ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED );
832        set.add( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
833        set.add( ResultCodeEnum.INAPPROPRIATE_AUTHENTICATION );
834        set.add( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
835        set.add( ResultCodeEnum.CANCELED );
836        BIND_CODES = Collections.unmodifiableSet( set );
837    }
838
839    /**
840     * A set of result code enumerations that may result from search operations.
841     * The set contains:
842     * <ul>
843     * <li><a href="#BUSY">BUSY</a></li>
844     * <li><a href="#OTHER">OTHER</a></li>
845     * <li><a href="#SUCCESS">SUCCESS</a></li>
846     * <li><a href="#REFERRAL">REFERRAL</a></li>
847     * <li><a href="#LOOP_DETECT">LOOP_DETECT</a></li>
848     * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
849     * <li><a href="#NO_SUCH_OBJECT">NO_SUCH_OBJECT</a></li>
850     * <li><a href="#ALIAS_PROBLEM">ALIAS_PROBLEM</a></li>
851     * <li><a href="#PROTOCOL_ERROR">PROTOCOL_ERROR</a></li>
852     * <li><a href="#INVALID_DN_SYNTAX">INVALID_DN_SYNTAX</a></li>
853     * <li><a href="#SIZE_LIMIT_EXCEEDED">SIZE_LIMIT_EXCEEDED</a></li>
854     * <li><a href="#TIME_LIMIT_EXCEEDED">TIME_LIMIT_EXCEEDED</a></li>
855     * <li><a href="#ADMIN_LIMIT_EXCEEDED">ADMIN_LIMIT_EXCEEDED</a></li>
856     * <li><a href="#STRONG_AUTH_REQUIRED">STRONG_AUTH_REQUIRED</a></li>
857     * <li><a href="#UNWILLING_TO_PERFORM">UNWILLING_TO_PERFORM</a></li>
858     * <li><a href="#INAPPROPRIATE_MATCHING">INAPPROPRIATE_MATCHING</a></li>
859     * <li><a href="#CONFIDENTIALITY_REQUIRED">CONFIDENTIALITY_REQUIRED</a></li>
860     * <li><a href="#INSUFFICIENT_ACCESS_RIGHTS">INSUFFICIENT_ACCESS_RIGHTS</a></li>
861     * <li><a href="#ALIAS_DEREFERENCING_PROBLEM">ALIAS_DEREFERENCING_PROBLEM</a></li>
862     * <li><a href="#UNAVAILABLE_CRITICAL_EXTENSION">UNAVAILABLE_CRITICAL_EXTENSION</a></li>
863     * </ul>
864     */
865    private static final Set<ResultCodeEnum> SEARCH_CODES;
866
867    static
868    {
869        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
870        set.add( ResultCodeEnum.BUSY );
871        set.add( ResultCodeEnum.OTHER );
872        set.add( ResultCodeEnum.SUCCESS );
873        set.add( ResultCodeEnum.REFERRAL );
874        set.add( ResultCodeEnum.LOOP_DETECT );
875        set.add( ResultCodeEnum.UNAVAILABLE );
876        set.add( ResultCodeEnum.NO_SUCH_OBJECT );
877        set.add( ResultCodeEnum.ALIAS_PROBLEM );
878        set.add( ResultCodeEnum.PROTOCOL_ERROR );
879        set.add( ResultCodeEnum.INVALID_DN_SYNTAX );
880        set.add( ResultCodeEnum.SIZE_LIMIT_EXCEEDED );
881        set.add( ResultCodeEnum.TIME_LIMIT_EXCEEDED );
882        set.add( ResultCodeEnum.ADMIN_LIMIT_EXCEEDED );
883        set.add( ResultCodeEnum.STRONG_AUTH_REQUIRED );
884        set.add( ResultCodeEnum.UNWILLING_TO_PERFORM );
885        set.add( ResultCodeEnum.INAPPROPRIATE_MATCHING );
886        set.add( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
887        set.add( ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS );
888        set.add( ResultCodeEnum.ALIAS_DEREFERENCING_PROBLEM );
889        set.add( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
890        set.add( ResultCodeEnum.CANCELED );
891        set.add( ResultCodeEnum.E_SYNC_REFRESH_REQUIRED );
892        SEARCH_CODES = Collections.unmodifiableSet( set );
893    }
894
895    /**
896     * A set of result code enumerations that may result from modify operations.
897     * The set contains:
898     * <ul>
899     * <li><a href="#BUSY">BUSY</a></li>
900     * <li><a href="#OTHER">OTHER</a></li>
901     * <li><a href="#SUCCESS">SUCCESS</a></li>
902     * <li><a href="#REFERRAL">REFERRAL</a></li>
903     * <li><a href="#LOOP_DETECT">LOOP_DETECT</a></li>
904     * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
905     * <li><a href="#NO_SUCH_OBJECT">NO_SUCH_OBJECT</a></li>
906     * <li><a href="#PROTOCOL_ERROR">PROTOCOL_ERROR</a></li>
907     * <li><a href="#INVALID_DN_SYNTAX">INVALID_DN_SYNTAX</a></li>
908     * <li><a href="#NOT_ALLOWED_ON_RDN">NOT_ALLOWED_ON_RDN</a></li>
909     * <li><a href="#NO_SUCH_ATTRIBUTE">NO_SUCH_ATTRIBUTE</a></li>
910     * <li><a href="#TIME_LIMIT_EXCEEDED">TIME_LIMIT_EXCEEDED</a></li>
911     * <li><a href="#ADMIN_LIMIT_EXCEEDED">ADMIN_LIMIT_EXCEEDED</a></li>
912     * <li><a href="#STRONG_AUTH_REQUIRED">STRONG_AUTH_REQUIRED</a></li>
913     * <li><a href="#UNWILLING_TO_PERFORM">UNWILLING_TO_PERFORM</a></li>
914     * <li><a href="#CONSTRAINT_VIOLATION">CONSTRAINT_VIOLATION</a></li>
915     * <li><a href="#OBJECT_CLASS_VIOLATION">OBJECT_CLASS_VIOLATION</a></li>
916     * <li><a href="#INVALID_ATTRIBUTE_SYNTAX">INVALID_ATTRIBUTE_SYNTAX</a></li>
917     * <li><a href="#UNDEFINED_ATTRIBUTE_TYPE">UNDEFINED_ATTRIBUTE_TYPE</a></li>
918     * <li><a href="#ATTRIBUTE_OR_VALUE_EXISTS">ATTRIBUTE_OR_VALUE_EXISTS</a></li>
919     * <li><a href="#CONFIDENTIALITY_REQUIRED">CONFIDENTIALITY_REQUIRED</a></li>
920     * <li><a href="#INSUFFICIENT_ACCESS_RIGHTS">INSUFFICIENT_ACCESS_RIGHTS</a></li>
921     * <li><a href="#OBJECT_CLASS_MODS_PROHIBITED">OBJECT_CLASS_MODS_PROHIBITED</a></li>
922     * <li><a href="#UNAVAILABLE_CRITICAL_EXTENSION">UNAVAILABLE_CRITICAL_EXTENSION</a></li>
923     * </ul>
924     */
925    private static final Set<ResultCodeEnum> MODIFY_CODES;
926
927    static
928    {
929        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
930        set.add( ResultCodeEnum.BUSY );
931        set.add( ResultCodeEnum.OTHER );
932        set.add( ResultCodeEnum.SUCCESS );
933        set.add( ResultCodeEnum.REFERRAL );
934        set.add( ResultCodeEnum.LOOP_DETECT );
935        set.add( ResultCodeEnum.UNAVAILABLE );
936        set.add( ResultCodeEnum.NO_SUCH_OBJECT );
937        set.add( ResultCodeEnum.PROTOCOL_ERROR );
938        set.add( ResultCodeEnum.INVALID_DN_SYNTAX );
939        set.add( ResultCodeEnum.NOT_ALLOWED_ON_RDN );
940        set.add( ResultCodeEnum.NO_SUCH_ATTRIBUTE );
941        set.add( ResultCodeEnum.TIME_LIMIT_EXCEEDED );
942        set.add( ResultCodeEnum.ADMIN_LIMIT_EXCEEDED );
943        set.add( ResultCodeEnum.STRONG_AUTH_REQUIRED );
944        set.add( ResultCodeEnum.UNWILLING_TO_PERFORM );
945        set.add( ResultCodeEnum.CONSTRAINT_VIOLATION );
946        set.add( ResultCodeEnum.OBJECT_CLASS_VIOLATION );
947        set.add( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX );
948        set.add( ResultCodeEnum.UNDEFINED_ATTRIBUTE_TYPE );
949        set.add( ResultCodeEnum.ATTRIBUTE_OR_VALUE_EXISTS );
950        set.add( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
951        set.add( ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS );
952        set.add( ResultCodeEnum.OBJECT_CLASS_MODS_PROHIBITED );
953        set.add( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
954        set.add( ResultCodeEnum.CANCELED );
955        MODIFY_CODES = Collections.unmodifiableSet( set );
956    }
957
958    /**
959     * A set of result code enumerations that may result from add operations.
960     * The set contains:
961     * <ul>
962     * <li><a href="#BUSY">BUSY</a></li>
963     * <li><a href="#OTHER">OTHER</a></li>
964     * <li><a href="#SUCCESS">SUCCESS</a></li>
965     * <li><a href="#REFERRAL">REFERRAL</a></li>
966     * <li><a href="#LOOP_DETECT">LOOP_DETECT</a></li>
967     * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
968     * <li><a href="#NO_SUCH_OBJECT">NO_SUCH_OBJECT</a></li>
969     * <li><a href="#PROTOCOL_ERROR">PROTOCOL_ERROR</a></li>
970     * <li><a href="#NAMING_VIOLATION">NAMING_VIOLATION</a></li>
971     * <li><a href="#INVALID_DN_SYNTAX">INVALID_DN_SYNTAX</a></li>
972     * <li><a href="#TIME_LIMIT_EXCEEDED">TIME_LIMIT_EXCEEDED</a></li>
973     * <li><a href="#ADMIN_LIMIT_EXCEEDED">ADMIN_LIMIT_EXCEEDED</a></li>
974     * <li><a href="#STRONG_AUTH_REQUIRED">STRONG_AUTH_REQUIRED</a></li>
975     * <li><a href="#UNWILLING_TO_PERFORM">UNWILLING_TO_PERFORM</a></li>
976     * <li><a href="#ENTRY_ALREADY_EXISTS">ENTRY_ALREADY_EXISTS</a></li>
977     * <li><a href="#CONSTRAINT_VIOLATION">CONSTRAINT_VIOLATION</a></li>
978     * <li><a href="#OBJECT_CLASS_VIOLATION">OBJECT_CLASS_VIOLATION</a></li>
979     * <li><a href="#INVALID_ATTRIBUTE_SYNTAX">INVALID_ATTRIBUTE_SYNTAX</a></li>
980     * <li><a href="#ATTRIBUTE_OR_VALUE_EXISTS">ATTRIBUTE_OR_VALUE_EXISTS</a></li>
981     * <li><a href="#UNDEFINED_ATTRIBUTE_TYPE">UNDEFINED_ATTRIBUTE_TYPE</a></li>
982     * <li><a href="#CONFIDENTIALITY_REQUIRED">CONFIDENTIALITY_REQUIRED</a></li>
983     * <li><a href="#INSUFFICIENT_ACCESS_RIGHTS">INSUFFICIENT_ACCESS_RIGHTS</a></li>
984     * <li><a href="#UNAVAILABLE_CRITICAL_EXTENSION">UNAVAILABLE_CRITICAL_EXTENSION</a></li>
985     * </ul>
986     */
987    private static final Set<ResultCodeEnum> ADD_CODES;
988
989    static
990    {
991        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
992        set.add( ResultCodeEnum.BUSY );
993        set.add( ResultCodeEnum.OTHER );
994        set.add( ResultCodeEnum.SUCCESS );
995        set.add( ResultCodeEnum.REFERRAL );
996        set.add( ResultCodeEnum.LOOP_DETECT );
997        set.add( ResultCodeEnum.UNAVAILABLE );
998        set.add( ResultCodeEnum.NO_SUCH_OBJECT );
999        set.add( ResultCodeEnum.PROTOCOL_ERROR );
1000        set.add( ResultCodeEnum.NAMING_VIOLATION );
1001        set.add( ResultCodeEnum.INVALID_DN_SYNTAX );
1002        set.add( ResultCodeEnum.TIME_LIMIT_EXCEEDED );
1003        set.add( ResultCodeEnum.ADMIN_LIMIT_EXCEEDED );
1004        set.add( ResultCodeEnum.STRONG_AUTH_REQUIRED );
1005        set.add( ResultCodeEnum.UNWILLING_TO_PERFORM );
1006        set.add( ResultCodeEnum.ENTRY_ALREADY_EXISTS );
1007        set.add( ResultCodeEnum.CONSTRAINT_VIOLATION );
1008        set.add( ResultCodeEnum.OBJECT_CLASS_VIOLATION );
1009        set.add( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX );
1010        set.add( ResultCodeEnum.ATTRIBUTE_OR_VALUE_EXISTS );
1011        set.add( ResultCodeEnum.UNDEFINED_ATTRIBUTE_TYPE );
1012        set.add( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
1013        set.add( ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS );
1014        set.add( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
1015        set.add( ResultCodeEnum.CANCELED );
1016        ADD_CODES = Collections.unmodifiableSet( set );
1017    }
1018
1019    /**
1020     * A set of result code enumerations that may result from delete operations.
1021     * The set may contain:
1022     * <ul>
1023     * <li><a href="#BUSY">BUSY</a></li>
1024     * <li><a href="#OTHER">OTHER</a></li>
1025     * <li><a href="#SUCCESS">SUCCESS</a></li>
1026     * <li><a href="#REFERRAL">REFERRAL</a></li>
1027     * <li><a href="#LOOP_DETECT">LOOP_DETECT</a></li>
1028     * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
1029     * <li><a href="#NO_SUCH_OBJECT">NO_SUCH_OBJECT</a></li>
1030     * <li><a href="#PROTOCOL_ERROR">PROTOCOL_ERROR</a></li>
1031     * <li><a href="#INVALID_DN_SYNTAX">INVALID_DN_SYNTAX</a></li>
1032     * <li><a href="#TIME_LIMIT_EXCEEDED">TIME_LIMIT_EXCEEDED</a></li>
1033     * <li><a href="#ADMIN_LIMIT_EXCEEDED">ADMIN_LIMIT_EXCEEDED</a></li>
1034     * <li><a href="#STRONG_AUTH_REQUIRED">STRONG_AUTH_REQUIRED</a></li>
1035     * <li><a href="#UNWILLING_TO_PERFORM">UNWILLING_TO_PERFORM</a></li>
1036     * <li><a href="#NOT_ALLOWED_ON_NON_LEAF">NOT_ALLOWED_ON_NON_LEAF</a></li>
1037     * <li><a href="#CONFIDENTIALITY_REQUIRED">CONFIDENTIALITY_REQUIRED</a></li>
1038     * <li><a href="#INSUFFICIENT_ACCESS_RIGHTS">INSUFFICIENT_ACCESS_RIGHTS</a></li>
1039     * <li><a href="#UNAVAILABLE_CRITICAL_EXTENSION">UNAVAILABLE_CRITICAL_EXTENSION</a></li>
1040     * </ul>
1041     */
1042    private static final Set<ResultCodeEnum> DELETE_CODES;
1043
1044    static
1045    {
1046        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1047        set.add( ResultCodeEnum.BUSY );
1048        set.add( ResultCodeEnum.OTHER );
1049        set.add( ResultCodeEnum.SUCCESS );
1050        set.add( ResultCodeEnum.REFERRAL );
1051        set.add( ResultCodeEnum.LOOP_DETECT );
1052        set.add( ResultCodeEnum.UNAVAILABLE );
1053        set.add( ResultCodeEnum.NO_SUCH_OBJECT );
1054        set.add( ResultCodeEnum.PROTOCOL_ERROR );
1055        set.add( ResultCodeEnum.INVALID_DN_SYNTAX );
1056        set.add( ResultCodeEnum.TIME_LIMIT_EXCEEDED );
1057        set.add( ResultCodeEnum.ADMIN_LIMIT_EXCEEDED );
1058        set.add( ResultCodeEnum.STRONG_AUTH_REQUIRED );
1059        set.add( ResultCodeEnum.UNWILLING_TO_PERFORM );
1060        set.add( ResultCodeEnum.NOT_ALLOWED_ON_NON_LEAF );
1061        set.add( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
1062        set.add( ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS );
1063        set.add( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
1064        set.add( ResultCodeEnum.CANCELED );
1065        DELETE_CODES = Collections.unmodifiableSet( set );
1066    }
1067
1068    /**
1069     * A set of result code enumerations resulting from modifyDn operations. The
1070     * set contains:
1071     * <ul>
1072     * <li><a href="#BUSY">BUSY</a></li>
1073     * <li><a href="#OTHER">OTHER</a></li>
1074     * <li><a href="#SUCCESS">SUCCESS</a></li>
1075     * <li><a href="#REFERRAL">REFERRAL</a></li>
1076     * <li><a href="#LOOP_DETECT">LOOP_DETECT</a></li>
1077     * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
1078     * <li><a href="#NO_SUCH_OBJECT">NO_SUCH_OBJECT</a></li>
1079     * <li><a href="#PROTOCOL_ERROR">PROTOCOL_ERROR</a></li>
1080     * <li><a href="#INVALID_DN_SYNTAX">INVALID_DN_SYNTAX</a></li>
1081     * <li><a href="#NAMING_VIOLATION">NAMING_VIOLATION</a></li>
1082     * <li><a href="#TIME_LIMIT_EXCEEDED">TIME_LIMIT_EXCEEDED</a></li>
1083     * <li><a href="#ENTRY_ALREADY_EXISTS">ENTRY_ALREADY_EXISTS</a></li>
1084     * <li><a href="#ADMIN_LIMIT_EXCEEDED">ADMIN_LIMIT_EXCEEDED</a></li>
1085     * <li><a href="#STRONG_AUTH_REQUIRED">STRONG_AUTH_REQUIRED</a></li>
1086     * <li><a href="#UNWILLING_TO_PERFORM">UNWILLING_TO_PERFORM</a></li>
1087     * <li><a href="#NOT_ALLOWED_ON_NON_LEAF">NOT_ALLOWED_ON_NON_LEAF</a></li>
1088     * <li><a href="#AFFECTS_MULTIPLE_DSAS">AFFECTS_MULTIPLE_DSAS</a></li>
1089     * <li><a href="#CONSTRAINT_VIOLATION">CONSTRAINT_VIOLATION</a></li>
1090     * <li><a href="#OBJECT_CLASS_VIOLATION">OBJECT_CLASS_VIOLATION</a></li>
1091     * <li><a href="#CONFIDENTIALITY_REQUIRED">CONFIDENTIALITY_REQUIRED</a></li>
1092     * <li><a href="#INSUFFICIENT_ACCESS_RIGHTS">INSUFFICIENT_ACCESS_RIGHTS</a></li>
1093     * <li><a href="#UNAVAILABLE_CRITICAL_EXTENSION">UNAVAILABLE_CRITICAL_EXTENSION</a></li>
1094     * </ul>
1095     */
1096    private static final Set<ResultCodeEnum> MODIFYDN_CODES;
1097
1098    static
1099    {
1100        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1101        set.add( ResultCodeEnum.BUSY );
1102        set.add( ResultCodeEnum.OTHER );
1103        set.add( ResultCodeEnum.SUCCESS );
1104        set.add( ResultCodeEnum.REFERRAL );
1105        set.add( ResultCodeEnum.LOOP_DETECT );
1106        set.add( ResultCodeEnum.UNAVAILABLE );
1107        set.add( ResultCodeEnum.NO_SUCH_OBJECT );
1108        set.add( ResultCodeEnum.PROTOCOL_ERROR );
1109        set.add( ResultCodeEnum.INVALID_DN_SYNTAX );
1110        set.add( ResultCodeEnum.NAMING_VIOLATION );
1111        set.add( ResultCodeEnum.TIME_LIMIT_EXCEEDED );
1112        set.add( ResultCodeEnum.ENTRY_ALREADY_EXISTS );
1113        set.add( ResultCodeEnum.ADMIN_LIMIT_EXCEEDED );
1114        set.add( ResultCodeEnum.STRONG_AUTH_REQUIRED );
1115        set.add( ResultCodeEnum.UNWILLING_TO_PERFORM );
1116        set.add( ResultCodeEnum.NOT_ALLOWED_ON_NON_LEAF );
1117        set.add( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS );
1118        set.add( ResultCodeEnum.CONSTRAINT_VIOLATION );
1119        set.add( ResultCodeEnum.OBJECT_CLASS_VIOLATION );
1120        set.add( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
1121        set.add( ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS );
1122        set.add( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
1123        set.add( ResultCodeEnum.CANCELED );
1124        MODIFYDN_CODES = Collections.unmodifiableSet( set );
1125    }
1126
1127    /**
1128     * A set of result code enumerations that may result from compare
1129     * operations. The set contains:
1130     * <ul>
1131     * <li><a href="#OPERATIONSERROR">OPERATIONSERROR</a></li>
1132     * <li><a href="#PROTOCOL_ERROR">PROTOCOL_ERROR</a></li>
1133     * <li><a href="#TIME_LIMIT_EXCEEDED">TIME_LIMIT_EXCEEDED</a></li>
1134     * <li><a href="#COMPAREFALSE">COMPAREFALSE</a></li>
1135     * <li><a href="#COMPARETRUE">COMPARETRUE</a></li>
1136     * <li><a href="#STRONG_AUTH_REQUIRED">STRONG_AUTH_REQUIRED</a></li>
1137     * <li><a href="#ADMIN_LIMIT_EXCEEDED">ADMIN_LIMIT_EXCEEDED</a></li>
1138     * <li><a href="#UNAVAILABLE_CRITICAL_EXTENSION">UNAVAILABLE_CRITICAL_EXTENSION</a></li>
1139     * <li><a href="#CONFIDENTIALITY_REQUIRED">CONFIDENTIALITY_REQUIRED</a></li>
1140     * <li><a href="#NO_SUCH_ATTRIBUTE">NO_SUCH_ATTRIBUTE</a></li>
1141     * <li><a href="#INVALID_ATTRIBUTE_SYNTAX">INVALID_ATTRIBUTE_SYNTAX</a></li>
1142     * <li><a href="#NO_SUCH_OBJECT">NO_SUCH_OBJECT</a></li>
1143     * <li><a href="#INVALID_DN_SYNTAX">INVALID_DN_SYNTAX</a></li>
1144     * <li><a href="#INSUFFICIENT_ACCESS_RIGHTS">INSUFFICIENT_ACCESS_RIGHTS</a></li>
1145     * <li><a href="#BUSY">BUSY</a></li>
1146     * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
1147     * <li><a href="#UNWILLING_TO_PERFORM">UNWILLING_TO_PERFORM</a></li>
1148     * <li><a href="#LOOP_DETECT">LOOP_DETECT</a></li>
1149     * <li><a href="#REFERRAL">REFERRAL</a></li>
1150     * <li><a href="#OTHER">OTHER</a></li>
1151     * </ul>
1152     */
1153    private static final Set<ResultCodeEnum> COMPARE_CODES;
1154
1155    static
1156    {
1157        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1158        set.add( ResultCodeEnum.OPERATIONS_ERROR );
1159        set.add( ResultCodeEnum.PROTOCOL_ERROR );
1160        set.add( ResultCodeEnum.TIME_LIMIT_EXCEEDED );
1161        set.add( ResultCodeEnum.COMPARE_FALSE );
1162        set.add( ResultCodeEnum.COMPARE_TRUE );
1163        set.add( ResultCodeEnum.STRONG_AUTH_REQUIRED );
1164        set.add( ResultCodeEnum.ADMIN_LIMIT_EXCEEDED );
1165        set.add( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
1166        set.add( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
1167        set.add( ResultCodeEnum.NO_SUCH_ATTRIBUTE );
1168        set.add( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX );
1169        set.add( ResultCodeEnum.NO_SUCH_OBJECT );
1170        set.add( ResultCodeEnum.INVALID_DN_SYNTAX );
1171        set.add( ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS );
1172        set.add( ResultCodeEnum.BUSY );
1173        set.add( ResultCodeEnum.UNAVAILABLE );
1174        set.add( ResultCodeEnum.UNWILLING_TO_PERFORM );
1175        set.add( ResultCodeEnum.LOOP_DETECT );
1176        set.add( ResultCodeEnum.REFERRAL );
1177        set.add( ResultCodeEnum.OTHER );
1178        set.add( ResultCodeEnum.CANCELED );
1179        COMPARE_CODES = Collections.unmodifiableSet( set );
1180    }
1181
1182    /**
1183     * A set of result code enumerations that could result from extended
1184     * operations. The set contains:
1185     * <ul>
1186     * <li></li>
1187     * <li><a href="#SUCCESS">SUCCESS</a></li>
1188     * <li><a href="#OPERATIONSERROR">OPERATIONSERROR</a></li>
1189     * <li><a href="#PROTOCOL_ERROR">PROTOCOL_ERROR</a></li>
1190     * <li><a href="#TIME_LIMIT_EXCEEDED">TIME_LIMIT_EXCEEDED</a></li>
1191     * <li><a href="#SIZE_LIMIT_EXCEEDED">SIZE_LIMIT_EXCEEDED</a></li>
1192     * <li><a href="#COMPAREFALSE">COMPAREFALSE</a></li>
1193     * <li><a href="#COMPARETRUE">COMPARETRUE</a></li>
1194     * <li><a href="#AUTH_METHOD_NOT_SUPPORTED">AUTH_METHOD_NOT_SUPPORTED</a></li>
1195     * <li><a href="#STRONG_AUTH_REQUIRED">STRONG_AUTH_REQUIRED</a></li>
1196     * <li><a href="#REFERRAL">REFERRAL</a></li>
1197     * <li><a href="#ADMIN_LIMIT_EXCEEDED">ADMIN_LIMIT_EXCEEDED</a></li>
1198     * <li><a href="#UNAVAILABLE_CRITICAL_EXTENSION">UNAVAILABLE_CRITICAL_EXTENSION</a></li>
1199     * <li><a href="#CONFIDENTIALITY_REQUIRED">CONFIDENTIALITY_REQUIRED</a></li>
1200     * <li><a href="#SASL_BIND_IN_PROGRESS">SASL_BIND_IN_PROGRESS</a></li>
1201     * <li><a href="#NO_SUCH_ATTRIBUTE">NO_SUCH_ATTRIBUTE</a></li>
1202     * <li><a href="#UNDEFINED_ATTRIBUTE_TYPE">UNDEFINED_ATTRIBUTE_TYPE</a></li>
1203     * <li><a href="#INAPPROPRIATE_MATCHING">INAPPROPRIATE_MATCHING</a></li>
1204     * <li><a href="#CONSTRAINT_VIOLATION">CONSTRAINT_VIOLATION</a></li>
1205     * <li><a href="#ATTRIBUTE_OR_VALUE_EXISTS">ATTRIBUTE_OR_VALUE_EXISTS</a></li>
1206     * <li><a href="#INVALID_ATTRIBUTE_SYNTAX">INVALID_ATTRIBUTE_SYNTAX</a></li>
1207     * <li><a href="#NO_SUCH_OBJECT">NO_SUCH_OBJECT</a></li>
1208     * <li><a href="#ALIAS_PROBLEM">ALIAS_PROBLEM</a></li>
1209     * <li><a href="#INVALID_DN_SYNTAX">INVALID_DN_SYNTAX</a></li>
1210     * <li><a href="#ALIAS_DEREFERENCING_PROBLEM">ALIAS_DEREFERENCING_PROBLEM</a></li>
1211     * <li><a href="#INAPPROPRIATE_AUTHENTICATION">INAPPROPRIATE_AUTHENTICATION</a></li>
1212     * <li><a href="#INVALID_CREDENTIALS">INVALID_CREDENTIALS</a></li>
1213     * <li><a href="#INSUFFICIENT_ACCESS_RIGHTS">INSUFFICIENT_ACCESS_RIGHTS</a></li>
1214     * <li><a href="#BUSY">BUSY</a></li>
1215     * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
1216     * <li><a href="#UNWILLING_TO_PERFORM">UNWILLING_TO_PERFORM</a></li>
1217     * <li><a href="#LOOP_DETECT">LOOP_DETECT</a></li>
1218     * <li><a href="#NAMING_VIOLATION">NAMING_VIOLATION</a></li>
1219     * <li><a href="#OBJECT_CLASS_VIOLATION">OBJECT_CLASS_VIOLATION</a></li>
1220     * <li><a href="#NOT_ALLOWED_ON_NON_LEAF">NOT_ALLOWED_ON_NON_LEAF</a></li>
1221     * <li><a href="#NOT_ALLOWED_ON_RDN">NOT_ALLOWED_ON_RDN</a></li>
1222     * <li><a href="#ENTRY_ALREADY_EXISTS">ENTRY_ALREADY_EXISTS</a></li>
1223     * <li><a href="#OBJECT_CLASS_MODS_PROHIBITED">OBJECT_CLASS_MODS_PROHIBITED</a></li>
1224     * <li><a href="#AFFECTS_MULTIPLE_DSAS">AFFECTS_MULTIPLE_DSAS</a></li>
1225     * <li><a href="#OTHER">OTHER</a></li>
1226     * </ul>
1227     */
1228    private static final Set<ResultCodeEnum> EXTENDED_CODES;
1229
1230    static
1231    {
1232        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1233        set.add( ResultCodeEnum.SUCCESS );
1234        set.add( ResultCodeEnum.OPERATIONS_ERROR );
1235        set.add( ResultCodeEnum.PROTOCOL_ERROR );
1236        set.add( ResultCodeEnum.TIME_LIMIT_EXCEEDED );
1237        set.add( ResultCodeEnum.SIZE_LIMIT_EXCEEDED );
1238        set.add( ResultCodeEnum.COMPARE_FALSE );
1239        set.add( ResultCodeEnum.COMPARE_TRUE );
1240        set.add( ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED );
1241        set.add( ResultCodeEnum.STRONG_AUTH_REQUIRED );
1242        set.add( ResultCodeEnum.REFERRAL );
1243        set.add( ResultCodeEnum.ADMIN_LIMIT_EXCEEDED );
1244        set.add( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
1245        set.add( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
1246        set.add( ResultCodeEnum.SASL_BIND_IN_PROGRESS );
1247        set.add( ResultCodeEnum.NO_SUCH_ATTRIBUTE );
1248        set.add( ResultCodeEnum.UNDEFINED_ATTRIBUTE_TYPE );
1249        set.add( ResultCodeEnum.INAPPROPRIATE_MATCHING );
1250        set.add( ResultCodeEnum.CONSTRAINT_VIOLATION );
1251        set.add( ResultCodeEnum.ATTRIBUTE_OR_VALUE_EXISTS );
1252        set.add( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX );
1253        set.add( ResultCodeEnum.NO_SUCH_OBJECT );
1254        set.add( ResultCodeEnum.ALIAS_PROBLEM );
1255        set.add( ResultCodeEnum.INVALID_DN_SYNTAX );
1256        set.add( ResultCodeEnum.ALIAS_DEREFERENCING_PROBLEM );
1257        set.add( ResultCodeEnum.INAPPROPRIATE_AUTHENTICATION );
1258        set.add( ResultCodeEnum.INVALID_CREDENTIALS );
1259        set.add( ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS );
1260        set.add( ResultCodeEnum.BUSY );
1261        set.add( ResultCodeEnum.UNAVAILABLE );
1262        set.add( ResultCodeEnum.UNWILLING_TO_PERFORM );
1263        set.add( ResultCodeEnum.LOOP_DETECT );
1264        set.add( ResultCodeEnum.NAMING_VIOLATION );
1265        set.add( ResultCodeEnum.OBJECT_CLASS_VIOLATION );
1266        set.add( ResultCodeEnum.NOT_ALLOWED_ON_NON_LEAF );
1267        set.add( ResultCodeEnum.NOT_ALLOWED_ON_RDN );
1268        set.add( ResultCodeEnum.ENTRY_ALREADY_EXISTS );
1269        set.add( ResultCodeEnum.OBJECT_CLASS_MODS_PROHIBITED );
1270        set.add( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS );
1271        set.add( ResultCodeEnum.OTHER );
1272        set.add( ResultCodeEnum.CANCELED );
1273        EXTENDED_CODES = Collections.unmodifiableSet( set );
1274    }
1275
1276
1277    /**
1278     * @return The integer associated with the result code
1279     */
1280    public int getResultCode()
1281    {
1282        return value;
1283    }
1284
1285
1286    /**
1287     * Gets the ResultCode enum from its integer value
1288     * 
1289     * @param value the ResultCode numneric value
1290     * @return The integer associated with the result code
1291     */
1292    public static ResultCodeEnum getResultCode( int value )
1293    {
1294        switch ( value )
1295        {
1296            case 0:
1297                return SUCCESS;
1298            case 1:
1299                return OPERATIONS_ERROR;
1300            case 2:
1301                return PROTOCOL_ERROR;
1302            case 3:
1303                return TIME_LIMIT_EXCEEDED;
1304            case 4:
1305                return SIZE_LIMIT_EXCEEDED;
1306            case 5:
1307                return COMPARE_FALSE;
1308            case 6:
1309                return COMPARE_TRUE;
1310            case 7:
1311                return AUTH_METHOD_NOT_SUPPORTED;
1312            case 8:
1313                return STRONG_AUTH_REQUIRED;
1314            case 9:
1315                return PARTIAL_RESULTS;
1316            case 10:
1317                return REFERRAL;
1318            case 11:
1319                return ADMIN_LIMIT_EXCEEDED;
1320            case 12:
1321                return UNAVAILABLE_CRITICAL_EXTENSION;
1322            case 13:
1323                return CONFIDENTIALITY_REQUIRED;
1324            case 14:
1325                return SASL_BIND_IN_PROGRESS;
1326            case 16:
1327                return NO_SUCH_ATTRIBUTE;
1328            case 17:
1329                return UNDEFINED_ATTRIBUTE_TYPE;
1330            case 18:
1331                return INAPPROPRIATE_MATCHING;
1332            case 19:
1333                return CONSTRAINT_VIOLATION;
1334            case 20:
1335                return ATTRIBUTE_OR_VALUE_EXISTS;
1336            case 21:
1337                return INVALID_ATTRIBUTE_SYNTAX;
1338            case 32:
1339                return NO_SUCH_OBJECT;
1340            case 33:
1341                return ALIAS_PROBLEM;
1342            case 34:
1343                return INVALID_DN_SYNTAX;
1344            case 35:
1345                return UNKNOWN;
1346            case 36:
1347                return ALIAS_DEREFERENCING_PROBLEM;
1348            case 48:
1349                return INAPPROPRIATE_AUTHENTICATION;
1350            case 49:
1351                return INVALID_CREDENTIALS;
1352            case 50:
1353                return INSUFFICIENT_ACCESS_RIGHTS;
1354            case 51:
1355                return BUSY;
1356            case 52:
1357                return UNAVAILABLE;
1358            case 53:
1359                return UNWILLING_TO_PERFORM;
1360            case 54:
1361                return LOOP_DETECT;
1362            case 64:
1363                return NAMING_VIOLATION;
1364            case 65:
1365                return OBJECT_CLASS_VIOLATION;
1366            case 66:
1367                return NOT_ALLOWED_ON_NON_LEAF;
1368            case 67:
1369                return NOT_ALLOWED_ON_RDN;
1370            case 68:
1371                return ENTRY_ALREADY_EXISTS;
1372            case 69:
1373                return OBJECT_CLASS_MODS_PROHIBITED;
1374            case 71:
1375                return AFFECTS_MULTIPLE_DSAS;
1376            case 80:
1377                return OTHER;
1378            case 118:
1379                return CANCELED;
1380            case 119:
1381                return NO_SUCH_OPERATION;
1382            case 120:
1383                return TOO_LATE;
1384            case 121:
1385                return CANNOT_CANCEL;
1386            case 4096:
1387                return E_SYNC_REFRESH_REQUIRED;
1388            default:
1389                return UNKNOWN;
1390        }
1391    }
1392
1393    // ------------------------------------------------------------------------
1394    // Getting Result Code Enumeration Object Using Integer Values
1395    // ------------------------------------------------------------------------
1396    // ------------------------------------------------------------------------
1397    // JNDI Exception to ResultCodeEnum Mappings
1398    // ------------------------------------------------------------------------
1399
1400    /**
1401     * A set of ResultCodes containing those that may correspond to NamingException.
1402     * <ul>
1403     * <li><a href="#OPERATIONSERROR">operationsError(1)</a></li>
1404     * <li><a href="#ALIAS_PROBLEM">aliasProblem(33)</a></li>
1405     * <li><a href="#ALIAS_DEREFERENCING_PROBLEM">aliasDereferencingProblem(36)</a></li>
1406     * <li><a href="#LOOP_DETECT">loopDetect(54)</a></li>
1407     * <li><a href="#AFFECTS_MULTIPLE_DSAS">affectsMultipleDSAs(71)</a></li>
1408     * <li><a href="#OTHER">other(80)</a></li>
1409     * </ul>
1410     */
1411    private static final Set<ResultCodeEnum> NAMING_EXCEPTION_CODES;
1412
1413    static
1414    {
1415        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1416        set.add( ResultCodeEnum.OPERATIONS_ERROR );
1417        set.add( ResultCodeEnum.ALIAS_PROBLEM );
1418        set.add( ResultCodeEnum.ALIAS_DEREFERENCING_PROBLEM );
1419        set.add( ResultCodeEnum.LOOP_DETECT );
1420        set.add( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS );
1421        set.add( ResultCodeEnum.OTHER );
1422        NAMING_EXCEPTION_CODES = Collections.unmodifiableSet( set );
1423    }
1424
1425    /**
1426     * A set of ResultCodes containing those that may correspond to a
1427     * {@link Exception}.
1428     * <ul>
1429     * <li><a href="#AUTH_METHOD_NOT_SUPPORTED">authMethodNotSupported(7)</a></li>
1430     * <li><a href="#STRONG_AUTH_REQUIRED">strongAuthRequired(8)</a></li>
1431     * <li><a href="#CONFIDENTIALITY_REQUIRED">confidentialityRequired(13)</a></li>
1432     * <li><a
1433     * href="#INAPPROPRIATE_AUTHENTICATION">inappropriateAuthentication(48)</a></li>
1434     * </ul>
1435     */
1436    private static final Set<ResultCodeEnum> AUTHENTICATION_NOT_SUPPORTED_EXCEPTION_CODES;
1437
1438    static
1439    {
1440        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1441        set.add( ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED );
1442        set.add( ResultCodeEnum.STRONG_AUTH_REQUIRED );
1443        set.add( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
1444        set.add( ResultCodeEnum.INAPPROPRIATE_AUTHENTICATION );
1445        AUTHENTICATION_NOT_SUPPORTED_EXCEPTION_CODES = Collections.unmodifiableSet( set );
1446    }
1447
1448    /**
1449     * A set of ResultCodes containing those that may correspond to a
1450     * {@link Exception}.
1451     * <ul>
1452     * <li><a href="#BUSY">busy(51)</a></li>
1453     * <li><a href="#UNAVAILABLE">unavailable(52)</a></li>
1454     * </ul>
1455     */
1456    private static final Set<ResultCodeEnum> SERVICE_UNAVAILABLE_CODES;
1457
1458    static
1459    {
1460        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1461        set.add( ResultCodeEnum.BUSY );
1462        set.add( ResultCodeEnum.UNAVAILABLE );
1463        SERVICE_UNAVAILABLE_CODES = Collections.unmodifiableSet( set );
1464    }
1465
1466    /**
1467     * A set of ResultCodes containing those that may correspond to a
1468     * {@link Exception}.
1469     * <ul>
1470     * <li><a href="#CONSTRAINT_VIOLATION">constraintViolation(19)</a></li>
1471     * <li><a href="#INVALID_ATTRIBUTE_SYNTAX">invalidAttributeSyntax(21)</a></li>
1472     * </ul>
1473     */
1474    private static final Set<ResultCodeEnum> INVALID_ATTRIBUTE_VALUE_EXCEPTION_CODES;
1475
1476    static
1477    {
1478        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1479        set.add( ResultCodeEnum.CONSTRAINT_VIOLATION );
1480        set.add( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX );
1481        INVALID_ATTRIBUTE_VALUE_EXCEPTION_CODES = Collections.unmodifiableSet( set );
1482    }
1483
1484    /**
1485     * A set of ResultCodes containing those that may correspond to a
1486     * {@link Exception}.
1487     * <ul>
1488     * <li><a href="#PARTIAL_RESULTS">partialResults(9)</a></li>
1489     * <li><a href="#REFERRAL">referral(10)</a></li>
1490     * </ul>
1491     */
1492    private static final Set<ResultCodeEnum> PARTIAL_RESULTS_EXCEPTION_CODES;
1493
1494    static
1495    {
1496        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1497        set.add( ResultCodeEnum.PARTIAL_RESULTS );
1498        set.add( ResultCodeEnum.REFERRAL );
1499        PARTIAL_RESULTS_EXCEPTION_CODES = Collections.unmodifiableSet( set );
1500    }
1501
1502    /**
1503     * A set of ResultCodes containing those that may correspond to a
1504     * {@link Exception}.
1505     * <ul>
1506     * <li><a href="#REFERRAL">referal(9)</a></li>
1507     * <li><a href="#ADMIN_LIMIT_EXCEEDED">adminLimitExceeded(11)</a></li>
1508     * </ul>
1509     */
1510    private static final Set<ResultCodeEnum> LIMIT_EXCEEDED_EXCEPTION_CODES;
1511
1512    static
1513    {
1514        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1515        set.add( ResultCodeEnum.REFERRAL );
1516        set.add( ResultCodeEnum.ADMIN_LIMIT_EXCEEDED );
1517        LIMIT_EXCEEDED_EXCEPTION_CODES = Collections.unmodifiableSet( set );
1518    }
1519
1520    /**
1521     * A set of ResultCodes containing those that may correspond to a
1522     * {@link Exception}.
1523     * <ul>
1524     * <li><a
1525     * href="#UNAVAILABLECRITICALEXTENTION">unavailableCriticalExtention(12)</a></li>
1526     * <li><a href="#UNWILLING_TO_PERFORM">unwillingToPerform(53)</a></li>
1527     * </ul>
1528     */
1529    private static final Set<ResultCodeEnum> OPERATION_NOT_SUPPORTED_EXCEPTION_CODES;
1530
1531    static
1532    {
1533        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1534        set.add( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
1535        set.add( ResultCodeEnum.UNWILLING_TO_PERFORM );
1536        OPERATION_NOT_SUPPORTED_EXCEPTION_CODES = Collections.unmodifiableSet( set );
1537    }
1538
1539    /**
1540     * A set of ResultCodes containing those that may correspond to a
1541     * {@link Exception}.
1542     * <ul>
1543     * <li><a href="#INVALID_DN_SYNTAX">invalidDNSyntax(34)</a></li>
1544     * <li><a href="#NAMING_VIOLATION">namingViolation(64)</a></li>
1545     * </ul>
1546     */
1547    private static final Set<ResultCodeEnum> INVALID_NAME_EXCEPTION_CODES;
1548
1549    static
1550    {
1551        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1552        set.add( ResultCodeEnum.INVALID_DN_SYNTAX );
1553        set.add( ResultCodeEnum.NAMING_VIOLATION );
1554        INVALID_NAME_EXCEPTION_CODES = Collections.unmodifiableSet( set );
1555    }
1556
1557    /**
1558     * A set of ResultCodes containing those that may correspond to a
1559     * {@link javax.naming.directory.SchemaViolationException}.
1560     * <ul>
1561     * <li><a href="#OBJECT_CLASS_VIOLATION">objectClassViolation(65)</a></li>
1562     * <li><a href="#NOT_ALLOWED_ON_RDN">notAllowedOnRDN(67)</a></li>
1563     * <li><a href="#OBJECT_CLASS_MODS_PROHIBITED">objectClassModsProhibited(69)</a></li>
1564     * </ul>
1565     */
1566    private static final Set<ResultCodeEnum> SCHEMA_VIOLATION_EXCEPTION_CODES;
1567
1568    static
1569    {
1570        Set<ResultCodeEnum> set = new HashSet<ResultCodeEnum>();
1571        set.add( ResultCodeEnum.OBJECT_CLASS_VIOLATION );
1572        set.add( ResultCodeEnum.NOT_ALLOWED_ON_RDN );
1573        set.add( ResultCodeEnum.OBJECT_CLASS_MODS_PROHIBITED );
1574        SCHEMA_VIOLATION_EXCEPTION_CODES = Collections.unmodifiableSet( set );
1575    }
1576
1577
1578    /**
1579     * Takes a guess at the result code to use if it cannot figure it out from
1580     * known Throwable to result code mappings. Some however are ambiguous
1581     * mapping the same Throwable to multiple codes. If no code can be resolved
1582     * then {@link ResultCodeEnum#OTHER} is returned.
1583     * 
1584     * @param t
1585     *            the throwable to estimate a result code for
1586     * @param type
1587     *            the type of operation being performed
1588     * @return the result code or a good estimate of one
1589     */
1590    public static ResultCodeEnum getBestEstimate( Throwable t, MessageTypeEnum type )
1591    {
1592        Set<ResultCodeEnum> set = getResultCodes( t );
1593
1594        if ( set.isEmpty() )
1595        {
1596            return ResultCodeEnum.OTHER;
1597        }
1598
1599        if ( set.size() == 1 )
1600        {
1601            return set.iterator().next();
1602        }
1603
1604        if ( type == null )
1605        {
1606            Set<ResultCodeEnum> tmp = new HashSet<ResultCodeEnum>();
1607            tmp.addAll( set );
1608            tmp.removeAll( NON_ERRONEOUS_CODES );
1609
1610            if ( tmp.isEmpty() )
1611            {
1612                return ResultCodeEnum.OTHER;
1613            }
1614
1615            return tmp.iterator().next();
1616        }
1617
1618        Set<ResultCodeEnum> candidates = EMPTY_RESULT_CODE_SET;
1619
1620        switch ( type )
1621        {
1622            case ABANDON_REQUEST:
1623                return set.iterator().next();
1624
1625            case ADD_REQUEST:
1626                candidates = intersection( set, ADD_CODES );
1627                break;
1628
1629            case ADD_RESPONSE:
1630                candidates = intersection( set, ADD_CODES );
1631                break;
1632
1633            case BIND_REQUEST:
1634                candidates = intersection( set, BIND_CODES );
1635                break;
1636
1637            case BIND_RESPONSE:
1638                candidates = intersection( set, BIND_CODES );
1639                break;
1640
1641            case COMPARE_REQUEST:
1642                candidates = intersection( set, COMPARE_CODES );
1643                break;
1644
1645            case COMPARE_RESPONSE:
1646                candidates = intersection( set, COMPARE_CODES );
1647                break;
1648
1649            case DEL_REQUEST:
1650                candidates = intersection( set, DELETE_CODES );
1651                break;
1652
1653            case DEL_RESPONSE:
1654                candidates = intersection( set, DELETE_CODES );
1655                break;
1656
1657            case EXTENDED_REQUEST:
1658                candidates = intersection( set, EXTENDED_CODES );
1659                break;
1660
1661            case EXTENDED_RESPONSE:
1662                candidates = intersection( set, EXTENDED_CODES );
1663                break;
1664
1665            case MODIFYDN_REQUEST:
1666                candidates = intersection( set, MODIFYDN_CODES );
1667                break;
1668
1669            case MODIFYDN_RESPONSE:
1670                candidates = intersection( set, MODIFYDN_CODES );
1671                break;
1672
1673            case MODIFY_REQUEST:
1674                candidates = intersection( set, MODIFY_CODES );
1675                break;
1676
1677            case MODIFY_RESPONSE:
1678                candidates = intersection( set, MODIFY_CODES );
1679                break;
1680
1681            case SEARCH_REQUEST:
1682                candidates = intersection( set, SEARCH_CODES );
1683                break;
1684
1685            case SEARCH_RESULT_DONE:
1686                candidates = intersection( set, SEARCH_CODES );
1687                break;
1688
1689            case SEARCH_RESULT_ENTRY:
1690                candidates = intersection( set, SEARCH_CODES );
1691                break;
1692
1693            case SEARCH_RESULT_REFERENCE:
1694                candidates = intersection( set, SEARCH_CODES );
1695                break;
1696
1697            case UNBIND_REQUEST:
1698                return set.iterator().next();
1699
1700            case INTERMEDIATE_RESPONSE:
1701                candidates = intersection( set, SEARCH_CODES );
1702                break;
1703
1704            default:
1705                throw new IllegalArgumentException( "Unexpected MessageTypeEnum " + type );
1706        }
1707
1708        // we don't want any codes that do not have anything to do w/ errors
1709        candidates.removeAll( NON_ERRONEOUS_CODES );
1710
1711        if ( candidates.isEmpty() )
1712        {
1713            return ResultCodeEnum.OTHER;
1714        }
1715
1716        return candidates.iterator().next();
1717    }
1718
1719
1720    private static Set<ResultCodeEnum> intersection( Set<ResultCodeEnum> s1, Set<ResultCodeEnum> s2 )
1721    {
1722        if ( s1.isEmpty() || s2.isEmpty() )
1723        {
1724            return new HashSet<ResultCodeEnum>();
1725        }
1726
1727        Set<ResultCodeEnum> intersection = new HashSet<ResultCodeEnum>();
1728
1729        if ( s1.size() <= s2.size() )
1730        {
1731            for ( ResultCodeEnum item : s1 )
1732            {
1733                if ( s2.contains( item ) )
1734                {
1735                    intersection.add( item );
1736                }
1737            }
1738        }
1739        else
1740        {
1741            for ( ResultCodeEnum item : s2 )
1742            {
1743                if ( s1.contains( item ) )
1744                {
1745                    intersection.add( item );
1746                }
1747            }
1748        }
1749
1750        return intersection;
1751    }
1752
1753
1754    /**
1755     * Gets the set of result codes a Throwable may map to. If the throwable
1756     * does not map to any result code at all an empty set is returned. The
1757     * following Throwables and their subclasses map to result codes:
1758     * 
1759     * <pre>
1760     * 
1761     *  Unambiguous Exceptions
1762     *  ======================
1763     * 
1764     *  CommunicationException              ==&gt; operationsError(1)
1765     *  TimeLimitExceededException          ==&gt; timeLimitExceeded(3)
1766     *  SizeLimitExceededException          ==&gt; sizeLimitExceeded(4)
1767     *  AuthenticationException             ==&gt; invalidCredentials(49)
1768     *  NoPermissionException               ==&gt; insufficientAccessRights(50)
1769     *  NoSuchAttributeException            ==&gt; noSuchAttribute(16)
1770     *  InvalidAttributeIdentifierException ==&gt; undefinedAttributeType(17)
1771     *  InvalidSearchFilterException        ==&gt; inappropriateMatching(18)
1772     *  AttributeInUseException             ==&gt; attributeOrValueExists(20)
1773     *  NameNotFoundException               ==&gt; NO_SUCH_OBJECT(32)
1774     *  NameAlreadyBoundException           ==&gt; entryAlreadyExists(68)
1775     *  ContextNotEmptyException            ==&gt; notAllowedOnNonLeaf(66)
1776     * 
1777     * 
1778     *  Ambiguous Exceptions
1779     *  ====================
1780     * 
1781     *  NamingException
1782     *  ---------------
1783     *  operationsError(1)
1784     *  aliasProblem(33)
1785     *  aliasDereferencingProblem(36)
1786     *  loopDetect(54)
1787     *  affectsMultipleDSAs(71)
1788     *  other(80)
1789     * 
1790     *  AuthenticationNotSupportedException
1791     *  -----------------------------------
1792     *  authMethodNotSupported (7)
1793     *  strongAuthRequired (8)
1794     *  confidentialityRequired (13)
1795     *  inappropriateAuthentication(48)
1796     * 
1797     *  ServiceUnavailableException
1798     *  ---------------------------
1799     *  busy(51)
1800     *  unavailable(52)
1801     * 
1802     *  InvalidAttributeValueException
1803     *  ------------------------------
1804     *  constraintViolation(19)
1805     *  invalidAttributeSyntax(21)
1806     * 
1807     *  PartialResultException
1808     *  ----------------------
1809     *  partialResults(9)
1810     *  referral(10)
1811     * 
1812     *  LimitExceededException
1813     *  ----------------------
1814     *  referal(9)
1815     *  adminLimitExceeded(11)
1816     * 
1817     *  OperationNotSupportedException
1818     *  ------------------------------
1819     *  unavailableCriticalExtention(12)
1820     *  unwillingToPerform(53)
1821     * 
1822     *  InvalidNameException
1823     *  --------------------
1824     *  invalidDNSyntax(34)
1825     *  namingViolation(64)
1826     * 
1827     *  SchemaViolationException
1828     *  ------------------------
1829     *  objectClassViolation(65)
1830     *  notAllowedOnRDN(67)
1831     *  objectClassModsProhibited(69)
1832     * 
1833     * </pre>
1834     * 
1835     * @param t
1836     *            the Throwable to find the result code mappings for
1837     * @return the set of mapped result codes
1838     */
1839    private static Set<ResultCodeEnum> getResultCodes( Throwable t )
1840    {
1841        ResultCodeEnum rc = getResultCode( t );
1842        if ( rc != null )
1843        {
1844            return Collections.singleton( rc );
1845        }
1846
1847        if ( t instanceof LdapSchemaViolationException )
1848        {
1849            return SCHEMA_VIOLATION_EXCEPTION_CODES;
1850        }
1851
1852        if ( t instanceof LdapInvalidDnException )
1853        {
1854            return INVALID_NAME_EXCEPTION_CODES;
1855        }
1856
1857        if ( t instanceof LdapUnwillingToPerformException )
1858        {
1859            return OPERATION_NOT_SUPPORTED_EXCEPTION_CODES;
1860        }
1861
1862        if ( t instanceof LimitExceededException )
1863        {
1864            return LIMIT_EXCEEDED_EXCEPTION_CODES;
1865        }
1866
1867        if ( t instanceof PartialResultException )
1868        {
1869            return PARTIAL_RESULTS_EXCEPTION_CODES;
1870        }
1871
1872        if ( t instanceof LdapInvalidAttributeValueException )
1873        {
1874            return INVALID_ATTRIBUTE_VALUE_EXCEPTION_CODES;
1875        }
1876
1877        if ( t instanceof LdapServiceUnavailableException )
1878        {
1879            return SERVICE_UNAVAILABLE_CODES;
1880        }
1881
1882        if ( t instanceof LdapAuthenticationNotSupportedException )
1883        {
1884            return AUTHENTICATION_NOT_SUPPORTED_EXCEPTION_CODES;
1885        }
1886
1887        // keep this last because others are subtypes and thier evaluation
1888        // may be shorted otherwise by this comparison here
1889        if ( t instanceof LdapException )
1890        {
1891            return NAMING_EXCEPTION_CODES;
1892        }
1893
1894        return EMPTY_RESULT_CODE_SET;
1895    }
1896
1897
1898    /**
1899     * Gets an LDAP result code from a Throwable if it can resolve it
1900     * unambiguously or returns null if it cannot resolve the exception to a
1901     * single ResultCode. If the Throwable is an instance of LdapException this
1902     * is already done for us, otherwise we use the following mapping:
1903     * 
1904     * <pre>
1905     * 
1906     *  Unambiguous Exceptions
1907     *  ======================
1908     * 
1909     *  CommunicationException              ==&gt; operationsError(1)
1910     *  TimeLimitExceededException          ==&gt; timeLimitExceeded(3)
1911     *  SizeLimitExceededException          ==&gt; sizeLimitExceeded(4)
1912     *  AuthenticationException             ==&gt; invalidCredentials(49)
1913     *  NoPermissionException               ==&gt; insufficientAccessRights(50)
1914     *  NoSuchAttributeException            ==&gt; noSuchAttribute(16)
1915     *  InvalidAttributeIdentifierException ==&gt; undefinedAttributeType(17)
1916     *  InvalidSearchFilterException        ==&gt; inappropriateMatching(18)
1917     *  AttributeInUseException             ==&gt; attributeOrValueExists(20)
1918     *  NameNotFoundException               ==&gt; NO_SUCH_OBJECT(32)
1919     *  NameAlreadyBoundException           ==&gt; entryAlreadyExists(68)
1920     *  ContextNotEmptyException            ==&gt; notAllowedOnNonLeaf(66)
1921     * </pre>
1922     * 
1923     * If we cannot find a mapping then null is returned.
1924     * 
1925     * @param t The exception for which we need a ResultCodeEnum
1926     * @return The ResultCodeEnum associated wit the given exception 
1927     */
1928    public static ResultCodeEnum getResultCode( Throwable t )
1929    {
1930        if ( t instanceof LdapOperationException )
1931        {
1932            return ( ( LdapOperationException ) t ).getResultCode();
1933        }
1934
1935        if ( t instanceof CommunicationException )
1936        {
1937            return ResultCodeEnum.PROTOCOL_ERROR;
1938        }
1939
1940        if ( t instanceof LdapTimeLimitExceededException )
1941        {
1942            return ResultCodeEnum.TIME_LIMIT_EXCEEDED;
1943        }
1944
1945        if ( t instanceof SizeLimitExceededException )
1946        {
1947            return ResultCodeEnum.SIZE_LIMIT_EXCEEDED;
1948        }
1949
1950        if ( t instanceof LdapAuthenticationException )
1951        {
1952            return ResultCodeEnum.INVALID_CREDENTIALS;
1953        }
1954
1955        if ( t instanceof LdapNoPermissionException )
1956        {
1957            return ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS;
1958        }
1959
1960        if ( t instanceof LdapNoSuchAttributeException )
1961        {
1962            return ResultCodeEnum.NO_SUCH_ATTRIBUTE;
1963        }
1964
1965        if ( t instanceof LdapInvalidAttributeTypeException )
1966        {
1967            return ResultCodeEnum.UNDEFINED_ATTRIBUTE_TYPE;
1968        }
1969
1970        if ( t instanceof LdapInvalidSearchFilterException )
1971        {
1972            return ResultCodeEnum.INAPPROPRIATE_MATCHING;
1973        }
1974
1975        if ( t instanceof LdapAttributeInUseException )
1976        {
1977            return ResultCodeEnum.ATTRIBUTE_OR_VALUE_EXISTS;
1978        }
1979
1980        if ( t instanceof LdapNoSuchObjectException )
1981        {
1982            return ResultCodeEnum.NO_SUCH_OBJECT;
1983        }
1984
1985        if ( t instanceof LdapEntryAlreadyExistsException )
1986        {
1987            return ResultCodeEnum.ENTRY_ALREADY_EXISTS;
1988        }
1989
1990        if ( t instanceof LdapContextNotEmptyException )
1991        {
1992            return ResultCodeEnum.NOT_ALLOWED_ON_NON_LEAF;
1993        }
1994
1995        return null;
1996    }
1997
1998
1999    /**
2000     * Process the response, throwing the associated exception if needed. If the result
2001     * was SUCCESS, does not return anything but true. 
2002     * 
2003     * @param response The response to process
2004     * @return For the COMPARE_TRUE or COMPARE_FALSE results, return true or false
2005     * @throws LdapException The associated exception
2006     */
2007    public static boolean processResponse( ResultResponse response ) throws LdapException
2008    {
2009        LdapResult ldapResult = response.getLdapResult();
2010
2011        switch ( ldapResult.getResultCode() )
2012        {
2013        // Not erroneous code
2014            case SUCCESS:
2015            case PARTIAL_RESULTS:
2016            case REFERRAL:
2017            case SASL_BIND_IN_PROGRESS:
2018            case CANCELED:
2019            case COMPARE_TRUE:
2020                return true;
2021
2022            case COMPARE_FALSE:
2023                return false;
2024
2025            case INVALID_CREDENTIALS:
2026                LdapAuthenticationException authenticationException = new LdapAuthenticationException(
2027                    ldapResult.getDiagnosticMessage() );
2028                authenticationException.setResolvedDn( ldapResult.getMatchedDn() );
2029
2030                throw authenticationException;
2031
2032            case UNWILLING_TO_PERFORM:
2033            case UNAVAILABLE_CRITICAL_EXTENSION:
2034                LdapUnwillingToPerformException unwillingToPerformException =
2035                    new LdapUnwillingToPerformException( ldapResult.getResultCode(), ldapResult.getDiagnosticMessage() );
2036                unwillingToPerformException.setResolvedDn( ldapResult.getMatchedDn() );
2037
2038                throw unwillingToPerformException;
2039
2040            case INSUFFICIENT_ACCESS_RIGHTS:
2041                LdapNoPermissionException ldapNoPermissionException = new LdapNoPermissionException(
2042                    ldapResult.getDiagnosticMessage() );
2043                ldapNoPermissionException.setResolvedDn( ldapResult.getMatchedDn() );
2044
2045                throw ldapNoPermissionException;
2046
2047            case NOT_ALLOWED_ON_NON_LEAF:
2048                LdapContextNotEmptyException ldapContextNotEmptyException = new LdapContextNotEmptyException(
2049                    ldapResult.getDiagnosticMessage() );
2050                ldapContextNotEmptyException.setResolvedDn( ldapResult.getMatchedDn() );
2051
2052                throw ldapContextNotEmptyException;
2053
2054            case NO_SUCH_OBJECT:
2055                LdapNoSuchObjectException ldapNoSuchObjectException = new LdapNoSuchObjectException(
2056                    ldapResult.getDiagnosticMessage() );
2057                ldapNoSuchObjectException.setResolvedDn( ldapResult.getMatchedDn() );
2058
2059                throw ldapNoSuchObjectException;
2060
2061            case NO_SUCH_ATTRIBUTE:
2062                LdapNoSuchAttributeException ldapNoSuchAttributeException = new LdapNoSuchAttributeException(
2063                    ldapResult.getDiagnosticMessage() );
2064                ldapNoSuchAttributeException.setResolvedDn( ldapResult.getMatchedDn() );
2065
2066                throw ldapNoSuchAttributeException;
2067
2068            case ATTRIBUTE_OR_VALUE_EXISTS:
2069                LdapAttributeInUseException ldapAttributeInUseException = new LdapAttributeInUseException(
2070                    ldapResult.getDiagnosticMessage() );
2071                ldapAttributeInUseException.setResolvedDn( ldapResult.getMatchedDn() );
2072
2073                throw ldapAttributeInUseException;
2074
2075            case ENTRY_ALREADY_EXISTS:
2076                LdapEntryAlreadyExistsException ldapEntryAlreadyExistsException = new LdapEntryAlreadyExistsException(
2077                    ldapResult.getDiagnosticMessage() );
2078                ldapEntryAlreadyExistsException.setResolvedDn( ldapResult.getMatchedDn() );
2079
2080                throw ldapEntryAlreadyExistsException;
2081
2082            case OBJECT_CLASS_VIOLATION:
2083            case NOT_ALLOWED_ON_RDN:
2084            case OBJECT_CLASS_MODS_PROHIBITED:
2085                LdapSchemaViolationException ldapSchemaViolationException =
2086                    new LdapSchemaViolationException( ldapResult.getResultCode(), ldapResult.getDiagnosticMessage() );
2087                ldapSchemaViolationException.setResolvedDn( ldapResult.getMatchedDn() );
2088
2089                throw ldapSchemaViolationException;
2090
2091            case ALIAS_PROBLEM:
2092                LdapAliasException ldapAliasException = new LdapAliasException( ldapResult.getDiagnosticMessage() );
2093                ldapAliasException.setResolvedDn( ldapResult.getMatchedDn() );
2094
2095                throw ldapAliasException;
2096
2097            case AFFECTS_MULTIPLE_DSAS:
2098                LdapAffectMultipleDsaException ldapAffectMultipleDsaException = new LdapAffectMultipleDsaException(
2099                    ldapResult.getDiagnosticMessage() );
2100                ldapAffectMultipleDsaException.setResolvedDn( ldapResult.getMatchedDn() );
2101
2102                throw ldapAffectMultipleDsaException;
2103
2104            case ALIAS_DEREFERENCING_PROBLEM:
2105                LdapAliasDereferencingException ldapAliasDereferencingException = new LdapAliasDereferencingException(
2106                    ldapResult.getDiagnosticMessage() );
2107                ldapAliasDereferencingException.setResolvedDn( ldapResult.getMatchedDn() );
2108
2109                throw ldapAliasDereferencingException;
2110
2111            case AUTH_METHOD_NOT_SUPPORTED:
2112            case INAPPROPRIATE_AUTHENTICATION:
2113            case CONFIDENTIALITY_REQUIRED:
2114                LdapAuthenticationNotSupportedException ldapAuthenticationNotSupportedException =
2115                    new LdapAuthenticationNotSupportedException( ldapResult.getResultCode(),
2116                        ldapResult.getDiagnosticMessage() );
2117                ldapAuthenticationNotSupportedException.setResolvedDn( ldapResult.getMatchedDn() );
2118
2119                throw ldapAuthenticationNotSupportedException;
2120
2121            case BUSY:
2122            case UNAVAILABLE:
2123                LdapServiceUnavailableException ldapServiceUnavailableException =
2124                    new LdapServiceUnavailableException( ldapResult.getResultCode(), ldapResult.getDiagnosticMessage() );
2125                ldapServiceUnavailableException.setResolvedDn( ldapResult.getMatchedDn() );
2126
2127                throw ldapServiceUnavailableException;
2128
2129            case CONSTRAINT_VIOLATION:
2130            case INVALID_ATTRIBUTE_SYNTAX:
2131                LdapInvalidAttributeValueException ldapInvalidAttributeValueException =
2132                    new LdapInvalidAttributeValueException( ldapResult.getResultCode(),
2133                        ldapResult.getDiagnosticMessage() );
2134                ldapInvalidAttributeValueException.setResolvedDn( ldapResult.getMatchedDn() );
2135
2136                throw ldapInvalidAttributeValueException;
2137
2138            case INAPPROPRIATE_MATCHING:
2139                LdapInvalidSearchFilterException ldapInvalidSearchFilterException = new LdapInvalidSearchFilterException(
2140                    ldapResult.getDiagnosticMessage() );
2141                ldapInvalidSearchFilterException.setResolvedDn( ldapResult.getMatchedDn() );
2142
2143                throw ldapInvalidSearchFilterException;
2144
2145            case INVALID_DN_SYNTAX:
2146            case NAMING_VIOLATION:
2147                LdapInvalidDnException ldapInvalidDnException =
2148                    new LdapInvalidDnException( ldapResult.getResultCode(), ldapResult.getDiagnosticMessage() );
2149                ldapInvalidDnException.setResolvedDn( ldapResult.getMatchedDn() );
2150
2151                throw ldapInvalidDnException;
2152
2153            case LOOP_DETECT:
2154                LdapLoopDetectedException ldapLoopDetectedException = new LdapLoopDetectedException(
2155                    ldapResult.getDiagnosticMessage() );
2156                ldapLoopDetectedException.setResolvedDn( ldapResult.getMatchedDn() );
2157
2158                throw ldapLoopDetectedException;
2159
2160            case OPERATIONS_ERROR:
2161                LdapOperationErrorException ldapOperationErrorException = new LdapOperationErrorException(
2162                    ldapResult.getDiagnosticMessage() );
2163                ldapOperationErrorException.setResolvedDn( ldapResult.getMatchedDn() );
2164
2165                throw ldapOperationErrorException;
2166
2167            case PROTOCOL_ERROR:
2168                LdapProtocolErrorException ldapProtocolErrorException = new LdapProtocolErrorException(
2169                    ldapResult.getDiagnosticMessage() );
2170                ldapProtocolErrorException.setResolvedDn( ldapResult.getMatchedDn() );
2171
2172                throw ldapProtocolErrorException;
2173
2174            case TIME_LIMIT_EXCEEDED:
2175                LdapTimeLimitExceededException ldapTimeLimitExceededException = new LdapTimeLimitExceededException(
2176                    ldapResult.getDiagnosticMessage() );
2177                ldapTimeLimitExceededException.setResolvedDn( ldapResult.getMatchedDn() );
2178
2179                throw ldapTimeLimitExceededException;
2180
2181            case UNDEFINED_ATTRIBUTE_TYPE:
2182                LdapInvalidAttributeTypeException ldapInvalidAttributeTypeException = new LdapInvalidAttributeTypeException(
2183                    ldapResult.getDiagnosticMessage() );
2184                ldapInvalidAttributeTypeException.setResolvedDn( ldapResult.getMatchedDn() );
2185
2186                throw ldapInvalidAttributeTypeException;
2187
2188            case OTHER:
2189                LdapOtherException ldapOtherException = new LdapOtherException( ldapResult.getDiagnosticMessage() );
2190                ldapOtherException.setResolvedDn( ldapResult.getMatchedDn() );
2191
2192                throw ldapOtherException;
2193
2194            case SIZE_LIMIT_EXCEEDED:
2195                LdapSizeLimitExceededException ldapSizeLimitExceededException = new LdapSizeLimitExceededException(
2196                    ldapResult.getDiagnosticMessage() );
2197                ldapSizeLimitExceededException.setResolvedDn( ldapResult.getMatchedDn() );
2198
2199                throw ldapSizeLimitExceededException;
2200
2201            case STRONG_AUTH_REQUIRED:
2202                LdapStrongAuthenticationRequiredException ldapStrongAuthenticationRequiredException =
2203                    new LdapStrongAuthenticationRequiredException( ldapResult.getDiagnosticMessage() );
2204                ldapStrongAuthenticationRequiredException.setResolvedDn( ldapResult.getMatchedDn() );
2205
2206                throw ldapStrongAuthenticationRequiredException;
2207
2208            case ADMIN_LIMIT_EXCEEDED:
2209                LdapAdminLimitExceededException ldapAdminLimitExceededException =
2210                    new LdapAdminLimitExceededException( ldapResult.getDiagnosticMessage() );
2211                ldapAdminLimitExceededException.setResolvedDn( ldapResult.getMatchedDn() );
2212
2213                throw ldapAdminLimitExceededException;
2214
2215            case TOO_LATE:
2216                LdapTooLateException ldapTooLateException = new LdapTooLateException( ldapResult.getDiagnosticMessage() );
2217                ldapTooLateException.setResolvedDn( ldapResult.getMatchedDn() );
2218
2219                throw ldapTooLateException;
2220
2221            case UNKNOWN:
2222                LdapUnknownException ldapUnknownException = new LdapUnknownException( ldapResult.getDiagnosticMessage() );
2223                ldapUnknownException.setResolvedDn( ldapResult.getMatchedDn() );
2224
2225                throw ldapUnknownException;
2226
2227            case CANNOT_CANCEL:
2228                LdapCannotCancelException ldapCannotCancelException = new LdapCannotCancelException(
2229                    ldapResult.getDiagnosticMessage() );
2230                ldapCannotCancelException.setResolvedDn( ldapResult.getMatchedDn() );
2231
2232                throw ldapCannotCancelException;
2233
2234            case NO_SUCH_OPERATION:
2235                LdapNoSuchOperationException ldapNoSuchOperationException = new LdapNoSuchOperationException(
2236                    ldapResult.getDiagnosticMessage() );
2237                ldapNoSuchOperationException.setResolvedDn( ldapResult.getMatchedDn() );
2238
2239                throw ldapNoSuchOperationException;
2240
2241            case E_SYNC_REFRESH_REQUIRED:
2242                // This is a specific error message. We won't encapsulate it in a dedicated exception
2243                // Fallthrough
2244
2245            default:
2246                LdapOperationException exception = new LdapOperationException( ldapResult.getResultCode(),
2247                    ldapResult.getDiagnosticMessage() );
2248                exception.setResolvedDn( ldapResult.getMatchedDn() );
2249
2250                throw exception;
2251        }
2252    }
2253}