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