directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akaras...@apache.org
Subject svn commit: rev 56542 - in incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common: message util
Date Thu, 04 Nov 2004 00:50:45 GMT
Author: akarasulu
Date: Wed Nov  3 16:50:45 2004
New Revision: 56542

Modified:
   incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/message/ResultCodeEnum.java
   incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/util/ExceptionUtils.java
Log:
Changes ...

ExceptionUtils
--------------

 o formated exception utils

ResultCodeEnum
--------------

 o switched out mutable unsafe String[] constants for unmodifiable Sets
 o added better documentation for constants
 o added mapping method to get a ResultCodeEnum from a Throwable
 o added a way to best estimate the result code based on the operation
   at hand and the Throwable encountered - basically this takes the
   set of resolved result codes for an exception and takes the intersection
   with the result codes for the operation; non error based codes are
   removed; if anything is left then it is returned otherwise the OTHER code
   is returned



Modified: incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/message/ResultCodeEnum.java
==============================================================================
--- incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/message/ResultCodeEnum.java	(original)
+++ incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/message/ResultCodeEnum.java	Wed Nov  3 16:50:45 2004
@@ -17,7 +17,15 @@
 package org.apache.ldap.common.message ;
 
 
-import org.apache.ldap.common.util.ValuedEnum ; 
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.Iterator;
+import javax.naming.*;
+import javax.naming.directory.*;
+
+import org.apache.ldap.common.util.ValuedEnum ;
+import org.apache.ldap.common.exception.LdapException;
 
 
 /**
@@ -31,54 +39,55 @@
  * are the definitions and values for error codes from section 4.1.10 of <a
  * href="http://www.faqs.org/rfcs/rfc2251.html">RFC 2251</a>:
  * <pre><code>
- *              resultCode      ENUMERATED {
- *                           success                      (0),
- *                           operationsError              (1),
- *                           protocolError                (2),
- *                           timeLimitExceeded            (3),
- *                           sizeLimitExceeded            (4),
- *                           compareFalse                 (5),
- *                           compareTrue                  (6),
- *                            authMethodNotSupported       (7),
- *                           strongAuthRequired           (8),
- *                                      -- 9 reserved --
- *                           referral                     (10),  -- new
- *                           adminLimitExceeded           (11),  -- new
- *                           unavailableCriticalExtension (12),  -- new
- *                           confidentialityRequired      (13),  -- new
- *                           saslBindInProgress           (14),  -- new
- *                           noSuchAttribute              (16),
- *                           undefinedAttributeType       (17),
- *                           inappropriateMatching        (18),
- *                           constraintViolation          (19),
- *                           attributeOrValueExists       (20),
- *                           invalidAttributeSyntax       (21),
- *                                      -- 22-31 unused --
- *                            noSuchObject                 (32),
- *                           aliasProblem                 (33),
- *                           invalidDNSyntax              (34),
- *                           -- 35 reserved for undefined isLeaf --
- *                           aliasDereferencingProblem    (36),
- *                                      -- 37-47 unused --
- *                           inappropriateAuthentication  (48),
- *                           invalidCredentials           (49),
- *                           insufficientAccessRights     (50),
- *                           busy                         (51),
- *                           unavailable                  (52),
- *                           unwillingToPerform           (53),
- *                           loopDetect                   (54),
- *                                      -- 55-63 unused --
- *                           namingViolation              (64),
- *                           objectClassViolation         (65),
- *                           notAllowedOnNonLeaf          (66),
- *                           notAllowedOnRDN              (67),
- *                           entryAlreadyExists           (68),
- *                           objectClassModsProhibited    (69),
- *                                      -- 70 reserved for CLDAP --
- *                           affectsMultipleDSAs          (71), -- new
- *                                      -- 72-79 unused --
- *                           other                        (80) },
- *                           -- 81-90 reserved for APIs --
+ *    resultCode
+ *       ENUMERATED {
+ *          success                      (0),
+ *          operationsError              (1),
+ *          protocolError                (2),
+ *          timeLimitExceeded            (3),
+ *          sizeLimitExceeded            (4),
+ *          compareFalse                 (5),
+ *          compareTrue                  (6),
+ *          authMethodNotSupported       (7),
+ *          strongAuthRequired           (8),
+ *          partialResults               (9),   -- new
+ *          referral                     (10),  -- new
+ *          adminLimitExceeded           (11),  -- new
+ *          unavailableCriticalExtension (12),  -- new
+ *          confidentialityRequired      (13),  -- new
+ *          saslBindInProgress           (14),  -- new
+ *          noSuchAttribute              (16),
+ *          undefinedAttributeType       (17),
+ *          inappropriateMatching        (18),
+ *          constraintViolation          (19),
+ *          attributeOrValueExists       (20),
+ *          invalidAttributeSyntax       (21),
+ *          -- 22-31 unused --
+ *          noSuchObject                 (32),
+ *          aliasProblem                 (33),
+ *          invalidDNSyntax              (34),
+ *          -- 35 reserved for undefined isLeaf --
+ *          aliasDereferencingProblem    (36),
+ *          -- 37-47 unused --
+ *          inappropriateAuthentication  (48),
+ *          invalidCredentials           (49),
+ *          insufficientAccessRights     (50),
+ *          busy                         (51),
+ *          unavailable                  (52),
+ *          unwillingToPerform           (53),
+ *          loopDetect                   (54),
+ *          -- 55-63 unused --
+ *          namingViolation              (64),
+ *          objectClassViolation         (65),
+ *          notAllowedOnNonLeaf          (66),
+ *          notAllowedOnRDN              (67),
+ *          entryAlreadyExists           (68),
+ *          objectClassModsProhibited    (69),
+ *          -- 70 reserved for CLDAP --
+ *          affectsMultipleDSAs          (71), -- new
+ *          -- 72-79 unused --
+ *          other                        (80) },
+ *          -- 81-90 reserved for APIs --
  *  </code></pre>
  * All the result codes with the exception of success, compareFalse and
  * compareTrue are to be treated as meaning the operation could not be
@@ -173,9 +182,7 @@
     public static final int COMPARETRUE_VAL = 6;
     public static final int AUTHMETHODNOTSUPPORTED_VAL = 7;
     public static final int STRONGAUTHREQUIRED_VAL = 8;
-
-    // -- 9 reserved --
-
+    public static final int PARTIALRESULTS_VAL = 9;
     public static final int REFERRAL_VAL = 10;
     public static final int ADMINLIMITEXCEEDED_VAL = 11;
     public static final int UNAVAILABLECRITICALEXTENSION_VAL = 12;
@@ -245,6 +252,18 @@
     // operation request.
     // ------------------------------------------------------------------------
 
+
+    /**
+     * Servers sends this result code to LDAP v2 clients to refer them to
+     * another LDAP server. When sending this code to a client, the server
+     * includes a newline-delimited list of LDAP URLs that identify another
+     * LDAP server.  If the client identifies itself as an LDAP v3 client in
+     * the request, servers send an REFERRAL result code instead of this
+     * result code.
+     */
+    public static final ResultCodeEnum PARTIALRESULTS =
+            new ResultCodeEnum( "PARTIALRESULTS", PARTIALRESULTS_VAL ) ;
+
     /**
      * It is returned when the client operation completed successfully without
      * errors.   This code is one of 5 result codes that may be returned in
@@ -762,32 +781,64 @@
      * If the server can return an error, which is more specific than the
      * following general errors, then the specific error should be returned
      * instead.  This array only contains the OTHER error code at the present
-     * time.
+     * time. The set contains:
+     * <ul>
+     *   <li><a href="OTHER">OTHER</a></li>
+     * </ul>
      */
-    public static final ResultCodeEnum[] GENERAL_CODES = {OTHER} ;
+    public static final Set GENERAL_CODES = Collections.singleton( OTHER ) ;
 
     /**
      * Five result codes that may be returned in LDAPResult are not used to
      * indicate an error.  The first three codes, indicate to the client that
      * no further action is required in order to satisfy their request.  In
      * contrast, the last two errors require further action by the client in
-     * order to complete their original operation request.
-     */
-    public static final ResultCodeEnum[] NON_ERRONEOUS_CODES =
-    {
-        SUCCESS, COMPARETRUE, COMPAREFALSE, REFERRAL, SASLBINDINPROGRESS
-    } ;
+     * order to complete their original operation request. The set contains:
+     * <ul>
+     *   <li><a href="#SUCCESS">SUCCESS</a></li>
+     *   <li><a href="#COMPARETRUE">COMPARETRUE</a></li>
+     *   <li><a href="#COMPAREFALSE">COMPAREFALSE</a></li>
+     *   <li><a href="#REFERRAL">REFERRAL</a></li>
+     *   <li><a href="#SASLBINDINPROGRESS">SASLBINDINPROGRESS</a></li>
+     * </ul>
+     */
+    public static final Set NON_ERRONEOUS_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( SUCCESS );
+        set.add( COMPARETRUE );
+        set.add( COMPAREFALSE );
+        set.add( REFERRAL );
+        set.add( SASLBINDINPROGRESS );
+        NON_ERRONEOUS_CODES = Collections.unmodifiableSet( set );
+    }
 
     /**
      * Contains the set of error codes associated with attribute problems.  An
      * attribute error reports a problem related to an attribute specified by
-     * the client in their request message.
-     */
-    public static final ResultCodeEnum[] ATTRIBUTE_CODES =
-    {
-        NOSUCHATTRIBUTE, UNDEFINEDATTRIBUTETYPE, INAPPROPRIATEMATCHING,
-        CONSTRAINTVIOLATION, ATTRIBUTEORVALUEEXISTS, INVALIDATTRIBUTESYNTAX
-    } ;
+     * the client in their request message. The set contains:
+     * <ul>
+     *   <li><a href="#NOSUCHATTRIBUTE">NOSUCHATTRIBUTE</a></li>
+     *   <li><a href="#UNDEFINEDATTRIBUTETYPE">UNDEFINEDATTRIBUTETYPE</a></li>
+     *   <li><a href="#INAPPROPRIATEMATCHING">INAPPROPRIATEMATCHING</a></li>
+     *   <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li>
+     *   <li><a href="#ATTRIBUTEORVALUEEXISTS">ATTRIBUTEORVALUEEXISTS</a></li>
+     *   <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li>
+     * </ul>
+     */
+    public static final Set ATTRIBUTE_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( NOSUCHATTRIBUTE );
+        set.add( UNDEFINEDATTRIBUTETYPE );
+        set.add( INAPPROPRIATEMATCHING );
+        set.add( CONSTRAINTVIOLATION );
+        set.add( ATTRIBUTEORVALUEEXISTS );
+        set.add( INVALIDATTRIBUTESYNTAX );
+        ATTRIBUTE_CODES = Collections.unmodifiableSet( set );
+    }
 
     /**
      * Stores the set of error codes associated with name problems.  A name
@@ -801,175 +852,721 @@
      * dereferenced of the resulting name, as defined in section 12.5 of X.511
      * [X511]. The matchedDN field is to be set to a zero length string with
      * all other result codes [RFC2251, Section 4.1.10].
-     */
-    public static final ResultCodeEnum[] NAME_CODES =
-    {
-        NOSUCHOBJECT, ALIASPROBLEM, INVALIDDNSYNTAX
-    } ;
+     * The set contains:
+     * <ul>
+     *   <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li>
+     *   <li><a href="#ALIASPROBLEM">ALIASPROBLEM</a></li>
+     *   <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li>
+     * </ul>
+     */
+    public static final Set NAME_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( NOSUCHOBJECT );
+        set.add( ALIASPROBLEM );
+        set.add( INVALIDDNSYNTAX );
+        NAME_CODES = Collections.unmodifiableSet( set );
+    }
 
     /**
      * Stores all the result codes associated with security related problems. A
      * security error reports a problem in carrying out an operation for
-     * security reasons [X511, Section 12.7].
-     */
-    public static final ResultCodeEnum[] SECURITY_CODES =
-    {
-        INVALIDCREDENTIALS, STRONGAUTHREQUIRED, AUTHMETHODNOTSUPPORTED,
-        CONFIDENTIALITYREQUIRED, INSUFFICIENTACCESSRIGHTS,
-        ALIASDEREFERENCINGPROBLEM, INAPPROPRIATEAUTHENTICATION
-    } ;
+     * security reasons [X511, Section 12.7]. The set contains:
+     * <ul>
+     *   <li><a href="#INVALIDCREDENTIALS">INVALIDCREDENTIALS</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li>
+     *   <li><a href="#AUTHMETHODNOTSUPPORTED">AUTHMETHODNOTSUPPORTED</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li>
+     *   <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li>
+     *   <li><a href="#ALIASDEREFERENCINGPROBLEM">ALIASDEREFERENCINGPROBLEM</a></li>
+     *   <li><a href="#INAPPROPRIATEAUTHENTICATION">INAPPROPRIATEAUTHENTICATION</a></li>
+     * </ul>
+     */
+    public static final Set SECURITY_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( INVALIDCREDENTIALS );
+        set.add( STRONGAUTHREQUIRED );
+        set.add( AUTHMETHODNOTSUPPORTED );
+        set.add( CONFIDENTIALITYREQUIRED );
+        set.add( INSUFFICIENTACCESSRIGHTS );
+        set.add( ALIASDEREFERENCINGPROBLEM );
+        set.add( INAPPROPRIATEAUTHENTICATION );
+        SECURITY_CODES = Collections.unmodifiableSet( set );
+    }
 
     /**
      * A service error reports a problem related to the provision of the
-     * service [X511, Section 12.8].  This array stores all error codes
+     * service [X511, Section 12.8].  This set stores all error codes
      * related to service problems.
-     */
-    public static final ResultCodeEnum[] SERVICE_CODES =
-    {
-        BUSY, LOOPDETECT, UNAVAILABLE, PROTOCOLERROR, OPERATIONSERROR,
-        TIMELIMITEXCEEDED, SIZELIMITEXCEEDED, ADMINLIMITEXCEEDED,
-        UNWILLINGTOPERFORM, UNAVAILABLECRITICALEXTENSION
-    } ;
+     * The set contains:
+     * <ul>
+     *   <li><a href="#BUSY">BUSY</a></li>
+     *   <li><a href="#LOOPDETECT">LOOPDETECT</a></li>
+     *   <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
+     *   <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li>
+     *   <li><a href="#OPERATIONSERROR">OPERATIONSERROR</a></li>
+     *   <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li>
+     *   <li><a href="#SIZELIMITEXCEEDED">SIZELIMITEXCEEDED</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li>
+     * </ul>
+     */
+    public static final Set SERVICE_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( BUSY );
+        set.add( LOOPDETECT );
+        set.add( UNAVAILABLE );
+        set.add( PROTOCOLERROR );
+        set.add( OPERATIONSERROR );
+        set.add( TIMELIMITEXCEEDED );
+        set.add( SIZELIMITEXCEEDED );
+        set.add( ADMINLIMITEXCEEDED );
+        set.add( UNWILLINGTOPERFORM );
+        set.add( UNAVAILABLECRITICALEXTENSION );
+        SERVICE_CODES = Collections.unmodifiableSet( set );
+    }
 
     /**
      * An update error reports problems related to attempts to add, delete, or
-     * modify information in the DIB [X511, Section 12.9].  This array
+     * modify information in the DIB [X511, Section 12.9].  This set
      * contains the category of update errors.
-     */
-    public static final ResultCodeEnum[] UPDATE_CODES =
-    {
-        NAMINGVIOLATION, OBJECTCLASSVIOLATION, NOTALLOWEDONNONLEAF,
-        NOTALLOWEDONRDN, ENTRYALREADYEXISTS, OBJECTCLASSMODSPROHIBITED,
-        AFFECTSMULTIPLEDSAS
-    } ;
+     * <ul>
+     *   <li><a href="#NAMINGVIOLATION">NAMINGVIOLATION</a></li>
+     *   <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li>
+     *   <li><a href="#NOTALLOWEDONNONLEAF">NOTALLOWEDONNONLEAF</a></li>
+     *   <li><a href="#NOTALLOWEDONRDN">NOTALLOWEDONRDN</a></li>
+     *   <li><a href="#ENTRYALREADYEXISTS">ENTRYALREADYEXISTS</a></li>
+     *   <li><a href="#OBJECTCLASSMODSPROHIBITED">OBJECTCLASSMODSPROHIBITED</a></li>
+     *   <li><a href="#AFFECTSMULTIPLEDSAS">AFFECTSMULTIPLEDSAS</a></li>
+     * </ul>
+     */
+    public static final Set UPDATE_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( NAMINGVIOLATION );
+        set.add( OBJECTCLASSVIOLATION );
+        set.add( NOTALLOWEDONNONLEAF );
+        set.add( NOTALLOWEDONRDN );
+        set.add( ENTRYALREADYEXISTS );
+        set.add( OBJECTCLASSMODSPROHIBITED );
+        set.add( AFFECTSMULTIPLEDSAS );
+        UPDATE_CODES = Collections.unmodifiableSet( set );
+    }
 
     // ------------------------------------------------------------------------
     // Result Codes Categorized by Request Type
     // ------------------------------------------------------------------------
 
-    /** Array of result code enumerations common to all operations. */
-    public static final ResultCodeEnum[] COMMON_CODES =
-    {
-        BUSY, OTHER, REFERRAL, LOOPDETECT, UNAVAILABLE, PROTOCOLERROR,
-        TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED, STRONGAUTHREQUIRED,
-        UNWILLINGTOPERFORM, CONFIDENTIALITYREQUIRED,
-        UNAVAILABLECRITICALEXTENSION
-    } ;
-
-    /** Array of result code enumerations resulting from bind operations. */
-    public static final ResultCodeEnum[] BIND_CODES =
-    {
-        BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, PROTOCOLERROR,
-        INVALIDDNSYNTAX, TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED,
-        UNWILLINGTOPERFORM, SASLBINDINPROGRESS, STRONGAUTHREQUIRED,
-        INVALIDCREDENTIALS, AUTHMETHODNOTSUPPORTED, CONFIDENTIALITYREQUIRED,
-        INAPPROPRIATEAUTHENTICATION, UNAVAILABLECRITICALEXTENSION
-    } ;
+    /**
+     * A set of result code enumerations common to all operations.
+     * The set contains:
+     * <ul>
+     *   <li><a href="#BUSY">BUSY</a></li>
+     *   <li><a href="#OTHER">OTHER</a></li>
+     *   <li><a href="#REFERRAL">REFERRAL</a></li>
+     *   <li><a href="#LOOPDETECT">LOOPDETECT</a></li>
+     *   <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
+     *   <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li>
+     *   <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li>
+     * </ul>
+     */
+    public static final Set COMMON_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( BUSY );
+        set.add( OTHER );
+        set.add( REFERRAL );
+        set.add( LOOPDETECT );
+        set.add( UNAVAILABLE );
+        set.add( PROTOCOLERROR );
+        set.add( TIMELIMITEXCEEDED );
+        set.add( ADMINLIMITEXCEEDED );
+        set.add( STRONGAUTHREQUIRED );
+        set.add( UNWILLINGTOPERFORM );
+        set.add( CONFIDENTIALITYREQUIRED );
+        set.add( UNAVAILABLECRITICALEXTENSION );
+        COMMON_CODES = Collections.unmodifiableSet( set );
+    }
 
-    /** Array of result code enumerations resulting from search operations. */
-    public static final ResultCodeEnum[] SEARCH_CODES =
-    {
-        BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, NOSUCHOBJECT,
-        ALIASPROBLEM, PROTOCOLERROR, INVALIDDNSYNTAX, SIZELIMITEXCEEDED,
-        TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED, STRONGAUTHREQUIRED,
-        UNWILLINGTOPERFORM, INAPPROPRIATEMATCHING, CONFIDENTIALITYREQUIRED,
-        INSUFFICIENTACCESSRIGHTS, ALIASDEREFERENCINGPROBLEM,
-        UNAVAILABLECRITICALEXTENSION
-    } ;
+    /**
+     * A set of result code enumerations that may result from bind operations.
+     * The set contains:
+     * <ul>
+     *   <li><a href="#BUSY">BUSY</a></li>
+     *   <li><a href="#OTHER">OTHER</a></li>
+     *   <li><a href="#SUCCESS">SUCCESS</a></li>
+     *   <li><a href="#REFERRAL">REFERRAL</a></li>
+     *   <li><a href="#LOOPDETECT">LOOPDETECT</a></li>
+     *   <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
+     *   <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li>
+     *   <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li>
+     *   <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li>
+     *   <li><a href="#SASLBINDINPROGRESS">SASLBINDINPROGRESS</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li>
+     *   <li><a href="#INVALIDCREDENTIALS">INVALIDCREDENTIALS</a></li>
+     *   <li><a href="#AUTHMETHODNOTSUPPORTED">AUTHMETHODNOTSUPPORTED</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li>
+     *   <li><a href="#INAPPROPRIATEAUTHENTICATION">INAPPROPRIATEAUTHENTICATION</a></li>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li>
+     * </ul>
+     */
+    public static final Set BIND_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( BUSY );
+        set.add( OTHER );
+        set.add( SUCCESS );
+        set.add( REFERRAL );
+        set.add( LOOPDETECT );
+        set.add( UNAVAILABLE );
+        set.add( PROTOCOLERROR );
+        set.add( INVALIDDNSYNTAX );
+        set.add( TIMELIMITEXCEEDED );
+        set.add( ADMINLIMITEXCEEDED );
+        set.add( UNWILLINGTOPERFORM );
+        set.add( SASLBINDINPROGRESS );
+        set.add( STRONGAUTHREQUIRED );
+        set.add( INVALIDCREDENTIALS );
+        set.add( AUTHMETHODNOTSUPPORTED );
+        set.add( CONFIDENTIALITYREQUIRED );
+        set.add( INAPPROPRIATEAUTHENTICATION );
+        set.add( UNAVAILABLECRITICALEXTENSION );
+        BIND_CODES = Collections.unmodifiableSet( set );
+    }
 
-    /** Array of result code enumerations resulting from modify operations. */
-    public static final ResultCodeEnum[] MODIFY_CODES =
-    {
-        BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, NOSUCHOBJECT,
-        PROTOCOLERROR, INVALIDDNSYNTAX, NOTALLOWEDONRDN, NOSUCHATTRIBUTE,
-        TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED, STRONGAUTHREQUIRED,
-        UNWILLINGTOPERFORM, CONSTRAINTVIOLATION, OBJECTCLASSVIOLATION,
-        INVALIDATTRIBUTESYNTAX, UNDEFINEDATTRIBUTETYPE, ATTRIBUTEORVALUEEXISTS,
-        CONFIDENTIALITYREQUIRED, INSUFFICIENTACCESSRIGHTS,
-        OBJECTCLASSMODSPROHIBITED, UNAVAILABLECRITICALEXTENSION
-    } ;
+    /**
+     * A set of result code enumerations that may result from search operations.
+     * The set contains:
+     * <ul>
+     *   <li><a href="#BUSY">BUSY</a></li>
+     *   <li><a href="#OTHER">OTHER</a></li>
+     *   <li><a href="#SUCCESS">SUCCESS</a></li>
+     *   <li><a href="#REFERRAL">REFERRAL</a></li>
+     *   <li><a href="#LOOPDETECT">LOOPDETECT</a></li>
+     *   <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
+     *   <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li>
+     *   <li><a href="#ALIASPROBLEM">ALIASPROBLEM</a></li>
+     *   <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li>
+     *   <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li>
+     *   <li><a href="#SIZELIMITEXCEEDED">SIZELIMITEXCEEDED</a></li>
+     *   <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li>
+     *   <li><a href="#INAPPROPRIATEMATCHING">INAPPROPRIATEMATCHING</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li>
+     *   <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li>
+     *   <li><a href="#ALIASDEREFERENCINGPROBLEM">ALIASDEREFERENCINGPROBLEM</a></li>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li>
+     * </ul>
+     */
+    public static final Set SEARCH_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( BUSY );
+        set.add( OTHER );
+        set.add( SUCCESS );
+        set.add( REFERRAL );
+        set.add( LOOPDETECT );
+        set.add( UNAVAILABLE );
+        set.add( NOSUCHOBJECT );
+        set.add( ALIASPROBLEM );
+        set.add( PROTOCOLERROR );
+        set.add( INVALIDDNSYNTAX );
+        set.add( SIZELIMITEXCEEDED );
+        set.add( TIMELIMITEXCEEDED );
+        set.add( ADMINLIMITEXCEEDED );
+        set.add( STRONGAUTHREQUIRED );
+        set.add( UNWILLINGTOPERFORM );
+        set.add( INAPPROPRIATEMATCHING );
+        set.add( CONFIDENTIALITYREQUIRED );
+        set.add( INSUFFICIENTACCESSRIGHTS );
+        set.add( ALIASDEREFERENCINGPROBLEM );
+        set.add( UNAVAILABLECRITICALEXTENSION );
+        SEARCH_CODES = Collections.unmodifiableSet( set );
+    }
 
-    /** Array of result code enumerations resulting from add operations. */
-    public static final ResultCodeEnum[] ADD_CODES =
-    {
-        BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, NOSUCHOBJECT,
-        PROTOCOLERROR, NAMINGVIOLATION, INVALIDDNSYNTAX, TIMELIMITEXCEEDED,
-        ADMINLIMITEXCEEDED, STRONGAUTHREQUIRED, UNWILLINGTOPERFORM,
-        ENTRYALREADYEXISTS, CONSTRAINTVIOLATION, OBJECTCLASSVIOLATION,
-        INVALIDATTRIBUTESYNTAX, ATTRIBUTEORVALUEEXISTS, UNDEFINEDATTRIBUTETYPE,
-        CONFIDENTIALITYREQUIRED, INSUFFICIENTACCESSRIGHTS,
-        UNAVAILABLECRITICALEXTENSION
-    } ;
+    /**
+     * A set of result code enumerations that may result from modify operations.
+     * The set contains:
+     * <ul>
+     *   <li><a href="#BUSY">BUSY</a></li>
+     *   <li><a href="#OTHER">OTHER</a></li>
+     *   <li><a href="#SUCCESS">SUCCESS</a></li>
+     *   <li><a href="#REFERRAL">REFERRAL</a></li>
+     *   <li><a href="#LOOPDETECT">LOOPDETECT</a></li>
+     *   <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
+     *   <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li>
+     *   <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li>
+     *   <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li>
+     *   <li><a href="#NOTALLOWEDONRDN">NOTALLOWEDONRDN</a></li>
+     *   <li><a href="#NOSUCHATTRIBUTE">NOSUCHATTRIBUTE</a></li>
+     *   <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li>
+     *   <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li>
+     *   <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li>
+     *   <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li>
+     *   <li><a href="#UNDEFINEDATTRIBUTETYPE">UNDEFINEDATTRIBUTETYPE</a></li>
+     *   <li><a href="#ATTRIBUTEORVALUEEXISTS">ATTRIBUTEORVALUEEXISTS</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li>
+     *   <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li>
+     *   <li><a href="#OBJECTCLASSMODSPROHIBITED">OBJECTCLASSMODSPROHIBITED</a></li>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li>
+     * </ul>
+     */
+    public static final Set MODIFY_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( BUSY );
+        set.add( OTHER );
+        set.add( SUCCESS );
+        set.add( REFERRAL );
+        set.add( LOOPDETECT );
+        set.add( UNAVAILABLE );
+        set.add( NOSUCHOBJECT );
+        set.add( PROTOCOLERROR );
+        set.add( INVALIDDNSYNTAX );
+        set.add( NOTALLOWEDONRDN );
+        set.add( NOSUCHATTRIBUTE );
+        set.add( TIMELIMITEXCEEDED );
+        set.add( ADMINLIMITEXCEEDED );
+        set.add( STRONGAUTHREQUIRED );
+        set.add( UNWILLINGTOPERFORM );
+        set.add( CONSTRAINTVIOLATION );
+        set.add( OBJECTCLASSVIOLATION );
+        set.add( INVALIDATTRIBUTESYNTAX );
+        set.add( UNDEFINEDATTRIBUTETYPE );
+        set.add( ATTRIBUTEORVALUEEXISTS );
+        set.add( CONFIDENTIALITYREQUIRED );
+        set.add( INSUFFICIENTACCESSRIGHTS );
+        set.add( OBJECTCLASSMODSPROHIBITED );
+        set.add( UNAVAILABLECRITICALEXTENSION );
+        MODIFY_CODES = Collections.unmodifiableSet( set );
+    }
 
-    /** Array of result code enumerations resulting from delete operations. */
-    public static final ResultCodeEnum[] DELETE_CODES =
-    {
-        BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, NOSUCHOBJECT,
-        PROTOCOLERROR, INVALIDDNSYNTAX, TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED,
-        STRONGAUTHREQUIRED, UNWILLINGTOPERFORM, NOTALLOWEDONNONLEAF,
-        CONFIDENTIALITYREQUIRED, INSUFFICIENTACCESSRIGHTS,
-        UNAVAILABLECRITICALEXTENSION
+    /**
+     * A set of result code enumerations that may result from add operations.
+     * The set contains:
+     * <ul>
+     *   <li><a href="#BUSY">BUSY</a></li>
+     *   <li><a href="#OTHER">OTHER</a></li>
+     *   <li><a href="#SUCCESS">SUCCESS</a></li>
+     *   <li><a href="#REFERRAL">REFERRAL</a></li>
+     *   <li><a href="#LOOPDETECT">LOOPDETECT</a></li>
+     *   <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
+     *   <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li>
+     *   <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li>
+     *   <li><a href="#NAMINGVIOLATION">NAMINGVIOLATION</a></li>
+     *   <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li>
+     *   <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li>
+     *   <li><a href="#ENTRYALREADYEXISTS">ENTRYALREADYEXISTS</a></li>
+     *   <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li>
+     *   <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li>
+     *   <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li>
+     *   <li><a href="#ATTRIBUTEORVALUEEXISTS">ATTRIBUTEORVALUEEXISTS</a></li>
+     *   <li><a href="#UNDEFINEDATTRIBUTETYPE">UNDEFINEDATTRIBUTETYPE</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li>
+     *   <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li>
+     * </ul>
+     */
+    public static final Set ADD_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( BUSY ); 
+        set.add( OTHER ); 
+        set.add( SUCCESS ); 
+        set.add( REFERRAL ); 
+        set.add( LOOPDETECT ); 
+        set.add( UNAVAILABLE ); 
+        set.add( NOSUCHOBJECT );
+        set.add( PROTOCOLERROR ); 
+        set.add( NAMINGVIOLATION ); 
+        set.add( INVALIDDNSYNTAX ); 
+        set.add( TIMELIMITEXCEEDED );
+        set.add( ADMINLIMITEXCEEDED ); 
+        set.add( STRONGAUTHREQUIRED ); 
+        set.add( UNWILLINGTOPERFORM );
+        set.add( ENTRYALREADYEXISTS ); 
+        set.add( CONSTRAINTVIOLATION ); 
+        set.add( OBJECTCLASSVIOLATION );
+        set.add( INVALIDATTRIBUTESYNTAX ); 
+        set.add( ATTRIBUTEORVALUEEXISTS ); 
+        set.add( UNDEFINEDATTRIBUTETYPE );
+        set.add( CONFIDENTIALITYREQUIRED ); 
+        set.add( INSUFFICIENTACCESSRIGHTS );
+        set.add( UNAVAILABLECRITICALEXTENSION );
+        ADD_CODES = Collections.unmodifiableSet( set );
     } ;
 
-    /** Array of result code enumerations resulting from modifyDn operations. */
-    public static final ResultCodeEnum[] MODIFYDN_CODES =
-    {
-        BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, NOSUCHOBJECT,
-        PROTOCOLERROR, INVALIDDNSYNTAX, NAMINGVIOLATION, TIMELIMITEXCEEDED,
-        ENTRYALREADYEXISTS, ADMINLIMITEXCEEDED, STRONGAUTHREQUIRED,
-        UNWILLINGTOPERFORM, NOTALLOWEDONNONLEAF, AFFECTSMULTIPLEDSAS,
-        CONSTRAINTVIOLATION, OBJECTCLASSVIOLATION, CONFIDENTIALITYREQUIRED,
-        INSUFFICIENTACCESSRIGHTS, UNAVAILABLECRITICALEXTENSION
+    /**
+     * A set of result code enumerations that may result from delete operations.
+     * The set may contain:
+     * <ul>
+     *   <li><a href="#BUSY">BUSY</a></li>
+     *   <li><a href="#OTHER">OTHER</a></li>
+     *   <li><a href="#SUCCESS">SUCCESS</a></li>
+     *   <li><a href="#REFERRAL">REFERRAL</a></li>
+     *   <li><a href="#LOOPDETECT">LOOPDETECT</a></li>
+     *   <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
+     *   <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li>
+     *   <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li>
+     *   <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li>
+     *   <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li>
+     *   <li><a href="#NOTALLOWEDONNONLEAF">NOTALLOWEDONNONLEAF</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li>
+     *   <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li>
+     * </ul>
+     */
+    public static final Set DELETE_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( BUSY ); 
+        set.add( OTHER ); 
+        set.add( SUCCESS ); 
+        set.add( REFERRAL ); 
+        set.add( LOOPDETECT ); 
+        set.add( UNAVAILABLE ); 
+        set.add( NOSUCHOBJECT );
+        set.add( PROTOCOLERROR ); 
+        set.add( INVALIDDNSYNTAX ); 
+        set.add( TIMELIMITEXCEEDED ); 
+        set.add( ADMINLIMITEXCEEDED );
+        set.add( STRONGAUTHREQUIRED ); 
+        set.add( UNWILLINGTOPERFORM ); 
+        set.add( NOTALLOWEDONNONLEAF );
+        set.add( CONFIDENTIALITYREQUIRED ); 
+        set.add( INSUFFICIENTACCESSRIGHTS );
+        set.add( UNAVAILABLECRITICALEXTENSION );
+        DELETE_CODES = Collections.unmodifiableSet( set );
     } ;
 
-    /** Array of result code enumerations resulting from compare operations. */
-    public static final ResultCodeEnum[] COMPARE_CODES =
-    {
-        BUSY, OTHER, REFERRAL, LOOPDETECT, UNAVAILABLE, COMPARETRUE,
-        COMPAREFALSE, NOSUCHOBJECT, PROTOCOLERROR, NOSUCHATTRIBUTE,
-        INVALIDDNSYNTAX, TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED,
-        STRONGAUTHREQUIRED, UNWILLINGTOPERFORM, INVALIDATTRIBUTESYNTAX,
-        CONFIDENTIALITYREQUIRED, INSUFFICIENTACCESSRIGHTS,
-        UNAVAILABLECRITICALEXTENSION
-    } ;
+    /**
+     * A set of result code enumerations resulting from modifyDn operations.
+     * The set contains:
+     * <ul>
+     *   <li><a href="#BUSY">BUSY</a></li>
+     *   <li><a href="#OTHER">OTHER</a></li>
+     *   <li><a href="#SUCCESS">SUCCESS</a></li>
+     *   <li><a href="#REFERRAL">REFERRAL</a></li>
+     *   <li><a href="#LOOPDETECT">LOOPDETECT</a></li>
+     *   <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
+     *   <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li>
+     *   <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li>
+     *   <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li>
+     *   <li><a href="#NAMINGVIOLATION">NAMINGVIOLATION</a></li>
+     *   <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li>
+     *   <li><a href="#ENTRYALREADYEXISTS">ENTRYALREADYEXISTS</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li>
+     *   <li><a href="#NOTALLOWEDONNONLEAF">NOTALLOWEDONNONLEAF</a></li>
+     *   <li><a href="#AFFECTSMULTIPLEDSAS">AFFECTSMULTIPLEDSAS</a></li>
+     *   <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li>
+     *   <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li>
+     *   <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li>
+     * </ul>
+     */
+    public static final Set MODIFYDN_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( BUSY );
+        set.add( OTHER );
+        set.add( SUCCESS );
+        set.add( REFERRAL );
+        set.add( LOOPDETECT );
+        set.add( UNAVAILABLE );
+        set.add( NOSUCHOBJECT );
+        set.add( PROTOCOLERROR );
+        set.add( INVALIDDNSYNTAX );
+        set.add( NAMINGVIOLATION );
+        set.add( TIMELIMITEXCEEDED );
+        set.add( ENTRYALREADYEXISTS );
+        set.add( ADMINLIMITEXCEEDED );
+        set.add( STRONGAUTHREQUIRED );
+        set.add( UNWILLINGTOPERFORM );
+        set.add( NOTALLOWEDONNONLEAF );
+        set.add( AFFECTSMULTIPLEDSAS );
+        set.add( CONSTRAINTVIOLATION );
+        set.add( OBJECTCLASSVIOLATION );
+        set.add( CONFIDENTIALITYREQUIRED );
+        set.add( INSUFFICIENTACCESSRIGHTS );
+        set.add( UNAVAILABLECRITICALEXTENSION );
+        MODIFYDN_CODES = Collections.unmodifiableSet( set );
+    } 
+
+    /**
+     * A set of result code enumerations that may result from compare
+     * operations.  The set contains:
+     * <ul>
+     *   <li><a href="#OPERATIONSERROR">OPERATIONSERROR</a></li>
+     *   <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li>
+     *   <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li>
+     *   <li><a href="#COMPAREFALSE">COMPAREFALSE</a></li>
+     *   <li><a href="#COMPARETRUE">COMPARETRUE</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li>
+     *   <li><a href="#NOSUCHATTRIBUTE">NOSUCHATTRIBUTE</a></li>
+     *   <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li>
+     *   <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li>
+     *   <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li>
+     *   <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li>
+     *   <li><a href="#BUSY">BUSY</a></li>
+     *   <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li>
+     *   <li><a href="#LOOPDETECT">LOOPDETECT</a></li>
+     *   <li><a href="#REFERRAL">REFERRAL</a></li>
+     *   <li><a href="#OTHER">OTHER</a></li>
+     * </ul>
+     */
+    public static final Set COMPARE_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( OPERATIONSERROR );
+        set.add( PROTOCOLERROR );
+        set.add( TIMELIMITEXCEEDED );
+        set.add( COMPAREFALSE );
+        set.add( COMPARETRUE );
+        set.add( STRONGAUTHREQUIRED );
+        set.add( ADMINLIMITEXCEEDED );
+        set.add( UNAVAILABLECRITICALEXTENSION );
+        set.add( CONFIDENTIALITYREQUIRED );
+        set.add( NOSUCHATTRIBUTE );
+        set.add( INVALIDATTRIBUTESYNTAX );
+        set.add( NOSUCHOBJECT );
+        set.add( INVALIDDNSYNTAX );
+        set.add( INSUFFICIENTACCESSRIGHTS );
+        set.add( BUSY );
+        set.add( UNAVAILABLE );
+        set.add( UNWILLINGTOPERFORM );
+        set.add( LOOPDETECT );
+        set.add( REFERRAL );
+        set.add( OTHER );
+        COMPARE_CODES = Collections.unmodifiableSet( set );
+    }
 
-    /** Array of result code enumerations resulting from extended operations. */
-    public static final ResultCodeEnum[] EXTENDED_CODES =
-    {
-        SUCCESS, OPERATIONSERROR, PROTOCOLERROR, TIMELIMITEXCEEDED,
-        SIZELIMITEXCEEDED, COMPAREFALSE, COMPARETRUE, AUTHMETHODNOTSUPPORTED,
-        STRONGAUTHREQUIRED, REFERRAL, ADMINLIMITEXCEEDED,
-        UNAVAILABLECRITICALEXTENSION, CONFIDENTIALITYREQUIRED,
-        SASLBINDINPROGRESS, NOSUCHATTRIBUTE, UNDEFINEDATTRIBUTETYPE,
-        INAPPROPRIATEMATCHING, CONSTRAINTVIOLATION, ATTRIBUTEORVALUEEXISTS,
-        INVALIDATTRIBUTESYNTAX, NOSUCHOBJECT, ALIASPROBLEM, INVALIDDNSYNTAX,
-        ALIASDEREFERENCINGPROBLEM, INAPPROPRIATEAUTHENTICATION,
-        INVALIDCREDENTIALS, INSUFFICIENTACCESSRIGHTS, BUSY, UNAVAILABLE,
-        UNWILLINGTOPERFORM, LOOPDETECT, NAMINGVIOLATION, OBJECTCLASSVIOLATION,
-        NOTALLOWEDONNONLEAF, NOTALLOWEDONRDN, ENTRYALREADYEXISTS,
-        OBJECTCLASSMODSPROHIBITED, AFFECTSMULTIPLEDSAS, OTHER,
-    } ;
+    /**
+     * A set of result code enumerations that could result from extended
+     * operations.  The set contains:
+     * <ul>
+     *   <li></li>
+     *   <li><a href="#SUCCESS">SUCCESS</a></li>
+     *   <li><a href="#OPERATIONSERROR">OPERATIONSERROR</a></li>
+     *   <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li>
+     *   <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li>
+     *   <li><a href="#SIZELIMITEXCEEDED">SIZELIMITEXCEEDED</a></li>
+     *   <li><a href="#COMPAREFALSE">COMPAREFALSE</a></li>
+     *   <li><a href="#COMPARETRUE">COMPARETRUE</a></li>
+     *   <li><a href="#AUTHMETHODNOTSUPPORTED">AUTHMETHODNOTSUPPORTED</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li>
+     *   <li><a href="#REFERRAL">REFERRAL</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li>
+     *   <li><a href="#SASLBINDINPROGRESS">SASLBINDINPROGRESS</a></li>
+     *   <li><a href="#NOSUCHATTRIBUTE">NOSUCHATTRIBUTE</a></li>
+     *   <li><a href="#UNDEFINEDATTRIBUTETYPE">UNDEFINEDATTRIBUTETYPE</a></li>
+     *   <li><a href="#INAPPROPRIATEMATCHING">INAPPROPRIATEMATCHING</a></li>
+     *   <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li>
+     *   <li><a href="#ATTRIBUTEORVALUEEXISTS">ATTRIBUTEORVALUEEXISTS</a></li>
+     *   <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li>
+     *   <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li>
+     *   <li><a href="#ALIASPROBLEM">ALIASPROBLEM</a></li>
+     *   <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li>
+     *   <li><a href="#ALIASDEREFERENCINGPROBLEM">ALIASDEREFERENCINGPROBLEM</a></li>
+     *   <li><a href="#INAPPROPRIATEAUTHENTICATION">INAPPROPRIATEAUTHENTICATION</a></li>
+     *   <li><a href="#INVALIDCREDENTIALS">INVALIDCREDENTIALS</a></li>
+     *   <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li>
+     *   <li><a href="#BUSY">BUSY</a></li>
+     *   <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li>
+     *   <li><a href="#LOOPDETECT">LOOPDETECT</a></li>
+     *   <li><a href="#NAMINGVIOLATION">NAMINGVIOLATION</a></li>
+     *   <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li>
+     *   <li><a href="#NOTALLOWEDONNONLEAF">NOTALLOWEDONNONLEAF</a></li>
+     *   <li><a href="#NOTALLOWEDONRDN">NOTALLOWEDONRDN</a></li>
+     *   <li><a href="#ENTRYALREADYEXISTS">ENTRYALREADYEXISTS</a></li>
+     *   <li><a href="#OBJECTCLASSMODSPROHIBITED">OBJECTCLASSMODSPROHIBITED</a></li>
+     *   <li><a href="#AFFECTSMULTIPLEDSAS">AFFECTSMULTIPLEDSAS</a></li>
+     *   <li><a href="#OTHER">OTHER</a></li>
+     * </ul>
+     */
+    public static final Set EXTENDED_CODES;
+    static 
+    {
+        HashSet set = new HashSet();
+        set.add( SUCCESS );
+        set.add( OPERATIONSERROR );
+        set.add( PROTOCOLERROR );
+        set.add( TIMELIMITEXCEEDED );
+        set.add( SIZELIMITEXCEEDED );
+        set.add( COMPAREFALSE );
+        set.add( COMPARETRUE );
+        set.add( AUTHMETHODNOTSUPPORTED );
+        set.add( STRONGAUTHREQUIRED );
+        set.add( REFERRAL );
+        set.add( ADMINLIMITEXCEEDED );
+        set.add( UNAVAILABLECRITICALEXTENSION );
+        set.add( CONFIDENTIALITYREQUIRED );
+        set.add( SASLBINDINPROGRESS );
+        set.add( NOSUCHATTRIBUTE );
+        set.add( UNDEFINEDATTRIBUTETYPE );
+        set.add( INAPPROPRIATEMATCHING );
+        set.add( CONSTRAINTVIOLATION );
+        set.add( ATTRIBUTEORVALUEEXISTS );
+        set.add( INVALIDATTRIBUTESYNTAX );
+        set.add( NOSUCHOBJECT );
+        set.add( ALIASPROBLEM );
+        set.add( INVALIDDNSYNTAX );
+        set.add( ALIASDEREFERENCINGPROBLEM );
+        set.add( INAPPROPRIATEAUTHENTICATION );
+        set.add( INVALIDCREDENTIALS );
+        set.add( INSUFFICIENTACCESSRIGHTS );
+        set.add( BUSY );
+        set.add( UNAVAILABLE );
+        set.add( UNWILLINGTOPERFORM );
+        set.add( LOOPDETECT );
+        set.add( NAMINGVIOLATION );
+        set.add( OBJECTCLASSVIOLATION );
+        set.add( NOTALLOWEDONNONLEAF );
+        set.add( NOTALLOWEDONRDN );
+        set.add( ENTRYALREADYEXISTS );
+        set.add( OBJECTCLASSMODSPROHIBITED );
+        set.add( AFFECTSMULTIPLEDSAS );
+        set.add( OTHER );
+        EXTENDED_CODES = Collections.unmodifiableSet( set );
+    }
 
     // ------------------------------------------------------------------------
     // All Result Codes
     // ------------------------------------------------------------------------
 
-    /** Array of all result code enumerations. */
-    public static final ResultCodeEnum[] ALL_CODES =
-    {
-        SUCCESS, OPERATIONSERROR, PROTOCOLERROR, TIMELIMITEXCEEDED,
-        SIZELIMITEXCEEDED, COMPAREFALSE, COMPARETRUE, AUTHMETHODNOTSUPPORTED,
-        STRONGAUTHREQUIRED, REFERRAL, ADMINLIMITEXCEEDED,
-        UNAVAILABLECRITICALEXTENSION, CONFIDENTIALITYREQUIRED,
-        SASLBINDINPROGRESS, NOSUCHATTRIBUTE, UNDEFINEDATTRIBUTETYPE,
-        INAPPROPRIATEMATCHING, CONSTRAINTVIOLATION, ATTRIBUTEORVALUEEXISTS,
-        INVALIDATTRIBUTESYNTAX, NOSUCHOBJECT, ALIASPROBLEM, INVALIDDNSYNTAX,
-        ALIASDEREFERENCINGPROBLEM, INAPPROPRIATEAUTHENTICATION,
-        INVALIDCREDENTIALS, INSUFFICIENTACCESSRIGHTS, BUSY, UNAVAILABLE,
-        UNWILLINGTOPERFORM, LOOPDETECT, NAMINGVIOLATION, OBJECTCLASSVIOLATION,
-        NOTALLOWEDONNONLEAF, NOTALLOWEDONRDN, ENTRYALREADYEXISTS,
-        OBJECTCLASSMODSPROHIBITED, AFFECTSMULTIPLEDSAS, OTHER
-    } ;
+    /**
+     * Set of all result code enumerations.  The set contains:
+     * <ul>
+     *   <li><a href="#SUCCESS">SUCCESS</a></li>
+     *   <li><a href="#OPERATIONSERROR">OPERATIONSERROR</a></li>
+     *   <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li>
+     *   <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li>
+     *   <li><a href="#SIZELIMITEXCEEDED">SIZELIMITEXCEEDED</a></li>
+     *   <li><a href="#COMPAREFALSE">COMPAREFALSE</a></li>
+     *   <li><a href="#COMPARETRUE">COMPARETRUE</a></li>
+     *   <li><a href="#AUTHMETHODNOTSUPPORTED">AUTHMETHODNOTSUPPORTED</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li>
+     *   <li><a href="#PARTIALRESULTS">PARTIALRESULTS</a></li>
+     *   <li><a href="#REFERRAL">REFERRAL</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li>
+     *   <li><a href="#SASLBINDINPROGRESS">SASLBINDINPROGRESS</a></li>
+     *   <li><a href="#NOSUCHATTRIBUTE">NOSUCHATTRIBUTE</a></li>
+     *   <li><a href="#UNDEFINEDATTRIBUTETYPE">UNDEFINEDATTRIBUTETYPE</a></li>
+     *   <li><a href="#INAPPROPRIATEMATCHING">INAPPROPRIATEMATCHING</a></li>
+     *   <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li>
+     *   <li><a href="#ATTRIBUTEORVALUEEXISTS">ATTRIBUTEORVALUEEXISTS</a></li>
+     *   <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li>
+     *   <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li>
+     *   <li><a href="#ALIASPROBLEM">ALIASPROBLEM</a></li>
+     *   <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li>
+     *   <li><a href="#ALIASDEREFERENCINGPROBLEM">ALIASDEREFERENCINGPROBLEM</a></li>
+     *   <li><a href="#INAPPROPRIATEAUTHENTICATION">INAPPROPRIATEAUTHENTICATION</a></li>
+     *   <li><a href="#INVALIDCREDENTIALS">INVALIDCREDENTIALS</a></li>
+     *   <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li>
+     *   <li><a href="#BUSY">BUSY</a></li>
+     *   <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li>
+     *   <li><a href="#LOOPDETECT">LOOPDETECT</a></li>
+     *   <li><a href="#NAMINGVIOLATION">NAMINGVIOLATION</a></li>
+     *   <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li>
+     *   <li><a href="#NOTALLOWEDONNONLEAF">NOTALLOWEDONNONLEAF</a></li>
+     *   <li><a href="#NOTALLOWEDONRDN">NOTALLOWEDONRDN</a></li>
+     *   <li><a href="#ENTRYALREADYEXISTS">ENTRYALREADYEXISTS</a></li>
+     *   <li><a href="#OBJECTCLASSMODSPROHIBITED">OBJECTCLASSMODSPROHIBITED</a></li>
+     *   <li><a href="#AFFECTSMULTIPLEDSAS">AFFECTSMULTIPLEDSAS</a></li>
+     *   <li><a href="#OTHER">OTHER</a></li>
+     * </ul>
+     */
+    public static final Set ALL_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( SUCCESS );
+        set.add( OPERATIONSERROR );
+        set.add( PROTOCOLERROR );
+        set.add( TIMELIMITEXCEEDED );
+        set.add( SIZELIMITEXCEEDED );
+        set.add( COMPAREFALSE );
+        set.add( COMPARETRUE );
+        set.add( AUTHMETHODNOTSUPPORTED );
+        set.add( STRONGAUTHREQUIRED );
+        set.add( PARTIALRESULTS );
+        set.add( REFERRAL );
+        set.add( ADMINLIMITEXCEEDED );
+        set.add( UNAVAILABLECRITICALEXTENSION );
+        set.add( CONFIDENTIALITYREQUIRED );
+        set.add( SASLBINDINPROGRESS );
+        set.add( NOSUCHATTRIBUTE );
+        set.add( UNDEFINEDATTRIBUTETYPE );
+        set.add( INAPPROPRIATEMATCHING );
+        set.add( CONSTRAINTVIOLATION );
+        set.add( ATTRIBUTEORVALUEEXISTS );
+        set.add( INVALIDATTRIBUTESYNTAX );
+        set.add( NOSUCHOBJECT );
+        set.add( ALIASPROBLEM );
+        set.add( INVALIDDNSYNTAX );
+        set.add( ALIASDEREFERENCINGPROBLEM );
+        set.add( INAPPROPRIATEAUTHENTICATION );
+        set.add( INVALIDCREDENTIALS );
+        set.add( INSUFFICIENTACCESSRIGHTS );
+        set.add( BUSY );
+        set.add( UNAVAILABLE );
+        set.add( UNWILLINGTOPERFORM );
+        set.add( LOOPDETECT );
+        set.add( NAMINGVIOLATION );
+        set.add( OBJECTCLASSVIOLATION );
+        set.add( NOTALLOWEDONNONLEAF );
+        set.add( NOTALLOWEDONRDN );
+        set.add( ENTRYALREADYEXISTS );
+        set.add( OBJECTCLASSMODSPROHIBITED );
+        set.add( AFFECTSMULTIPLEDSAS );
+        set.add( OTHER );
+        ALL_CODES = Collections.unmodifiableSet( set );
+    }
 
     // ------------------------------------------------------------------------
     // Constructors
@@ -995,10 +1592,10 @@
      *
      * @see #GENERAL_CODES
      */
-    public static ResultCodeEnum[] getGeneralCodes()
+    public static Set getGeneralCodes()
     {
         // Must clone to prevent array content alterations
-        return ( ResultCodeEnum[] ) GENERAL_CODES.clone() ;
+        return GENERAL_CODES;
     }
 
 
@@ -1010,10 +1607,10 @@
      *
      * @see #NON_ERRONEOUS_CODES
      */
-    public static ResultCodeEnum[] getNonErroneousCodes()
+    public static Set getNonErroneousCodes()
     {
         // Must clone to prevent array content alterations
-        return ( ResultCodeEnum[] ) NON_ERRONEOUS_CODES.clone() ;
+        return NON_ERRONEOUS_CODES;
     }
 
 
@@ -1025,10 +1622,10 @@
      *
      * @see #ATTRIBUTE_CODES
      */
-    public static ResultCodeEnum[] getAttributeCodes()
+    public static Set getAttributeCodes()
     {
         // Must clone to prevent array content alterations
-        return ( ResultCodeEnum[] ) ATTRIBUTE_CODES.clone() ;
+        return ATTRIBUTE_CODES;
     }
 
 
@@ -1040,10 +1637,10 @@
      *
      * @see #NAME_CODES
      */
-    public static ResultCodeEnum[] getNameCodes()
+    public static Set getNameCodes()
     {
         // Must clone to prevent array content alterations
-        return ( ResultCodeEnum[] ) NAME_CODES.clone() ;
+        return NAME_CODES;
     }
 
 
@@ -1055,10 +1652,10 @@
      *
      * @see #SECURITY_CODES
      */
-    public static ResultCodeEnum[] getSecurityCodes()
+    public static Set getSecurityCodes()
     {
         // Must clone to prevent array content alterations
-        return ( ResultCodeEnum[] ) SECURITY_CODES.clone() ;
+        return SECURITY_CODES;
     }
 
 
@@ -1070,10 +1667,10 @@
      *
      * @see #SERVICE_CODES
      */
-    public static ResultCodeEnum[] getServiceCodes()
+    public static Set getServiceCodes()
     {
         // Must clone to prevent array content alterations
-        return ( ResultCodeEnum[] ) SERVICE_CODES.clone() ;
+        return SERVICE_CODES;
     }
 
 
@@ -1085,10 +1682,10 @@
      *
      * @see #UPDATE_CODES
      */
-    public static ResultCodeEnum[] getUpdateCodes()
+    public static Set getUpdateCodes()
     {
         // Must clone to prevent array content alterations
-        return ( ResultCodeEnum[] ) UPDATE_CODES.clone() ;
+        return UPDATE_CODES;
     }
 
 
@@ -1099,9 +1696,9 @@
      *
      * @see #COMMON_CODES
      */
-    public static ResultCodeEnum[] getCommonCodes()
+    public static Set getCommonCodes()
     {
-        return ( ResultCodeEnum[] ) COMMON_CODES.clone() ;
+        return COMMON_CODES;
     }
 
 
@@ -1113,9 +1710,9 @@
      *
      * @see #BIND_CODES
      */
-    public static ResultCodeEnum[] getBindCodes()
+    public static Set getBindCodes()
     {
-        return ( ResultCodeEnum[] ) BIND_CODES.clone() ;
+        return BIND_CODES;
     }
 
 
@@ -1127,9 +1724,9 @@
      *
      * @see #SEARCH_CODES
      */
-    public static ResultCodeEnum[] getSearchCodes()
+    public static Set getSearchCodes()
     {
-        return ( ResultCodeEnum[] ) SEARCH_CODES.clone() ;
+        return SEARCH_CODES;
     }
 
 
@@ -1141,9 +1738,9 @@
      *
      * @see #MODIFY_CODES
      */
-    public static ResultCodeEnum[] getModifyCodes()
+    public static Set getModifyCodes()
     {
-        return ( ResultCodeEnum[] ) MODIFY_CODES.clone() ;
+        return MODIFY_CODES;
     }
 
 
@@ -1154,9 +1751,9 @@
      *
      * @see #ADD_CODES
      */
-    public static ResultCodeEnum[] getAddCodes()
+    public static Set getAddCodes()
     {
-        return ( ResultCodeEnum[] ) ADD_CODES.clone() ;
+        return ADD_CODES;
     }
 
 
@@ -1168,9 +1765,9 @@
      *
      * @see #DELETE_CODES
      */
-    public static ResultCodeEnum[] getDeleteCodes()
+    public static Set getDeleteCodes()
     {
-        return ( ResultCodeEnum[] ) DELETE_CODES.clone() ;
+        return DELETE_CODES;
     }
 
 
@@ -1182,9 +1779,9 @@
      *
      * @see #MODIFYDN_CODES
      */
-    public static ResultCodeEnum[] getModifyDnCodes()
+    public static Set getModifyDnCodes()
     {
-        return ( ResultCodeEnum[] ) MODIFYDN_CODES.clone() ;
+        return MODIFYDN_CODES;
     }
 
 
@@ -1196,9 +1793,9 @@
      *
      * @see #COMPARE_CODES
      */
-    public static ResultCodeEnum[] getCompareCodes()
+    public static Set getCompareCodes()
     {
-        return ( ResultCodeEnum[] ) COMPARE_CODES.clone() ;
+        return COMPARE_CODES;
     }
 
 
@@ -1210,9 +1807,9 @@
      *
      * @see #EXTENDED_CODES
      */
-    public static ResultCodeEnum[] getExtendedCodes()
+    public static Set getExtendedCodes()
     {
-        return ( ResultCodeEnum[] ) EXTENDED_CODES.clone() ;
+        return EXTENDED_CODES;
     }
 
 
@@ -1223,10 +1820,10 @@
      *
      * @see #ALL_CODES
      */
-    public static ResultCodeEnum[] getAllCodes()
+    public static Set getAllCodes()
     {
         // Must clone to prevent array content tampering.
-        return ( ResultCodeEnum[] ) ALL_CODES.clone() ;
+        return ALL_CODES;
     }
 
 
@@ -1238,13 +1835,13 @@
      * Gets the result code enumeration object associated with a result code
      * value.
      *
-     * @param a_value the result code constant.
+     * @param value the result code constant.
      * @return the result code with a_value, or null if no enumeration exists
      *         for an (undefined) value.
      */
-    public static ResultCodeEnum getResultCodeEnum( int a_value )
+    public static ResultCodeEnum getResultCodeEnum( int value )
     {
-        switch ( a_value )
+        switch ( value )
         {
         case ( SUCCESS_VAL ):
             return SUCCESS ;
@@ -1273,7 +1870,8 @@
         case ( STRONGAUTHREQUIRED_VAL ):
             return STRONGAUTHREQUIRED ;
 
-        // -- 9 reserved --
+        case ( PARTIALRESULTS_VAL ):
+             return PARTIALRESULTS ;
 
         case ( REFERRAL_VAL ):
             return REFERRAL ;
@@ -1384,5 +1982,579 @@
         default:
             return null ;
         }
+    }
+
+
+    // ------------------------------------------------------------------------
+    // JNDI Exception to ResultCodeEnum Mappings
+    // ------------------------------------------------------------------------
+
+    /**
+     * A set of ResultCodes containing those that may correspond to a
+     * {@link NamingException}.
+     *
+     * <ul>
+     *   <li><a href="#OPERATIONSERROR">operationsError(1)</a></li>
+     *   <li><a href="#ALIASPROBLEM">aliasProblem(33)</a></li>
+     *   <li><a href="#ALIASDEREFERENCINGPROBLEM">aliasDereferencingProblem(36)</a></li>
+     *   <li><a href="#LOOPDETECT">loopDetect(54)</a></li>
+     *   <li><a href="#AFFECTSMULTIPLEDSAS">affectsMultipleDSAs(71)</a></li>
+     *   <li><a href="#OTHER">other(80)</a></li>
+     * </ul>
+     */
+    public static final Set NAMINGEXCEPTION_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( ResultCodeEnum.OPERATIONSERROR );
+        set.add( ResultCodeEnum.ALIASPROBLEM );
+        set.add( ResultCodeEnum.ALIASDEREFERENCINGPROBLEM );
+        set.add( ResultCodeEnum.LOOPDETECT );
+        set.add( ResultCodeEnum.AFFECTSMULTIPLEDSAS );
+        set.add( ResultCodeEnum.OTHER );
+        NAMINGEXCEPTION_CODES = Collections.unmodifiableSet( set );
+    }
+
+    /**
+     * A set of ResultCodes containing those that may correspond to a
+     * {@link Exception}.
+     *
+     * <ul>
+     *   <li><a href="#AUTHMETHODNOTSUPPORTED">authMethodNotSupported(7)</a></li>
+     *   <li><a href="#STRONGAUTHREQUIRED">strongAuthRequired(8)</a></li>
+     *   <li><a href="#CONFIDENTIALITYREQUIRED">confidentialityRequired(13)</a></li>
+     *   <li><a href="#INAPPROPRIATEAUTHENTICATION">inappropriateAuthentication(48)</a></li>
+     * </ul>
+     */
+    public static final Set AUTHENTICATIONNOTSUPPOERTEDEXCEPTION_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( ResultCodeEnum.AUTHMETHODNOTSUPPORTED );
+        set.add( ResultCodeEnum.STRONGAUTHREQUIRED );
+        set.add( ResultCodeEnum.CONFIDENTIALITYREQUIRED );
+        set.add( ResultCodeEnum.INAPPROPRIATEAUTHENTICATION );
+        AUTHENTICATIONNOTSUPPOERTEDEXCEPTION_CODES = Collections.unmodifiableSet( set );
+    }
+
+    /**
+     * A set of ResultCodes containing those that may correspond to a
+     * {@link Exception}.
+     *
+     * <ul>
+     *   <li><a href="#BUSY">busy(51)</a></li>
+     *   <li><a href="#UNAVAILABLE">unavailable(52)</a></li>
+     * </ul>
+     */
+    public static final Set SERVICEUNAVAILABLE_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( ResultCodeEnum.BUSY );
+        set.add( ResultCodeEnum.UNAVAILABLE );
+        SERVICEUNAVAILABLE_CODES = Collections.unmodifiableSet( set );
+    }
+
+    /**
+     * A set of ResultCodes containing those that may correspond to a
+     * {@link Exception}.
+     *
+     * <ul>
+     *   <li><a href="#CONSTRAINTVIOLATION">constraintViolation(19)</a></li>
+     *   <li><a href="#INVALIDATTRIBUTESYNTAX">invalidAttributeSyntax(21)</a></li>
+     * </ul>
+     */
+    public static final Set INVALIDATTRIBUTEVALUEEXCEPTION_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( ResultCodeEnum.CONSTRAINTVIOLATION );
+        set.add( ResultCodeEnum.INVALIDATTRIBUTESYNTAX );
+        INVALIDATTRIBUTEVALUEEXCEPTION_CODES = Collections.unmodifiableSet( set );
+    }
+
+    /**
+     * A set of ResultCodes containing those that may correspond to a
+     * {@link Exception}.
+     *
+     * <ul>
+     *   <li><a href="#PARTIALRESULTS">partialResults(9)</a></li>
+     *   <li><a href="#REFERRAL">referral(10)</a></li>
+     * </ul>
+     */
+    public static final Set PARTIALRESULTSEXCEPTION_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( ResultCodeEnum.PARTIALRESULTS );
+        set.add( ResultCodeEnum.REFERRAL );
+        PARTIALRESULTSEXCEPTION_CODES = Collections.unmodifiableSet( set );
+    }
+
+    /**
+     * A set of ResultCodes containing those that may correspond to a
+     * {@link Exception}.
+     *
+     * <ul>
+     *   <li><a href="#REFERRAL">referal(9)</a></li>
+     *   <li><a href="#ADMINLIMITEXCEEDED">adminLimitExceeded(11)</a></li>
+     * </ul>
+     */
+    public static final Set LIMITEXCEEDEDEXCEPTION_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( ResultCodeEnum.REFERRAL );
+        set.add( ResultCodeEnum.ADMINLIMITEXCEEDED );
+        LIMITEXCEEDEDEXCEPTION_CODES = Collections.unmodifiableSet( set );
+    }
+
+    /**
+     * A set of ResultCodes containing those that may correspond to a
+     * {@link Exception}.
+     *
+     * <ul>
+     *   <li><a href="#UNAVAILABLECRITICALEXTENTION">unavailableCriticalExtention(12)</a></li>
+     *   <li><a href="#UNWILLINGTOPERFORM">unwillingToPerform(53)</a></li>
+     * </ul>
+     */
+    public static final Set OPERATIONNOTSUPPOERTEXCEPTION_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( ResultCodeEnum.UNAVAILABLECRITICALEXTENSION );
+        set.add( ResultCodeEnum.UNWILLINGTOPERFORM );
+        OPERATIONNOTSUPPOERTEXCEPTION_CODES = Collections.unmodifiableSet( set );
+    }
+
+    /**
+     * A set of ResultCodes containing those that may correspond to a
+     * {@link Exception}.
+     *
+     * <ul>
+     *   <li><a href="#INVALIDDNSYNTAX">invalidDNSyntax(34)</a></li>
+     *   <li><a href="#NAMINGVIOLATION">namingViolation(64)</a></li>
+     * </ul>
+     */
+    public static final Set INVALIDNAMEEXCEPTION_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( ResultCodeEnum.INVALIDDNSYNTAX );
+        set.add( ResultCodeEnum.NAMINGVIOLATION );
+        INVALIDNAMEEXCEPTION_CODES = Collections.unmodifiableSet( set );
+    }
+
+    /**
+     * A set of ResultCodes containing those that may correspond to a
+     * {@link javax.naming.directory.SchemaViolationException}.
+     *
+     * <ul>
+     *   <li><a href="#OBJECTCLASSVIOLATION">objectClassViolation(65)</a></li>
+     *   <li><a href="#NOTALLOWEDONRDN">notAllowedOnRDN(67)</a></li>
+     *   <li><a href="#OBJECTCLASSMODSPROHIBITED">objectClassModsProhibited(69)</a></li>
+     * </ul>
+     */
+    public static final Set SCHEMAVIOLATIONEXCEPTION_CODES;
+    static
+    {
+        HashSet set = new HashSet();
+        set.add( ResultCodeEnum.OBJECTCLASSVIOLATION );
+        set.add( ResultCodeEnum.NOTALLOWEDONRDN );
+        set.add( ResultCodeEnum.OBJECTCLASSMODSPROHIBITED );
+        SCHEMAVIOLATIONEXCEPTION_CODES = Collections.unmodifiableSet( set );
+    }
+
+
+    /**
+     * Takes a guess at the result code to use if it cannot figure it out from
+     * known Throwable to result code mappings.  Some however are ambiguous
+     * mapping the same Throwable to multiple codes.  If no code can be resolved
+     * then {@link ResultCodeEnum#OTHER} is returned.
+     *
+     * @param t the throwable to estimate a result code for
+     * @param type the type of operation being performed
+     * @return the result code or a good estimate of one
+     */
+    public static ResultCodeEnum getBestEstimate( Throwable t, MessageTypeEnum type )
+    {
+        Set set = getResultCodes( t );
+
+        if ( set.isEmpty() )
+        {
+            return ResultCodeEnum.OTHER;
+        }
+
+        if ( set.size() == 1 )
+        {
+            return ( ResultCodeEnum ) set.iterator().next();
+        }
+
+        if ( type == null )
+        {
+            HashSet tmp = new HashSet();
+            tmp.addAll( set );
+            tmp.removeAll( NON_ERRONEOUS_CODES );
+
+            if ( tmp.isEmpty() )
+            {
+                return ResultCodeEnum.OTHER;
+            }
+
+            return ( ResultCodeEnum ) tmp.iterator().next();
+        }
+
+        Set candidates = Collections.EMPTY_SET;
+        switch( type.getValue() )
+        {
+            case( MessageTypeEnum.ABANDONREQUEST_VAL ):
+                return ( ResultCodeEnum ) set.iterator().next();
+            case( MessageTypeEnum.ADDREQUEST_VAL ):
+                candidates = intersection( set, ADD_CODES );
+                break;
+            case( MessageTypeEnum.ADDRESPONSE_VAL ):
+                candidates = intersection( set, ADD_CODES );
+                break;
+            case( MessageTypeEnum.BINDREQUEST_VAL ):
+                candidates = intersection( set, BIND_CODES );
+                break;
+            case( MessageTypeEnum.BINDRESPONSE_VAL ):
+                candidates = intersection( set, BIND_CODES );
+                break;
+            case( MessageTypeEnum.COMPAREREQUEST_VAL ):
+                candidates = intersection( set, COMPARE_CODES );
+                break;
+            case( MessageTypeEnum.COMPARERESPONSE_VAL ):
+                candidates = intersection( set, COMPARE_CODES );
+                break;
+            case( MessageTypeEnum.DELREQUEST_VAL ):
+                candidates = intersection( set, DELETE_CODES );
+                break;
+            case( MessageTypeEnum.DELRESPONSE_VAL ):
+                candidates = intersection( set, DELETE_CODES );
+                break;
+            case( MessageTypeEnum.EXTENDEDREQ_VAL ):
+                candidates = intersection( set, EXTENDED_CODES );
+                break;
+            case( MessageTypeEnum.EXTENDEDRESP_VAL ):
+                candidates = intersection( set, EXTENDED_CODES );
+                break;
+            case( MessageTypeEnum.MODDNREQUEST_VAL ):
+                candidates = intersection( set, MODIFYDN_CODES );
+                break;
+            case( MessageTypeEnum.MODDNRESPONSE_VAL ):
+                candidates = intersection( set, MODIFYDN_CODES );
+                break;
+            case( MessageTypeEnum.MODIFYREQUEST_VAL ):
+                candidates = intersection( set, MODIFY_CODES );
+                break;
+            case( MessageTypeEnum.MODIFYRESPONSE_VAL ):
+                candidates = intersection( set, MODIFY_CODES );
+                break;
+            case( MessageTypeEnum.SEARCHREQUEST_VAL ):
+                candidates = intersection( set, SEARCH_CODES );
+                break;
+            case( MessageTypeEnum.SEARCHRESDONE_VAL ):
+                candidates = intersection( set, SEARCH_CODES );
+                break;
+            case( MessageTypeEnum.SEARCHRESENTRY_VAL ):
+                candidates = intersection( set, SEARCH_CODES );
+                break;
+            case( MessageTypeEnum.SEARCHRESREF_VAL ):
+                candidates = intersection( set, SEARCH_CODES );
+                break;
+            case( MessageTypeEnum.UNBINDREQUEST_VAL ):
+                return ( ResultCodeEnum ) set.iterator().next();
+        }
+
+        // we don't want any codes that do not have anything to do w/ errors
+        candidates.removeAll( NON_ERRONEOUS_CODES );
+
+        if ( candidates.isEmpty() )
+        {
+            return ResultCodeEnum.OTHER;
+        }
+
+        return ( ResultCodeEnum ) candidates.iterator().next();
+    }
+
+
+    private static Set intersection( Set s1, Set s2 )
+    {
+        if ( s1.isEmpty() || s2.isEmpty() )
+        {
+            return Collections.EMPTY_SET;
+        }
+
+        Set intersection = new HashSet();
+        if ( s1.size() <= s2.size() )
+        {
+            Iterator items = s1.iterator();
+            while ( items.hasNext() )
+            {
+                Object item = items.next();
+                if ( s2.contains( item ) )
+                {
+                    intersection.add( item );
+                }
+            }
+        }
+        else
+        {
+            Iterator items = s2.iterator();
+            while ( items.hasNext() )
+            {
+                Object item = items.next();
+                if ( s1.contains( item ) )
+                {
+                    intersection.add( item );
+                }
+            }
+        }
+
+        return intersection;
+    }
+
+
+    /**
+     * Gets the set of result codes a Throwable may map to.  If the throwable
+     * does not map to any result code at all an empty set is returned.  The
+     * following Throwables and their subclasses map to result codes:
+     *
+     * <pre>
+     *
+     * Unambiguous Exceptions
+     * ======================
+     *
+     * CommunicationException              ==> operationsError(1)
+     * TimeLimitExceededException          ==> timeLimitExceeded(3)
+     * SizeLimitExceededException          ==> sizeLimitExceeded(4)
+     * AuthenticationException             ==> invalidCredentials(49)
+     * NoPermissionException               ==> insufficientAccessRights(50)
+     * NoSuchAttributeException            ==> noSuchAttribute(16)
+     * InvalidAttributeIdentifierException ==> undefinedAttributeType(17)
+     * InvalidSearchFilterException        ==> inappropriateMatching(18)
+     * AttributeInUseException             ==> attributeOrValueExists(20)
+     * NameNotFoundException               ==> noSuchObject(32)
+     * NameAlreadyBoundException           ==> entryAlreadyExists(68)
+     * ContextNotEmptyException            ==> notAllowedOnNonLeaf(66)
+     *
+     *
+     * Ambiguous Exceptions
+     * ====================
+     *
+     * NamingException
+     * ---------------
+     * operationsError(1)
+     * aliasProblem(33)
+     * aliasDereferencingProblem(36)
+     * loopDetect(54)
+     * affectsMultipleDSAs(71)
+     * other(80)
+     *
+     * AuthenticationNotSupportedException
+     * -----------------------------------
+     * authMethodNotSupported (7)
+     * strongAuthRequired (8)
+     * confidentialityRequired (13)
+     * inappropriateAuthentication(48)
+     *
+     * ServiceUnavailableException
+     * ---------------------------
+     * busy(51)
+     * unavailable(52)
+     *
+     * InvalidAttributeValueException
+     * ------------------------------
+     * constraintViolation(19)
+     * invalidAttributeSyntax(21)
+     *
+     * PartialResultException
+     * ----------------------
+     * partialResults(9)
+     * referral(10)
+     *
+     * LimitExceededException
+     * ----------------------
+     * referal(9)
+     * adminLimitExceeded(11)
+     *
+     * OperationNotSupportedException
+     * ------------------------------
+     * unavailableCriticalExtention(12)
+     * unwillingToPerform(53)
+     *
+     * InvalidNameException
+     * --------------------
+     * invalidDNSyntax(34)
+     * namingViolation(64)
+     *
+     * SchemaViolationException
+     * ------------------------
+     * objectClassViolation(65)
+     * notAllowedOnRDN(67)
+     * objectClassModsProhibited(69)
+     *
+     * </pre>
+     *
+     * @param t the Throwable to find the result code mappings for
+     * @return the set of mapped result codes
+     */
+    public static Set getResultCodes( Throwable t )
+    {
+        ResultCodeEnum rc;
+        if ( ( rc = getResultCode( t ) ) != null )
+        {
+            return Collections.singleton( rc );
+        }
+
+        if ( t instanceof SchemaViolationException )
+        {
+            return SCHEMAVIOLATIONEXCEPTION_CODES;
+        }
+
+        if ( t instanceof InvalidNameException )
+        {
+            return INVALIDNAMEEXCEPTION_CODES;
+        }
+
+        if ( t instanceof OperationNotSupportedException )
+        {
+            return OPERATIONNOTSUPPOERTEXCEPTION_CODES;
+        }
+
+        if ( t instanceof LimitExceededException )
+        {
+            return LIMITEXCEEDEDEXCEPTION_CODES;
+        }
+
+        if ( t instanceof PartialResultException )
+        {
+            return PARTIALRESULTSEXCEPTION_CODES;
+        }
+
+        if ( t instanceof InvalidAttributeValueException )
+        {
+            return INVALIDATTRIBUTEVALUEEXCEPTION_CODES;
+        }
+
+        if ( t instanceof ServiceUnavailableException )
+        {
+            return SERVICEUNAVAILABLE_CODES;
+        }
+
+        if ( t instanceof AuthenticationNotSupportedException )
+        {
+            return AUTHENTICATIONNOTSUPPOERTEDEXCEPTION_CODES;
+        }
+
+        // keep this last because others are subtypes and thier evaluation
+        // may be shorted otherwise by this comparison here
+        if ( t instanceof NamingException )
+        {
+            return NAMINGEXCEPTION_CODES;
+        }
+
+        return Collections.EMPTY_SET;
+    }
+
+
+    /**
+     * Gets an LDAP result code from a Throwable if it can resolve it
+     * unambiguously or returns null if it cannot resolve the exception to
+     * a single ResultCode.  If the Throwable is an instance of LdapException
+     * this is already done for us, otherwise we use the following mapping:
+     * <pre>
+     *
+     * Unambiguous Exceptions
+     * ======================
+     *
+     * CommunicationException              ==> operationsError(1)
+     * TimeLimitExceededException          ==> timeLimitExceeded(3)
+     * SizeLimitExceededException          ==> sizeLimitExceeded(4)
+     * AuthenticationException             ==> invalidCredentials(49)
+     * NoPermissionException               ==> insufficientAccessRights(50)
+     * NoSuchAttributeException            ==> noSuchAttribute(16)
+     * InvalidAttributeIdentifierException ==> undefinedAttributeType(17)
+     * InvalidSearchFilterException        ==> inappropriateMatching(18)
+     * AttributeInUseException             ==> attributeOrValueExists(20)
+     * NameNotFoundException               ==> noSuchObject(32)
+     * NameAlreadyBoundException           ==> entryAlreadyExists(68)
+     * ContextNotEmptyException            ==> notAllowedOnNonLeaf(66)
+     * </pre>
+     *
+     * If we cannot find a mapping then null is returned.
+     *
+     * @param t
+     * @return
+     */
+    public static ResultCodeEnum getResultCode( Throwable t )
+    {
+        if ( t instanceof LdapException )
+        {
+            return ( ( LdapException ) t ).getResultCode();
+        }
+
+        if ( t instanceof CommunicationException )
+        {
+            return ResultCodeEnum.PROTOCOLERROR;
+        }
+
+        if ( t instanceof TimeLimitExceededException )
+        {
+            return ResultCodeEnum.TIMELIMITEXCEEDED;
+        }
+
+        if ( t instanceof SizeLimitExceededException )
+        {
+            return ResultCodeEnum.SIZELIMITEXCEEDED;
+        }
+
+        if ( t instanceof AuthenticationException )
+        {
+            return ResultCodeEnum.INVALIDCREDENTIALS;
+        }
+
+        if ( t instanceof NoPermissionException )
+        {
+            return ResultCodeEnum.INSUFFICIENTACCESSRIGHTS;
+        }
+
+        if ( t instanceof NoSuchAttributeException )
+        {
+            return ResultCodeEnum.NOSUCHATTRIBUTE;
+        }
+
+        if ( t instanceof InvalidAttributeIdentifierException )
+        {
+            return ResultCodeEnum.UNDEFINEDATTRIBUTETYPE;
+        }
+
+        if ( t instanceof InvalidSearchFilterException )
+        {
+            return ResultCodeEnum.INAPPROPRIATEMATCHING;
+        }
+
+        if ( t instanceof AttributeInUseException )
+        {
+            return ResultCodeEnum.ATTRIBUTEORVALUEEXISTS;
+        }
+
+        if ( t instanceof NameNotFoundException )
+        {
+            return ResultCodeEnum.NOSUCHOBJECT;
+        }
+
+        if ( t instanceof NameAlreadyBoundException )
+        {
+            return ResultCodeEnum.ENTRYALREADYEXISTS;
+        }
+
+        if ( t instanceof ContextNotEmptyException )
+        {
+            return ResultCodeEnum.NOTALLOWEDONNONLEAF;
+        }
+
+        return null;
     }
 }

Modified: incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/util/ExceptionUtils.java
==============================================================================
--- incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/util/ExceptionUtils.java	(original)
+++ incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/util/ExceptionUtils.java	Wed Nov  3 16:50:45 2004
@@ -15,6 +15,7 @@
  */
 package org.apache.ldap.common.util;
 
+
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -22,31 +23,23 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.StringTokenizer;
+import java.util.*;
 
 
 /**
- * <p>Provides utilities for manipulating and examining 
- * <code>Throwable</code> objects.</p>
+ * <p>Provides utilities for manipulating and examining <code>Throwable</code>
+ * objects.</p>
  *
- * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
- * @author Dmitri Plotnikov
- * @author Stephen Colebourne
- * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a>
- * @author Pete Gieser
- * @since 1.0
- * @version $Id: ExceptionUtils.java,v 1.39 2004/07/04 03:24:57 bayard Exp $
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
  */
-public class ExceptionUtils {
-    
+public class ExceptionUtils
+{
+
     /**
-     * <p>Used when printing stack frames to denote the start of a
-     * wrapped exception.</p>
-     *
+     * <p>Used when printing stack frames to denote the start of a wrapped
+     * exception.</p>
+     * <p/>
      * <p>Package private for accessibility by test suite.</p>
      */
     static final String WRAPPED_MARKER = " [wrapped] ";
@@ -73,218 +66,273 @@
      * <p>The Method object for JDK1.4 getCause.</p>
      */
     private static final Method THROWABLE_CAUSE_METHOD;
-    static {
+
+
+    static
+    {
         Method getCauseMethod;
-        try {
-            getCauseMethod = Throwable.class.getMethod("getCause", null);
-        } catch (Exception e) {
+        try
+        {
+            getCauseMethod = Throwable.class.getMethod( "getCause", null );
+        }
+        catch ( Exception e )
+        {
             getCauseMethod = null;
         }
         THROWABLE_CAUSE_METHOD = getCauseMethod;
     }
-    
+
+
     /**
      * <p>Public constructor allows an instance of <code>ExceptionUtils</code>
      * to be created, although that is not normally necessary.</p>
      */
-    public ExceptionUtils() {
+    public ExceptionUtils()
+    {
     }
 
+
     /**
      * <p>Checks if a String is not empty ("") and not null.</p>
      *
-     * @param str  the String to check, may be null
+     * @param str the String to check, may be null
      * @return <code>true</code> if the String is not empty and not null
      */
-    private static boolean isNotEmpty(String str) {
-        return (str != null && str.length() > 0);
+    private static boolean isNotEmpty( String str )
+    {
+        return ( str != null && str.length() > 0 );
     }
 
     //-----------------------------------------------------------------------
     /**
-     * <p>Adds to the list of method names used in the search for <code>Throwable</code>
-     * objects.</p>
-     * 
-     * @param methodName  the methodName to add to the list, <code>null</code>
-     *  and empty strings are ignored
+     * <p>Adds to the list of method names used in the search for
+     * <code>Throwable</code> objects.</p>
+     *
+     * @param methodName the methodName to add to the list, <code>null</code>
+     *                   and empty strings are ignored
      * @since 2.0
      */
-    public static void addCauseMethodName(String methodName) {
-        if (isNotEmpty(methodName)) {
-            List list = new ArrayList(Arrays.asList(CAUSE_METHOD_NAMES));
-            list.add(methodName);
-            CAUSE_METHOD_NAMES = (String[]) list.toArray(new String[list.size()]);
+    public static void addCauseMethodName( String methodName )
+    {
+        if ( isNotEmpty( methodName ) )
+        {
+            List list = new ArrayList( Arrays.asList( CAUSE_METHOD_NAMES ) );
+            list.add( methodName );
+            CAUSE_METHOD_NAMES = ( String[] ) list.toArray( new String[list.size()] );
         }
     }
 
+
     /**
      * <p>Introspects the <code>Throwable</code> to obtain the cause.</p>
-     * 
-     * <p>The method searches for methods with specific names that return a 
-     * <code>Throwable</code> object. This will pick up most wrapping exceptions,
-     * including those from JDK 1.4, and
-     * The method names can be added to using {@link #addCauseMethodName(String)}.</p>
-     *
-     * <p>The default list searched for are:</p>
-     * <ul>
-     *  <li><code>getCause()</code></li>
-     *  <li><code>getNextException()</code></li>
-     *  <li><code>getTargetException()</code></li>
-     *  <li><code>getException()</code></li>
-     *  <li><code>getSourceException()</code></li>
-     *  <li><code>getRootCause()</code></li>
-     *  <li><code>getCausedByException()</code></li>
-     *  <li><code>getNested()</code></li>
-     * </ul>
-     * 
+     * <p/>
+     * <p>The method searches for methods with specific names that return a
+     * <code>Throwable</code> object. This will pick up most wrapping
+     * exceptions, including those from JDK 1.4, and The method names can be
+     * added to using {@link #addCauseMethodName(String)}.</p>
+     * <p/>
+     * <p>The default list searched for are:</p> <ul> <li><code>getCause()</code></li>
+     * <li><code>getNextException()</code></li> <li><code>getTargetException()</code></li>
+     * <li><code>getException()</code></li> <li><code>getSourceException()</code></li>
+     * <li><code>getRootCause()</code></li> <li><code>getCausedByException()</code></li>
+     * <li><code>getNested()</code></li> </ul>
+     * <p/>
      * <p>In the absence of any such method, the object is inspected for a
      * <code>detail</code> field assignable to a <code>Throwable</code>.</p>
-     * 
+     * <p/>
      * <p>If none of the above is found, returns <code>null</code>.</p>
      *
-     * @param throwable  the throwable to introspect for a cause, may be null
-     * @return the cause of the <code>Throwable</code>,
-     *  <code>null</code> if none found or null throwable input
+     * @param throwable the throwable to introspect for a cause, may be null
+     * @return the cause of the <code>Throwable</code>, <code>null</code> if
+     *         none found or null throwable input
      * @since 1.0
      */
-    public static Throwable getCause(Throwable throwable) {
-        return getCause(throwable, CAUSE_METHOD_NAMES);
+    public static Throwable getCause( Throwable throwable )
+    {
+        return getCause( throwable, CAUSE_METHOD_NAMES );
     }
 
+
     /**
      * <p>Introspects the <code>Throwable</code> to obtain the cause.</p>
-     * 
-     * <ol>
-     * <li>Try known exception types.</li>
-     * <li>Try the supplied array of method names.</li>
-     * <li>Try the field 'detail'.</li>
-     * </ol>
-     * 
-     * <p>A <code>null</code> set of method names means use the default set.
-     * A <code>null</code> in the set of method names will be ignored.</p>
-     *
-     * @param throwable  the throwable to introspect for a cause, may be null
-     * @param methodNames  the method names, null treated as default set
-     * @return the cause of the <code>Throwable</code>,
-     *  <code>null</code> if none found or null throwable input
+     * <p/>
+     * <ol> <li>Try known exception types.</li> <li>Try the supplied array of
+     * method names.</li> <li>Try the field 'detail'.</li> </ol>
+     * <p/>
+     * <p>A <code>null</code> set of method names means use the default set. A
+     * <code>null</code> in the set of method names will be ignored.</p>
+     *
+     * @param throwable   the throwable to introspect for a cause, may be null
+     * @param methodNames the method names, null treated as default set
+     * @return the cause of the <code>Throwable</code>, <code>null</code> if
+     *         none found or null throwable input
      * @since 1.0
      */
-    public static Throwable getCause(Throwable throwable, String[] methodNames) {
-        if (throwable == null) {
+    public static Throwable getCause( Throwable throwable, String[] methodNames )
+    {
+        if ( throwable == null )
+        {
             return null;
         }
-        Throwable cause = getCauseUsingWellKnownTypes(throwable);
-        if (cause == null) {
-            if (methodNames == null) {
+        Throwable cause = getCauseUsingWellKnownTypes( throwable );
+        if ( cause == null )
+        {
+            if ( methodNames == null )
+            {
                 methodNames = CAUSE_METHOD_NAMES;
             }
-            for (int i = 0; i < methodNames.length; i++) {
+            for ( int i = 0; i < methodNames.length; i++ )
+            {
                 String methodName = methodNames[i];
-                if (methodName != null) {
-                    cause = getCauseUsingMethodName(throwable, methodName);
-                    if (cause != null) {
+                if ( methodName != null )
+                {
+                    cause = getCauseUsingMethodName( throwable, methodName );
+                    if ( cause != null )
+                    {
                         break;
                     }
                 }
             }
 
-            if (cause == null) {
-                cause = getCauseUsingFieldName(throwable, "detail");
+            if ( cause == null )
+            {
+                cause = getCauseUsingFieldName( throwable, "detail" );
             }
         }
         return cause;
     }
 
+
     /**
      * <p>Introspects the <code>Throwable</code> to obtain the root cause.</p>
-     * 
+     * <p/>
      * <p>This method walks through the exception chain to the last element,
-     * "root" of the tree, using {@link #getCause(Throwable)}, and
-     * returns that exception.</p>
+     * "root" of the tree, using {@link #getCause(Throwable)}, and returns that
+     * exception.</p>
      *
-     * @param throwable  the throwable to get the root cause for, may be null
-     * @return the root cause of the <code>Throwable</code>,
-     *  <code>null</code> if none found or null throwable input
-     */
-    public static Throwable getRootCause(Throwable throwable) {
-        Throwable cause = getCause(throwable);
-        if (cause != null) {
+     * @param throwable the throwable to get the root cause for, may be null
+     * @return the root cause of the <code>Throwable</code>, <code>null</code>
+     *         if none found or null throwable input
+     */
+    public static Throwable getRootCause( Throwable throwable )
+    {
+        Throwable cause = getCause( throwable );
+        if ( cause != null )
+        {
             throwable = cause;
-            while ((throwable = getCause(throwable)) != null) {
+            while ( ( throwable = getCause( throwable ) ) != null )
+            {
                 cause = throwable;
             }
         }
         return cause;
     }
 
+
     /**
      * <p>Finds a <code>Throwable</code> for known types.</p>
-     * 
-     * <p>Uses <code>instanceof</code> checks to examine the exception,
-     * looking for well known types which could contain chained or
-     * wrapped exceptions.</p>
+     * <p/>
+     * <p>Uses <code>instanceof</code> checks to examine the exception, looking
+     * for well known types which could contain chained or wrapped
+     * exceptions.</p>
      *
-     * @param throwable  the exception to examine
+     * @param throwable the exception to examine
      * @return the wrapped exception, or <code>null</code> if not found
      */
-    private static Throwable getCauseUsingWellKnownTypes(Throwable throwable) {
-        if (throwable instanceof Nestable) {
-            return ((Nestable) throwable).getCause();
-        } else if (throwable instanceof SQLException) {
-            return ((SQLException) throwable).getNextException();
-        } else if (throwable instanceof InvocationTargetException) {
-            return ((InvocationTargetException) throwable).getTargetException();
-        } else {
+    private static Throwable getCauseUsingWellKnownTypes( Throwable throwable )
+    {
+        if ( throwable instanceof Nestable )
+        {
+            return ( ( Nestable ) throwable ).getCause();
+        }
+        else if ( throwable instanceof SQLException )
+        {
+            return ( ( SQLException ) throwable ).getNextException();
+        }
+        else if ( throwable instanceof InvocationTargetException )
+        {
+            return ( ( InvocationTargetException ) throwable ).getTargetException();
+        }
+        else
+        {
             return null;
         }
     }
 
+
     /**
      * <p>Finds a <code>Throwable</code> by method name.</p>
-     * 
+     *
      * @param throwable  the exception to examine
-     * @param methodName  the name of the method to find and invoke
+     * @param methodName the name of the method to find and invoke
      * @return the wrapped exception, or <code>null</code> if not found
      */
-    private static Throwable getCauseUsingMethodName(Throwable throwable, String methodName) {
+    private static Throwable getCauseUsingMethodName( Throwable throwable, String methodName )
+    {
         Method method = null;
-        try {
-            method = throwable.getClass().getMethod(methodName, null);
-        } catch (NoSuchMethodException ignored) {
-        } catch (SecurityException ignored) {
+        try
+        {
+            method = throwable.getClass().getMethod( methodName, null );
+        }
+        catch ( NoSuchMethodException ignored )
+        {
+        }
+        catch ( SecurityException ignored )
+        {
         }
 
-        if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) {
-            try {
-                return (Throwable) method.invoke(throwable, ArrayUtils.EMPTY_OBJECT_ARRAY);
-            } catch (IllegalAccessException ignored) {
-            } catch (IllegalArgumentException ignored) {
-            } catch (InvocationTargetException ignored) {
+        if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) )
+        {
+            try
+            {
+                return ( Throwable ) method.invoke( throwable, ArrayUtils.EMPTY_OBJECT_ARRAY );
+            }
+            catch ( IllegalAccessException ignored )
+            {
+            }
+            catch ( IllegalArgumentException ignored )
+            {
+            }
+            catch ( InvocationTargetException ignored )
+            {
             }
         }
         return null;
     }
 
+
     /**
      * <p>Finds a <code>Throwable</code> by field name.</p>
-     * 
-     * @param throwable  the exception to examine
-     * @param fieldName  the name of the attribute to examine
+     *
+     * @param throwable the exception to examine
+     * @param fieldName the name of the attribute to examine
      * @return the wrapped exception, or <code>null</code> if not found
      */
-    private static Throwable getCauseUsingFieldName(Throwable throwable, String fieldName) {
+    private static Throwable getCauseUsingFieldName( Throwable throwable, String fieldName )
+    {
         Field field = null;
-        try {
-            field = throwable.getClass().getField(fieldName);
-        } catch (NoSuchFieldException ignored) {
-        } catch (SecurityException ignored) {
+        try
+        {
+            field = throwable.getClass().getField( fieldName );
+        }
+        catch ( NoSuchFieldException ignored )
+        {
+        }
+        catch ( SecurityException ignored )
+        {
         }
 
-        if (field != null && Throwable.class.isAssignableFrom(field.getType())) {
-            try {
-                return (Throwable) field.get(throwable);
-            } catch (IllegalAccessException ignored) {
-            } catch (IllegalArgumentException ignored) {
+        if ( field != null && Throwable.class.isAssignableFrom( field.getType() ) )
+        {
+            try
+            {
+                return ( Throwable ) field.get( throwable );
+            }
+            catch ( IllegalAccessException ignored )
+            {
+            }
+            catch ( IllegalArgumentException ignored )
+            {
             }
         }
         return null;
@@ -293,59 +341,85 @@
     //-----------------------------------------------------------------------
     /**
      * <p>Checks if the Throwable class has a <code>getCause</code> method.</p>
-     * 
+     * <p/>
      * <p>This is true for JDK 1.4 and above.</p>
-     * 
+     *
      * @return true if Throwable is nestable
      * @since 2.0
      */
-    public static boolean isThrowableNested() {
-        return (THROWABLE_CAUSE_METHOD != null);
+    public static boolean isThrowableNested()
+    {
+        return ( THROWABLE_CAUSE_METHOD != null );
     }
-    
+
+
     /**
-     * <p>Checks whether this <code>Throwable</code> class can store a cause.</p>
-     * 
-     * <p>This method does <b>not</b> check whether it actually does store a cause.<p>
+     * <p>Checks whether this <code>Throwable</code> class can store a
+     * cause.</p>
+     * <p/>
+     * <p>This method does <b>not</b> check whether it actually does store a
+     * cause.<p>
      *
-     * @param throwable  the <code>Throwable</code> to examine, may be null
+     * @param throwable the <code>Throwable</code> to examine, may be null
      * @return boolean <code>true</code> if nested otherwise <code>false</code>
      * @since 2.0
      */
-    public static boolean isNestedThrowable(Throwable throwable) {
-        if (throwable == null) {
+    public static boolean isNestedThrowable( Throwable throwable )
+    {
+        if ( throwable == null )
+        {
             return false;
         }
 
-        if (throwable instanceof Nestable) {
+        if ( throwable instanceof Nestable )
+        {
             return true;
-        } else if (throwable instanceof SQLException) {
+        }
+        else if ( throwable instanceof SQLException )
+        {
             return true;
-        } else if (throwable instanceof InvocationTargetException) {
+        }
+        else if ( throwable instanceof InvocationTargetException )
+        {
             return true;
-        } else if (isThrowableNested()) {
+        }
+        else if ( isThrowableNested() )
+        {
             return true;
         }
 
         Class cls = throwable.getClass();
-        for (int i = 0, isize = CAUSE_METHOD_NAMES.length; i < isize; i++) {
-            try {
-                Method method = cls.getMethod(CAUSE_METHOD_NAMES[i], null);
-                if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) {
+        for ( int i = 0, isize = CAUSE_METHOD_NAMES.length; i < isize; i++ )
+        {
+            try
+            {
+                Method method = cls.getMethod( CAUSE_METHOD_NAMES[i], null );
+                if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) )
+                {
                     return true;
                 }
-            } catch (NoSuchMethodException ignored) {
-            } catch (SecurityException ignored) {
+            }
+            catch ( NoSuchMethodException ignored )
+            {
+            }
+            catch ( SecurityException ignored )
+            {
             }
         }
 
-        try {
-            Field field = cls.getField("detail");
-            if (field != null) {
+        try
+        {
+            Field field = cls.getField( "detail" );
+            if ( field != null )
+            {
                 return true;
             }
-        } catch (NoSuchFieldException ignored) {
-        } catch (SecurityException ignored) {
+        }
+        catch ( NoSuchFieldException ignored )
+        {
+        }
+        catch ( SecurityException ignored )
+        {
         }
 
         return false;
@@ -353,94 +427,107 @@
 
     //-----------------------------------------------------------------------
     /**
-     * <p>Counts the number of <code>Throwable</code> objects in the
-     * exception chain.</p>
-     * 
-     * <p>A throwable without cause will return <code>1</code>.
-     * A throwable with one cause will return <code>2</code> and so on.
-     * A <code>null</code> throwable will return <code>0</code>.</p>
-     * 
-     * @param throwable  the throwable to inspect, may be null
+     * <p>Counts the number of <code>Throwable</code> objects in the exception
+     * chain.</p>
+     * <p/>
+     * <p>A throwable without cause will return <code>1</code>. A throwable with
+     * one cause will return <code>2</code> and so on. A <code>null</code>
+     * throwable will return <code>0</code>.</p>
+     *
+     * @param throwable the throwable to inspect, may be null
      * @return the count of throwables, zero if null input
      */
-    public static int getThrowableCount(Throwable throwable) {
+    public static int getThrowableCount( Throwable throwable )
+    {
         int count = 0;
-        while (throwable != null) {
+        while ( throwable != null )
+        {
             count++;
-            throwable = ExceptionUtils.getCause(throwable);
+            throwable = ExceptionUtils.getCause( throwable );
         }
         return count;
     }
 
+
     /**
-     * <p>Returns the list of <code>Throwable</code> objects in the
-     * exception chain.</p>
-     * 
-     * <p>A throwable without cause will return an array containing
-     * one element - the input throwable.
-     * A throwable with one cause will return an array containing
-     * two elements. - the input throwable and the cause throwable.
-     * A <code>null</code> throwable will return an array size zero.</p>
+     * <p>Returns the list of <code>Throwable</code> objects in the exception
+     * chain.</p>
+     * <p/>
+     * <p>A throwable without cause will return an array containing one element
+     * - the input throwable. A throwable with one cause will return an array
+     * containing two elements. - the input throwable and the cause throwable. A
+     * <code>null</code> throwable will return an array size zero.</p>
      *
-     * @param throwable  the throwable to inspect, may be null
+     * @param throwable the throwable to inspect, may be null
      * @return the array of throwables, never null
      */
-    public static Throwable[] getThrowables(Throwable throwable) {
+    public static Throwable[] getThrowables( Throwable throwable )
+    {
         List list = new ArrayList();
-        while (throwable != null) {
-            list.add(throwable);
-            throwable = ExceptionUtils.getCause(throwable);
+        while ( throwable != null )
+        {
+            list.add( throwable );
+            throwable = ExceptionUtils.getCause( throwable );
         }
-        return (Throwable[]) list.toArray(new Throwable[list.size()]);
+        return ( Throwable[] ) list.toArray( new Throwable[list.size()] );
     }
 
     //-----------------------------------------------------------------------
     /**
      * <p>Returns the (zero based) index of the first <code>Throwable</code>
      * that matches the specified type in the exception chain.</p>
-     * 
-     * <p>A <code>null</code> throwable returns <code>-1</code>.
-     * A <code>null</code> type returns <code>-1</code>.
-     * No match in the chain returns <code>-1</code>.</p>
+     * <p/>
+     * <p>A <code>null</code> throwable returns <code>-1</code>. A
+     * <code>null</code> type returns <code>-1</code>. No match in the chain
+     * returns <code>-1</code>.</p>
      *
-     * @param throwable  the throwable to inspect, may be null
-     * @param type  the type to search for
+     * @param throwable the throwable to inspect, may be null
+     * @param type      the type to search for
      * @return the index into the throwable chain, -1 if no match or null input
      */
-    public static int indexOfThrowable(Throwable throwable, Class type) {
-        return indexOfThrowable(throwable, type, 0);
+    public static int indexOfThrowable( Throwable throwable, Class type )
+    {
+        return indexOfThrowable( throwable, type, 0 );
     }
 
+
     /**
      * <p>Returns the (zero based) index of the first <code>Throwable</code>
-     * that matches the specified type in the exception chain from
-     * a specified index.</p>
-     * 
-     * <p>A <code>null</code> throwable returns <code>-1</code>.
-     * A <code>null</code> type returns <code>-1</code>.
-     * No match in the chain returns <code>-1</code>.
-     * A negative start index is treated as zero.
-     * A start index greater than the number of throwables returns <code>-1</code>.</p>
-     *
-     * @param throwable  the throwable to inspect, may be null
-     * @param type  the type to search for
-     * @param fromIndex  the (zero based) index of the starting position,
-     *  negative treated as zero, larger than chain size returns -1
+     * that matches the specified type in the exception chain from a specified
+     * index.</p>
+     * <p/>
+     * <p>A <code>null</code> throwable returns <code>-1</code>. A
+     * <code>null</code> type returns <code>-1</code>. No match in the chain
+     * returns <code>-1</code>. A negative start index is treated as zero. A
+     * start index greater than the number of throwables returns
+     * <code>-1</code>.</p>
+     *
+     * @param throwable the throwable to inspect, may be null
+     * @param type      the type to search for
+     * @param fromIndex the (zero based) index of the starting position,
+     *                  negative treated as zero, larger than chain size returns
+     *                  -1
      * @return the index into the throwable chain, -1 if no match or null input
      */
-    public static int indexOfThrowable(Throwable throwable, Class type, int fromIndex) {
-        if (throwable == null) {
+    public static int indexOfThrowable( Throwable throwable, Class type, int fromIndex )
+    {
+        if ( throwable == null )
+        {
             return -1;
         }
-        if (fromIndex < 0) {
+        if ( fromIndex < 0 )
+        {
             fromIndex = 0;
         }
-        Throwable[] throwables = ExceptionUtils.getThrowables(throwable);
-        if (fromIndex >= throwables.length) {
+        Throwable[] throwables = ExceptionUtils.getThrowables( throwable );
+        if ( fromIndex >= throwables.length )
+        {
             return -1;
         }
-        for (int i = fromIndex; i < throwables.length; i++) {
-            if (throwables[i].getClass().equals(type)) {
+        for ( int i = fromIndex; i < throwables.length; i++ )
+        {
+            if ( throwables[i].getClass().equals( type ) )
+            {
                 return i;
             }
         }
@@ -449,80 +536,91 @@
 
     //-----------------------------------------------------------------------
     /**
-     * <p>Prints a compact stack trace for the root cause of a throwable
-     * to <code>System.err</code>.</p>
-     * 
-     * <p>The compact stack trace starts with the root cause and prints
-     * stack frames up to the place where it was caught and wrapped.
-     * Then it prints the wrapped exception and continues with stack frames
-     * until the wrapper exception is caught and wrapped again, etc.</p>
-     *
-     * <p>The method is equivalent to <code>printStackTrace</code> for throwables
-     * that don't have nested causes.</p>
-     * 
-     * @param throwable  the throwable to output
+     * <p>Prints a compact stack trace for the root cause of a throwable to
+     * <code>System.err</code>.</p>
+     * <p/>
+     * <p>The compact stack trace starts with the root cause and prints stack
+     * frames up to the place where it was caught and wrapped. Then it prints
+     * the wrapped exception and continues with stack frames until the wrapper
+     * exception is caught and wrapped again, etc.</p>
+     * <p/>
+     * <p>The method is equivalent to <code>printStackTrace</code> for
+     * throwables that don't have nested causes.</p>
+     *
+     * @param throwable the throwable to output
      * @since 2.0
      */
-    public static void printRootCauseStackTrace(Throwable throwable) {
-        printRootCauseStackTrace(throwable, System.err);
+    public static void printRootCauseStackTrace( Throwable throwable )
+    {
+        printRootCauseStackTrace( throwable, System.err );
     }
 
+
     /**
      * <p>Prints a compact stack trace for the root cause of a throwable.</p>
+     * <p/>
+     * <p>The compact stack trace starts with the root cause and prints stack
+     * frames up to the place where it was caught and wrapped. Then it prints
+     * the wrapped exception and continues with stack frames until the wrapper
+     * exception is caught and wrapped again, etc.</p>
+     * <p/>
+     * <p>The method is equivalent to <code>printStackTrace</code> for
+     * throwables that don't have nested causes.</p>
      *
-     * <p>The compact stack trace starts with the root cause and prints
-     * stack frames up to the place where it was caught and wrapped.
-     * Then it prints the wrapped exception and continues with stack frames
-     * until the wrapper exception is caught and wrapped again, etc.</p>
-     *
-     * <p>The method is equivalent to <code>printStackTrace</code> for throwables
-     * that don't have nested causes.</p>
-     * 
-     * @param throwable  the throwable to output, may be null
-     * @param stream  the stream to output to, may not be null
+     * @param throwable the throwable to output, may be null
+     * @param stream    the stream to output to, may not be null
      * @throws IllegalArgumentException if the stream is <code>null</code>
      * @since 2.0
      */
-    public static void printRootCauseStackTrace(Throwable throwable, PrintStream stream) {
-        if (throwable == null) {
+    public static void printRootCauseStackTrace( Throwable throwable, PrintStream stream )
+    {
+        if ( throwable == null )
+        {
             return;
         }
-        if (stream == null) {
-            throw new IllegalArgumentException("The PrintStream must not be null");
-        }
-        String trace[] = getRootCauseStackTrace(throwable);
-        for (int i = 0; i < trace.length; i++) {
-            stream.println(trace[i]);
+        if ( stream == null )
+        {
+            throw new IllegalArgumentException( "The PrintStream must not be null" );
+        }
+        String trace[] = getRootCauseStackTrace( throwable );
+        for ( int i = 0; i < trace.length; i++ )
+        {
+            stream.println( trace[i] );
         }
         stream.flush();
     }
 
+
     /**
      * <p>Prints a compact stack trace for the root cause of a throwable.</p>
+     * <p/>
+     * <p>The compact stack trace starts with the root cause and prints stack
+     * frames up to the place where it was caught and wrapped. Then it prints
+     * the wrapped exception and continues with stack frames until the wrapper
+     * exception is caught and wrapped again, etc.</p>
+     * <p/>
+     * <p>The method is equivalent to <code>printStackTrace</code> for
+     * throwables that don't have nested causes.</p>
      *
-     * <p>The compact stack trace starts with the root cause and prints
-     * stack frames up to the place where it was caught and wrapped.
-     * Then it prints the wrapped exception and continues with stack frames
-     * until the wrapper exception is caught and wrapped again, etc.</p>
-     *
-     * <p>The method is equivalent to <code>printStackTrace</code> for throwables
-     * that don't have nested causes.</p>
-     * 
-     * @param throwable  the throwable to output, may be null
-     * @param writer  the writer to output to, may not be null
+     * @param throwable the throwable to output, may be null
+     * @param writer    the writer to output to, may not be null
      * @throws IllegalArgumentException if the writer is <code>null</code>
      * @since 2.0
      */
-    public static void printRootCauseStackTrace(Throwable throwable, PrintWriter writer) {
-        if (throwable == null) {
+    public static void printRootCauseStackTrace( Throwable throwable, PrintWriter writer )
+    {
+        if ( throwable == null )
+        {
             return;
         }
-        if (writer == null) {
-            throw new IllegalArgumentException("The PrintWriter must not be null");
-        }
-        String trace[] = getRootCauseStackTrace(throwable);
-        for (int i = 0; i < trace.length; i++) {
-            writer.println(trace[i]);
+        if ( writer == null )
+        {
+            throw new IllegalArgumentException( "The PrintWriter must not be null" );
+        }
+        String trace[] = getRootCauseStackTrace( throwable );
+        for ( int i = 0; i < trace.length; i++ )
+        {
+            writer.println( trace[i] );
         }
         writer.flush();
     }
@@ -531,58 +629,72 @@
     /**
      * <p>Creates a compact stack trace for the root cause of the supplied
      * <code>Throwable</code>.</p>
-     * 
-     * @param throwable  the throwable to examine, may be null
+     *
+     * @param throwable the throwable to examine, may be null
      * @return an array of stack trace frames, never null
      * @since 2.0
      */
-    public static String[] getRootCauseStackTrace(Throwable throwable) {
-        if (throwable == null) {
+    public static String[] getRootCauseStackTrace( Throwable throwable )
+    {
+        if ( throwable == null )
+        {
             return ArrayUtils.EMPTY_STRING_ARRAY;
         }
-        Throwable throwables[] = getThrowables(throwable);
+        Throwable throwables[] = getThrowables( throwable );
         int count = throwables.length;
         ArrayList frames = new ArrayList();
-        List nextTrace = getStackFrameList(throwables[count - 1]);
-        for (int i = count; --i >= 0;) {
+        List nextTrace = getStackFrameList( throwables[count - 1] );
+        for ( int i = count; --i >= 0; )
+        {
             List trace = nextTrace;
-            if (i != 0) {
-                nextTrace = getStackFrameList(throwables[i - 1]);
-                removeCommonFrames(trace, nextTrace);
+            if ( i != 0 )
+            {
+                nextTrace = getStackFrameList( throwables[i - 1] );
+                removeCommonFrames( trace, nextTrace );
             }
-            if (i == count - 1) {
-                frames.add(throwables[i].toString());
-            } else {
-                frames.add(WRAPPED_MARKER + throwables[i].toString());
+            if ( i == count - 1 )
+            {
+                frames.add( throwables[i].toString() );
             }
-            for (int j = 0; j < trace.size(); j++) {
-                frames.add(trace.get(j));
+            else
+            {
+                frames.add( WRAPPED_MARKER + throwables[i].toString() );
+            }
+            for ( int j = 0; j < trace.size(); j++ )
+            {
+                frames.add( trace.get( j ) );
             }
         }
-        return (String[]) frames.toArray(new String[0]);
+        return ( String[] ) frames.toArray( new String[0] );
     }
 
+
     /**
-     * <p>Removes common frames from the cause trace given the two stack traces.</p>
-     * 
-     * @param causeFrames  stack trace of a cause throwable
-     * @param wrapperFrames  stack trace of a wrapper throwable
+     * <p>Removes common frames from the cause trace given the two stack
+     * traces.</p>
+     *
+     * @param causeFrames   stack trace of a cause throwable
+     * @param wrapperFrames stack trace of a wrapper throwable
      * @throws IllegalArgumentException if either argument is null
      * @since 2.0
      */
-    public static void removeCommonFrames(List causeFrames, List wrapperFrames) {
-        if (causeFrames == null || wrapperFrames == null) {
-            throw new IllegalArgumentException("The List must not be null");
+    public static void removeCommonFrames( List causeFrames, List wrapperFrames )
+    {
+        if ( causeFrames == null || wrapperFrames == null )
+        {
+            throw new IllegalArgumentException( "The List must not be null" );
         }
         int causeFrameIndex = causeFrames.size() - 1;
         int wrapperFrameIndex = wrapperFrames.size() - 1;
-        while (causeFrameIndex >= 0 && wrapperFrameIndex >= 0) {
+        while ( causeFrameIndex >= 0 && wrapperFrameIndex >= 0 )
+        {
             // Remove the frame from the cause trace if it is the same
             // as in the wrapper trace
-            String causeFrame = (String) causeFrames.get(causeFrameIndex);
-            String wrapperFrame = (String) wrapperFrames.get(wrapperFrameIndex);
-            if (causeFrame.equals(wrapperFrame)) {
-                causeFrames.remove(causeFrameIndex);
+            String causeFrame = ( String ) causeFrames.get( causeFrameIndex );
+            String wrapperFrame = ( String ) wrapperFrames.get( wrapperFrameIndex );
+            if ( causeFrame.equals( wrapperFrame ) )
+            {
+                causeFrames.remove( causeFrameIndex );
             }
             causeFrameIndex--;
             wrapperFrameIndex--;
@@ -593,31 +705,36 @@
     /**
      * <p>Gets the stack trace from a Throwable as a String.</p>
      *
-     * @param throwable  the <code>Throwable</code> to be examined
+     * @param throwable the <code>Throwable</code> to be examined
      * @return the stack trace as generated by the exception's
-     *  <code>printStackTrace(PrintWriter)</code> method
+     *         <code>printStackTrace(PrintWriter)</code> method
      */
-    public static String getStackTrace(Throwable throwable) {
+    public static String getStackTrace( Throwable throwable )
+    {
         StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw, true);
-        throwable.printStackTrace(pw);
+        PrintWriter pw = new PrintWriter( sw, true );
+        throwable.printStackTrace( pw );
         return sw.getBuffer().toString();
     }
 
+
     /**
      * <p>A way to get the entire nested stack-trace of an throwable.</p>
      *
-     * @param throwable  the <code>Throwable</code> to be examined
+     * @param throwable the <code>Throwable</code> to be examined
      * @return the nested stack trace, with the root cause first
      * @since 2.0
      */
-    public static String getFullStackTrace(Throwable throwable) {
+    public static String getFullStackTrace( Throwable throwable )
+    {
         StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw, true);
-        Throwable[] ts = getThrowables(throwable);
-        for (int i = 0; i < ts.length; i++) {
-            ts[i].printStackTrace(pw);
-            if (isNestedThrowable(ts[i])) {
+        PrintWriter pw = new PrintWriter( sw, true );
+        Throwable[] ts = getThrowables( throwable );
+        for ( int i = 0; i < ts.length; i++ )
+        {
+            ts[i].printStackTrace( pw );
+            if ( isNestedThrowable( ts[i] ) )
+            {
                 break;
             }
         }
@@ -627,62 +744,71 @@
     //-----------------------------------------------------------------------
     /**
      * <p>Captures the stack trace associated with the specified
-     * <code>Throwable</code> object, decomposing it into a list of
-     * stack frames.</p>
+     * <code>Throwable</code> object, decomposing it into a list of stack
+     * frames.</p>
      *
-     * @param throwable  the <code>Throwable</code> to examine, may be null
+     * @param throwable the <code>Throwable</code> to examine, may be null
      * @return an array of strings describing each stack frame, never null
      */
-    public static String[] getStackFrames(Throwable throwable) {
-        if (throwable == null) {
+    public static String[] getStackFrames( Throwable throwable )
+    {
+        if ( throwable == null )
+        {
             return ArrayUtils.EMPTY_STRING_ARRAY;
         }
-        return getStackFrames(getStackTrace(throwable));
+        return getStackFrames( getStackTrace( throwable ) );
     }
 
+
     /**
-     * <p>Functionality shared between the
-     * <code>getStackFrames(Throwable)</code> methods of this and the
+     * <p>Functionality shared between the <code>getStackFrames(Throwable)</code>
+     * methods of this and the
      */
-    static String[] getStackFrames(String stackTrace) {
+    static String[] getStackFrames( String stackTrace )
+    {
         String linebreak = SystemUtils.LINE_SEPARATOR;
-        StringTokenizer frames = new StringTokenizer(stackTrace, linebreak);
+        StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
         List list = new LinkedList();
-        while (frames.hasMoreTokens()) {
-            list.add(frames.nextToken());
+        while ( frames.hasMoreTokens() )
+        {
+            list.add( frames.nextToken() );
         }
-        return (String[]) list.toArray(new String[list.size()]);
+        return ( String[] ) list.toArray( new String[list.size()] );
     }
 
+
     /**
-     * <p>Produces a <code>List</code> of stack frames - the message
-     * is not included.</p>
+     * <p>Produces a <code>List</code> of stack frames - the message is not
+     * included.</p>
+     * <p/>
+     * <p>This works in most cases - it will only fail if the exception message
+     * contains a line that starts with: <code>&quot;&nbsp;&nbsp;&nbsp;at&quot;.</code></p>
      *
-     * <p>This works in most cases - it will only fail if the exception
-     * message contains a line that starts with:
-     * <code>&quot;&nbsp;&nbsp;&nbsp;at&quot;.</code></p>
-     * 
      * @param t is any throwable
      * @return List of stack frames
      */
-    static List getStackFrameList(Throwable t) {
-        String stackTrace = getStackTrace(t);
+    static List getStackFrameList( Throwable t )
+    {
+        String stackTrace = getStackTrace( t );
         String linebreak = SystemUtils.LINE_SEPARATOR;
-        StringTokenizer frames = new StringTokenizer(stackTrace, linebreak);
+        StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
         List list = new LinkedList();
         boolean traceStarted = false;
-        while (frames.hasMoreTokens()) {
+        while ( frames.hasMoreTokens() )
+        {
             String token = frames.nextToken();
             // Determine if the line starts with <whitespace>at
-            int at = token.indexOf("at");
-            if (at != -1 && token.substring(0, at).trim().length() == 0) {
+            int at = token.indexOf( "at" );
+            if ( at != -1 && token.substring( 0, at ).trim().length() == 0 )
+            {
                 traceStarted = true;
-                list.add(token);
-            } else if (traceStarted) {
+                list.add( token );
+            }
+            else if ( traceStarted )
+            {
                 break;
             }
         }
         return list;
     }
-    
 }

Mime
View raw message