001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *  
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *  
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License. 
018 *  
019 */
020package org.apache.directory.api.ldap.model.message;
021
022
023import java.util.Collections;
024import java.util.HashSet;
025import java.util.Set;
026
027import javax.naming.CommunicationException;
028import javax.naming.LimitExceededException;
029import javax.naming.PartialResultException;
030import javax.naming.SizeLimitExceededException;
031
032import org.apache.directory.api.i18n.I18n;
033import org.apache.directory.api.ldap.model.exception.LdapAdminLimitExceededException;
034import org.apache.directory.api.ldap.model.exception.LdapAffectMultipleDsaException;
035import org.apache.directory.api.ldap.model.exception.LdapAliasDereferencingException;
036import org.apache.directory.api.ldap.model.exception.LdapAliasException;
037import org.apache.directory.api.ldap.model.exception.LdapAttributeInUseException;
038import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
039import org.apache.directory.api.ldap.model.exception.LdapAuthenticationNotSupportedException;
040import org.apache.directory.api.ldap.model.exception.LdapCannotCancelException;
041import org.apache.directory.api.ldap.model.exception.LdapContextNotEmptyException;
042import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
043import org.apache.directory.api.ldap.model.exception.LdapException;
044import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeTypeException;
045import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
046import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
047import org.apache.directory.api.ldap.model.exception.LdapInvalidSearchFilterException;
048import org.apache.directory.api.ldap.model.exception.LdapLoopDetectedException;
049import org.apache.directory.api.ldap.model.exception.LdapNoPermissionException;
050import org.apache.directory.api.ldap.model.exception.LdapNoSuchAttributeException;
051import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
052import org.apache.directory.api.ldap.model.exception.LdapNoSuchOperationException;
053import org.apache.directory.api.ldap.model.exception.LdapOperationErrorException;
054import org.apache.directory.api.ldap.model.exception.LdapOperationException;
055import org.apache.directory.api.ldap.model.exception.LdapOtherException;
056import org.apache.directory.api.ldap.model.exception.LdapProtocolErrorException;
057import org.apache.directory.api.ldap.model.exception.LdapSchemaViolationException;
058import org.apache.directory.api.ldap.model.exception.LdapServiceUnavailableException;
059import org.apache.directory.api.ldap.model.exception.LdapSizeLimitExceededException;
060import org.apache.directory.api.ldap.model.exception.LdapStrongAuthenticationRequiredException;
061import org.apache.directory.api.ldap.model.exception.LdapTimeLimitExceededException;
062import org.apache.directory.api.ldap.model.exception.LdapTooLateException;
063import org.apache.directory.api.ldap.model.exception.LdapUnknownException;
064import org.apache.directory.api.ldap.model.exception.LdapUnwillingToPerformException;
065
066
067/**
068 * Type safe LDAP message envelope result code enumeration. The resultCode is a
069 * parameter of the LDAPResult which is the construct used in this protocol to
070 * return success or failure indications from servers to clients. In response to
071 * various requests servers will return responses containing fields of type
072 * LDAPResult to indicate the final status of a protocol operation request. This
073 * enumeration represents the various status codes associated with an
074 * LDAPResult, hence it is called the ResultCodeEnum. Here are the definitions
075 * and values for error codes from section 4.1.10 of <a
076 * href="http://www.faqs.org/rfcs/rfc2251.html">RFC 2251</a>:
077 * 
078 * <pre><code>
079 *     resultCode
080 *        ENUMERATED {
081 *           success                      (0),
082 *           operationsError              (1),
083 *           protocolError                (2),
084 *           timeLimitExceeded            (3),
085 *           sizeLimitExceeded            (4),
086 *           compareFalse                 (5),
087 *           compareTrue                  (6),
088 *           authMethodNotSupported       (7),
089 *           strongAuthRequired           (8),
090 *           partialResults               (9),   -- new
091 *           referral                     (10),  -- new
092 *           adminLimitExceeded           (11),  -- new
093 *           unavailableCriticalExtension (12),  -- new
094 *           confidentialityRequired      (13),  -- new
095 *           saslBindInProgress           (14),  -- new
096 *           noSuchAttribute              (16),
097 *           undefinedAttributeType       (17),
098 *           inappropriateMatching        (18),
099 *           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 */
174public 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}