diff --git a/ldap-convert/src/main/java/org/apache/directory/shared/converter/schema/SchemaParser.java b/ldap-convert/src/main/java/org/apache/directory/shared/converter/schema/SchemaParser.java
index 1e30bf6..bfdac19 100755
--- a/ldap-convert/src/main/java/org/apache/directory/shared/converter/schema/SchemaParser.java
+++ b/ldap-convert/src/main/java/org/apache/directory/shared/converter/schema/SchemaParser.java
@@ -30,30 +30,12 @@
 import java.text.ParseException;
 import java.util.List;
 
+import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.directory.shared.i18n.I18n;
-import org.apache.directory.shared.ldap.util.ExceptionUtils;
 
 import antlr.RecognitionException;
 import antlr.TokenStreamException;
 
-/*
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.io.Writer;
-import java.text.ParseException;
-import java.util.List;
-
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
-import org.apache.directory.shared.ldap.util.ExceptionUtils;
-*/
-
 
 /**
  * A reusable wrapper for antlr generated schema parsers.
diff --git a/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoader.java b/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoader.java
index 55cd283..c0d51da 100644
--- a/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoader.java
+++ b/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoader.java
@@ -22,21 +22,17 @@
 
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.FileWriter;
 import java.io.FilenameFilter;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.directory.shared.i18n.I18n;
-import org.apache.directory.shared.ldap.constants.MetaSchemaConstants;
 import org.apache.directory.shared.ldap.constants.SchemaConstants;
 import org.apache.directory.shared.ldap.entry.Entry;
 import org.apache.directory.shared.ldap.ldif.LdifEntry;
 import org.apache.directory.shared.ldap.ldif.LdifReader;
-import org.apache.directory.shared.ldap.ldif.LdifUtils;
 import org.apache.directory.shared.ldap.schema.registries.AbstractSchemaLoader;
 import org.apache.directory.shared.ldap.schema.registries.Schema;
-import org.apache.directory.shared.ldap.util.DateUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -64,13 +60,6 @@
     /** Speedup for DEBUG mode */
     private static final boolean IS_DEBUG = LOG.isDebugEnabled();
 
-    /**
-     * the administrator DN - very ADS specific but we need some DN here for
-     * the modifiers name when the system modifies by itself enabled and 
-     * disabled schemas in the repository.
-     */
-    private static final String ADMIN_SYSTEM_DN = "uid=admin,ou=system";
-
     /** directory containing the schema LDIF file for ou=schema */
     private final File baseDirectory;
 
@@ -245,69 +234,6 @@
 
     
     /**
-     * Utility method used to enable a specific schema on disk in the LDIF
-     * based schema repository.  This method will remove the m-disabled AT
-     * in the schema file and update the modifiersName and modifyTimestamp.
-     * 
-     * The modifiersName and modifyTimestamp on the schema.ldif file will
-     * also be updated to indicate a change to the schema.
-     *
-     * @param schema the disabled schema to enable
-     * @throws Exception if there are problems writing changes back to disk
-     */
-    private void enableSchema( Schema schema ) throws Exception
-    {
-        // -------------------------------------------------------------------
-        // Modifying the foo schema foo.ldif file to be enabled but still
-        // have to now update the timestamps and update the modifiersName
-        // -------------------------------------------------------------------
-
-        File schemaLdifFile = new File( new File( baseDirectory, SchemaConstants.OU_SCHEMA ), "cn="
-            + schema.getSchemaName() + "." + LDIF_EXT );
-        LdifReader reader = new LdifReader( schemaLdifFile );
-        LdifEntry ldifEntry = reader.next();
-        Entry entry = ldifEntry.getEntry();
-
-        entry.removeAttributes( "changeType" );
-        entry.removeAttributes( SchemaConstants.MODIFIERS_NAME_AT );
-        entry.removeAttributes( SchemaConstants.MODIFY_TIMESTAMP_AT );
-        entry.removeAttributes( MetaSchemaConstants.M_DISABLED_AT );
-
-        entry.add( SchemaConstants.MODIFIERS_NAME_AT, ADMIN_SYSTEM_DN );
-        entry.add( SchemaConstants.MODIFY_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
-
-        FileWriter out = new FileWriter( schemaLdifFile );
-        out.write( LdifUtils.convertEntryToLdif( entry ) );
-        out.flush();
-        out.close();
-
-        // -------------------------------------------------------------------
-        // Now we need to update the timestamp on the schema.ldif file which
-        // shows that something changed below the schema directory in schema
-        // -------------------------------------------------------------------
-
-        schemaLdifFile = new File( baseDirectory, "ou=schema." + LDIF_EXT );
-        reader = new LdifReader( schemaLdifFile );
-        ldifEntry = reader.next();
-        entry = ldifEntry.getEntry();
-
-        entry.removeAttributes( "changeType" );
-        entry.removeAttributes( SchemaConstants.MODIFIERS_NAME_AT );
-        entry.removeAttributes( SchemaConstants.MODIFY_TIMESTAMP_AT );
-
-        entry.add( SchemaConstants.MODIFIERS_NAME_AT, ADMIN_SYSTEM_DN );
-        entry.add( SchemaConstants.MODIFY_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
-
-        out = new FileWriter( schemaLdifFile );
-        out.write( LdifUtils.convertEntryToLdif( entry ) );
-        out.flush();
-        out.close();
-
-        reader.close();
-    }
-
-
-    /**
      * Utility method to get the file for a schema directory.
      *
      * @param schema the schema to get the file for
diff --git a/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/SchemaEntityFactory.java b/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/SchemaEntityFactory.java
index 633b1cd..23bb38d 100644
--- a/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/SchemaEntityFactory.java
+++ b/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/SchemaEntityFactory.java
@@ -21,7 +21,6 @@
 
 
 import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -74,13 +73,6 @@
     /** Slf4j logger */
     private final static Logger LOG = LoggerFactory.getLogger( SchemaEntityFactory.class );
 
-    /** for fast debug checks */
-    private static final boolean IS_DEBUG = LOG.isDebugEnabled();
-
-    /** Used for looking up the setRegistries(Registries) method */
-    private final static Class<?>[] parameterTypes = new Class[]
-        { Registries.class };
-
     private static final List<String> EMPTY_LIST = new ArrayList<String>();
     private static final String[] EMPTY_ARRAY = new String[]
         {};
@@ -258,8 +250,8 @@
     /**
      * Class load a syntaxChecker instance
      */
-    private SyntaxChecker classLoadSyntaxChecker( SchemaManager schemaManager, String oid, String className,
-        EntryAttribute byteCode, Registries targetRegistries ) throws Exception
+    private SyntaxChecker classLoadSyntaxChecker( String oid, String className, EntryAttribute byteCode )
+        throws Exception
     {
         // Try to class load the syntaxChecker
         Class<?> clazz = null;
@@ -328,7 +320,7 @@
         EntryAttribute byteCode = entry.get( MetaSchemaConstants.M_BYTECODE_AT );
 
         // Class load the syntaxChecker
-        SyntaxChecker syntaxChecker = classLoadSyntaxChecker( schemaManager, oid, className, byteCode, targetRegistries );
+        SyntaxChecker syntaxChecker = classLoadSyntaxChecker( oid, className, byteCode );
 
         // Update the common fields
         setSchemaObjectProperties( syntaxChecker, entry, schema );
@@ -368,7 +360,7 @@
         EntryAttribute byteCode = getByteCode( syntaxCheckerDescription, SchemaConstants.SYNTAX_CHECKER );
 
         // Class load the SyntaxChecker
-        SyntaxChecker syntaxChecker = classLoadSyntaxChecker( schemaManager, oid, fqcn, byteCode, targetRegistries );
+        SyntaxChecker syntaxChecker = classLoadSyntaxChecker( oid, fqcn, byteCode );
 
         // Update the common fields
         setSchemaObjectProperties( syntaxChecker, syntaxCheckerDescription, schema );
@@ -381,7 +373,7 @@
      * Class load a comparator instances
      */
     private LdapComparator<?> classLoadComparator( SchemaManager schemaManager, String oid, String className,
-        EntryAttribute byteCode, Registries targetRegistries ) throws Exception
+        EntryAttribute byteCode ) throws Exception
     {
         // Try to class load the comparator
         LdapComparator<?> comparator = null;
@@ -413,7 +405,7 @@
             // Ok, let's try with the constructor without argument.
             // In this case, we will have to check that the OID is the same than
             // the one we got in the Comparator entry
-            Constructor<?> constructor = clazz.getConstructor();
+            clazz.getConstructor();
             comparator = ( LdapComparator<?> ) clazz.newInstance();
 
             if ( !comparator.getOid().equals( oid ) )
@@ -464,7 +456,7 @@
         EntryAttribute byteCode = getByteCode( comparatorDescription, SchemaConstants.COMPARATOR );
 
         // Class load the comparator
-        LdapComparator<?> comparator = classLoadComparator( schemaManager, oid, fqcn, byteCode, targetRegistries );
+        LdapComparator<?> comparator = classLoadComparator( schemaManager, oid, fqcn, byteCode );
 
         // Update the common fields
         setSchemaObjectProperties( comparator, comparatorDescription, schema );
@@ -510,7 +502,7 @@
         EntryAttribute byteCode = entry.get( MetaSchemaConstants.M_BYTECODE_AT );
 
         // Class load the comparator
-        LdapComparator<?> comparator = classLoadComparator( schemaManager, oid, fqcn, byteCode, targetRegistries );
+        LdapComparator<?> comparator = classLoadComparator( schemaManager, oid, fqcn, byteCode );
 
         // Update the common fields
         setSchemaObjectProperties( comparator, entry, schema );
@@ -524,7 +516,7 @@
      * Class load a normalizer instances
      */
     private Normalizer classLoadNormalizer( SchemaManager schemaManager, String oid, String className,
-        EntryAttribute byteCode, Registries targetRegistries ) throws Exception
+        EntryAttribute byteCode ) throws Exception
     {
         // Try to class load the normalizer
         Class<?> clazz = null;
@@ -588,7 +580,7 @@
         EntryAttribute byteCode = getByteCode( normalizerDescription, SchemaConstants.NORMALIZER );
 
         // Class load the normalizer
-        Normalizer normalizer = classLoadNormalizer( schemaManager, oid, fqcn, byteCode, targetRegistries );
+        Normalizer normalizer = classLoadNormalizer( schemaManager, oid, fqcn, byteCode );
 
         // Update the common fields
         setSchemaObjectProperties( normalizer, normalizerDescription, schema );
@@ -634,7 +626,7 @@
         EntryAttribute byteCode = entry.get( MetaSchemaConstants.M_BYTECODE_AT );
 
         // Class load the Normalizer
-        Normalizer normalizer = classLoadNormalizer( schemaManager, oid, className, byteCode, targetRegistries );
+        Normalizer normalizer = classLoadNormalizer( schemaManager, oid, className, byteCode );
 
         // Update the common fields
         setSchemaObjectProperties( normalizer, entry, schema );
@@ -645,42 +637,6 @@
 
 
     /**
-     * Uses reflection to see if a setRegistries( Registries ) method exists on the
-     * object's class.  If so then the registries are dependency injected into the 
-     * new schema object.
-     * 
-     * @param obj a schema object to have a Registries dependency injected.
-     */
-    private void injectRegistries( Object obj, Registries targetRegistries ) throws Exception
-    {
-        Method method = null;
-
-        try
-        {
-            method = obj.getClass().getMethod( "setRegistries", parameterTypes );
-        }
-        catch ( NoSuchMethodException e )
-        {
-            if ( IS_DEBUG )
-            {
-                LOG.debug( obj.getClass() + " has no setRegistries() method." );
-            }
-
-            return;
-        }
-
-        if ( method == null )
-        {
-            return;
-        }
-
-        Object[] args = new Object[]
-            { targetRegistries };
-        method.invoke( obj, args );
-    }
-
-
-    /**
      * {@inheritDoc}
      * @throws LdapInvalidAttributeValueException 
      * @throws LdapUnwillingToPerformException 
diff --git a/ldap-schema-manager/src/main/java/org/apache/directory/shared/ldap/schema/manager/impl/DefaultSchemaManager.java b/ldap-schema-manager/src/main/java/org/apache/directory/shared/ldap/schema/manager/impl/DefaultSchemaManager.java
index 84b03b6..5bf98b0 100644
--- a/ldap-schema-manager/src/main/java/org/apache/directory/shared/ldap/schema/manager/impl/DefaultSchemaManager.java
+++ b/ldap-schema-manager/src/main/java/org/apache/directory/shared/ldap/schema/manager/impl/DefaultSchemaManager.java
@@ -36,7 +36,6 @@
 import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
 import org.apache.directory.shared.ldap.exception.LdapProtocolErrorException;
 import org.apache.directory.shared.ldap.exception.LdapUnwillingToPerformException;
-//import org.apache.directory.shared.ldap.exception.LdapSchemaViolationException;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.name.DN;
 import org.apache.directory.shared.ldap.schema.AttributeType;
@@ -113,7 +112,7 @@
 
     /** the normalized name for the schema modification attributes */
     private DN schemaModificationAttributesDN;
-    
+
     /** A Map containing all the schema being dependent from a schema */
     private Map<String, Set<String>> schemaDependences = new HashMap<String, Set<String>>();
 
@@ -197,14 +196,15 @@
         for ( String schemaName : schemas )
         {
             Schema schema = schemaLoader.getSchema( schemaName );
-            
+
             if ( schema != null )
             {
                 schemaArray[n++] = schema;
             }
             else
             {
-                throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_11001, schemaName ) );
+                throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err(
+                    I18n.ERR_11001, schemaName ) );
             }
         }
 
@@ -216,7 +216,7 @@
     {
         // Create a content container for this schema
         registries.addSchema( schema.getSchemaName() );
-        
+
         // And inject any existig SchemaObject into the registries 
         addComparators( schema, registries );
         addNormalizers( schema, registries );
@@ -257,25 +257,6 @@
         }
     }
 
-    
-    /**
-     * Tells if there are schemaObjects for a given schema from the registries
-     */
-    private boolean hasSchemaObjects( Schema schema, Registries registries ) throws Exception
-    {
-        Map<String, Set<SchemaObjectWrapper>> schemaObjects = registries.getObjectBySchemaName();
-        Set<SchemaObjectWrapper> content = schemaObjects.get( StringTools.toLowerCase( schema.getSchemaName() ) );
-
-        if ( ( content == null ) || content.isEmpty() )
-        {
-            return false;
-        }
-        else
-        {
-            return true;
-        }
-    }
-
 
     //-----------------------------------------------------------------------
     // API methods
@@ -531,7 +512,7 @@
         {
             return true;
         }
-        
+
         boolean loaded = false;
 
         // Reset the errors if not null
@@ -547,7 +528,7 @@
         // Load the schemas
         for ( Schema schema : schemas )
         {
-            if ( !load( clonedRegistries, schema ) && ( ! errors.isEmpty() ) )
+            if ( !load( clonedRegistries, schema ) && ( !errors.isEmpty() ) )
             {
                 return false;
             }
@@ -570,26 +551,26 @@
                 for ( Schema schema : schemas )
                 {
                     load( registries, schema );
-                    
+
                     // Update the schema dependences if needed
-                    
+
                     if ( schema.getDependencies() != null )
                     {
                         for ( String dep : schema.getDependencies() )
                         {
                             Set<String> deps = schemaDependences.get( dep );
-                            
+
                             if ( deps == null )
                             {
                                 deps = new HashSet<String>();
                                 deps.add( schema.getSchemaName() );
                             }
-                            
+
                             // Replace the dependences
                             schemaDependences.put( dep, deps );
                         }
                     }
-                    
+
                     // add the schema to the schemaLoader
                     schemaLoader.addSchema( schema );
                 }
@@ -618,7 +599,7 @@
         {
             return true;
         }
-        
+
         Schema[] schemas = toArray( schemaNames );
 
         return load( schemas );
@@ -661,7 +642,7 @@
         else
         {
             LOG.info( "Loading {} enabled schema: \n{}", schema.getSchemaName(), schema );
-            
+
             // Check that the dependencies, if any, are correct
             if ( schema.getDependencies() != null )
             {
@@ -692,6 +673,8 @@
      * - isRelaxed
      * - disabledAccepted
      */
+    // False positive
+    @SuppressWarnings("PMD.UnusedPrivateMethod")
     private boolean unload( Registries registries, Schema schema ) throws Exception
     {
         if ( schema == null )
@@ -749,12 +732,14 @@
     /**
      * Add all the Schema's DitContentRules
      */
+    // Not yet implemented, but may be used
+    @SuppressWarnings("PMD.UnusedFormalParameter")
     private void addDitContentRules( Schema schema, Registries registries ) throws Exception
     {
-    	if ( !schemaLoader.loadDitContentRules( schema ).isEmpty() )
-    	{
+        if ( !schemaLoader.loadDitContentRules( schema ).isEmpty() )
+        {
             throw new NotImplementedException( I18n.err( I18n.ERR_11003 ) );
-    	}
+        }
         // for ( Entry entry : schemaLoader.loadDitContentRules( schema ) )
         // {
         //     throw new NotImplementedException( I18n.err( I18n.ERR_11003 ) );
@@ -765,12 +750,14 @@
     /**
      * Add all the Schema's DitStructureRules
      */
+    // Not yet implemented, but may be used
+    @SuppressWarnings("PMD.UnusedFormalParameter")
     private void addDitStructureRules( Schema schema, Registries registries ) throws Exception
     {
-    	if ( !schemaLoader.loadDitStructureRules( schema ).isEmpty() )
-    	{
+        if ( !schemaLoader.loadDitStructureRules( schema ).isEmpty() )
+        {
             throw new NotImplementedException( I18n.err( I18n.ERR_11004 ) );
-    	}
+        }
         // for ( Entry entry : schemaLoader.loadDitStructureRules( schema ) )
         // {
         //     throw new NotImplementedException( I18n.err( I18n.ERR_11004 ) );
@@ -795,12 +782,14 @@
     /**
      * Add all the Schema's MatchingRuleUses
      */
+    // Not yet implemented, but may be used
+    @SuppressWarnings("PMD.UnusedFormalParameter")
     private void addMatchingRuleUses( Schema schema, Registries registries ) throws Exception
     {
-    	if ( !schemaLoader.loadMatchingRuleUses( schema ).isEmpty() )
-    	{
+        if ( !schemaLoader.loadMatchingRuleUses( schema ).isEmpty() )
+        {
             throw new NotImplementedException( I18n.err( I18n.ERR_11005 ) );
-    	}
+        }
         // for ( Entry entry : schemaLoader.loadMatchingRuleUses( schema ) )
         // {
         //     throw new NotImplementedException( I18n.err( I18n.ERR_11005 ) );
@@ -811,12 +800,14 @@
     /**
      * Add all the Schema's NameForms
      */
+    // Not yet implemented, but may be used
+    @SuppressWarnings("PMD.UnusedFormalParameter")
     private void addNameForms( Schema schema, Registries registries ) throws Exception
     {
-    	if ( !schemaLoader.loadNameForms( schema ).isEmpty() )
-    	{
+        if ( !schemaLoader.loadNameForms( schema ).isEmpty() )
+        {
             throw new NotImplementedException( I18n.err( I18n.ERR_11006 ) );
-    	}
+        }
         // for ( Entry entry : schemaLoader.loadNameForms( schema ) )
         // {
         //     throw new NotImplementedException( I18n.err( I18n.ERR_11006 ) );
@@ -969,7 +960,7 @@
             {
                 load( registries, schema );
             }
-            
+
             return true;
         }
         else
@@ -978,7 +969,7 @@
             {
                 schema.disable();
             }
-            
+
             return false;
         }
     }
@@ -1190,7 +1181,7 @@
         {
             errors.clear();
         }
-        
+
         // Work on a cloned and relaxed registries
         Registries clonedRegistries = cloneRegistries();
         clonedRegistries.setRelaxed();
@@ -1218,18 +1209,18 @@
                 for ( Schema schema : schemas )
                 {
                     unload( registries, schema );
-                    
+
                     // Update the schema dependences
                     for ( String dep : schema.getDependencies() )
                     {
                         Set<String> deps = schemaDependences.get( dep );
-                        
+
                         if ( deps != null )
                         {
                             deps.remove( schema.getSchemaName() );
                         }
                     }
-                    
+
                     schemaLoader.removeSchema( schema );
                 }
 
@@ -1555,8 +1546,8 @@
 
         return false;
     }
-    
-    
+
+
     /**
      * Get the inner SchemaObject if it's not a C/N/SC
      */
@@ -1614,8 +1605,8 @@
             else
             {
                 // We have an invalid SchemaObject, no need to go any further
-                Throwable error = new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
-                		I18n.err( I18n.ERR_11007, schemaObject.getOid() ) );
+                Throwable error = new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err(
+                    I18n.ERR_11007, schemaObject.getOid() ) );
                 errors.add( error );
             }
         }
@@ -1656,8 +1647,7 @@
             // The new schemaObject's OID must not already exist
             if ( checkOidExist( copy ) )
             {
-                Throwable error = new LdapProtocolErrorException(
-                		I18n.err( I18n.ERR_11008, schemaObject.getOid() ) );
+                Throwable error = new LdapProtocolErrorException( I18n.err( I18n.ERR_11008, schemaObject.getOid() ) );
                 errors.add( error );
 
                 return false;
@@ -1669,8 +1659,8 @@
             if ( schemaName == null )
             {
                 // The schema associated with the SchemzaObject does not exist. This is not valid.
-                Throwable error = new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_11009, schemaObject.getOid(),
-                        		copy.getSchemaName() ) );
+                Throwable error = new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err(
+                    I18n.ERR_11009, schemaObject.getOid(), copy.getSchemaName() ) );
                 errors.add( error );
 
                 return false;
@@ -1759,8 +1749,7 @@
             // The new schemaObject's OID must exist
             if ( !checkOidExist( schemaObject ) )
             {
-                Throwable error = new LdapProtocolErrorException( 
-                		I18n.err( I18n.ERR_11011, schemaObject.getOid() ) );
+                Throwable error = new LdapProtocolErrorException( I18n.err( I18n.ERR_11011, schemaObject.getOid() ) );
                 errors.add( error );
                 return false;
             }
@@ -2005,7 +1994,7 @@
         return !isRelaxed;
     }
 
-    
+
     /**
      * {@inheritDoc}
      */
diff --git a/ldap-schema-manager/src/test/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoaderTest.java b/ldap-schema-manager/src/test/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoaderTest.java
index 0a083f0..9ba20c2 100644
--- a/ldap-schema-manager/src/test/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoaderTest.java
+++ b/ldap-schema-manager/src/test/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoaderTest.java
@@ -32,7 +32,7 @@
 import org.apache.directory.shared.ldap.schema.ldif.extractor.impl.DefaultSchemaLdifExtractor;
 import org.apache.directory.shared.ldap.schema.loader.ldif.LdifSchemaLoader;
 import org.apache.directory.shared.ldap.schema.manager.impl.DefaultSchemaManager;
-import org.apache.directory.shared.ldap.util.ExceptionUtils;
+import org.apache.directory.shared.ldap.util.LdapExceptionUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -87,7 +87,7 @@
         
         if ( !loaded )
         {
-            fail( "Schema load failed : " + ExceptionUtils.printErrors( sm.getErrors() ) );
+            fail( "Schema load failed : " + LdapExceptionUtils.printErrors( sm.getErrors() ) );
         }
         
         assertTrue( sm.getRegistries().getAttributeTypeRegistry().contains( "cn" ) );
diff --git a/ldap-schema/src/main/java/org/apache/directory/shared/ldap/schema/ldif/extractor/impl/DefaultSchemaLdifExtractor.java b/ldap-schema/src/main/java/org/apache/directory/shared/ldap/schema/ldif/extractor/impl/DefaultSchemaLdifExtractor.java
index a7d48d5..cfce53c 100644
--- a/ldap-schema/src/main/java/org/apache/directory/shared/ldap/schema/ldif/extractor/impl/DefaultSchemaLdifExtractor.java
+++ b/ldap-schema/src/main/java/org/apache/directory/shared/ldap/schema/ldif/extractor/impl/DefaultSchemaLdifExtractor.java
@@ -125,13 +125,10 @@
      */
     public void extractOrCopy( boolean overwrite ) throws IOException
     {
-        if ( !outputDirectory.exists() )
+        if ( !outputDirectory.exists() && !outputDirectory.mkdirs() )
         {
-            if ( !outputDirectory.mkdirs() )
-            {
-                throw new IOException( I18n.err( I18n.ERR_09001_DIRECTORY_CREATION_FAILED, outputDirectory
-                    .getAbsolutePath() ) );
-            }
+            throw new IOException( I18n.err( I18n.ERR_09001_DIRECTORY_CREATION_FAILED, outputDirectory
+                .getAbsolutePath() ) );
         }
 
         File schemaDirectory = new File( outputDirectory, SCHEMA_SUBDIR );
@@ -192,13 +189,10 @@
     {
         LOG.debug( "copyFile(): source = {}, destination = {}", source, destination );
 
-        if ( !destination.getParentFile().exists() )
+        if ( !destination.getParentFile().exists() && !destination.getParentFile().mkdirs() )
         {
-            if ( !destination.getParentFile().mkdirs() )
-            {
-                throw new IOException( I18n.err( I18n.ERR_09001_DIRECTORY_CREATION_FAILED, destination.getParentFile()
-                    .getAbsolutePath() ) );
-            }
+            throw new IOException( I18n.err( I18n.ERR_09001_DIRECTORY_CREATION_FAILED, destination.getParentFile()
+                .getAbsolutePath() ) );
         }
 
         if ( !source.getParentFile().exists() )
@@ -409,13 +403,10 @@
                 return;
             }
 
-            if ( !destination.getParentFile().exists() )
+            if ( !destination.getParentFile().exists() && !destination.getParentFile().mkdirs() )
             {
-                if ( !destination.getParentFile().mkdirs() )
-                {
-                    throw new IOException( I18n.err( I18n.ERR_09001_DIRECTORY_CREATION_FAILED, destination
-                        .getParentFile().getAbsolutePath() ) );
-                }
+                throw new IOException( I18n.err( I18n.ERR_09001_DIRECTORY_CREATION_FAILED, destination
+                    .getParentFile().getAbsolutePath() ) );
             }
 
             FileOutputStream out = new FileOutputStream( destination );
diff --git a/ldap-schema/src/main/java/org/apache/directory/shared/ldap/schema/ldif/extractor/impl/ResourceMap.java b/ldap-schema/src/main/java/org/apache/directory/shared/ldap/schema/ldif/extractor/impl/ResourceMap.java
index 9870c99..575071c 100644
--- a/ldap-schema/src/main/java/org/apache/directory/shared/ldap/schema/ldif/extractor/impl/ResourceMap.java
+++ b/ldap-schema/src/main/java/org/apache/directory/shared/ldap/schema/ldif/extractor/impl/ResourceMap.java
@@ -22,7 +22,6 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.net.URL;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
diff --git a/ldap-schema/src/main/resources/schema/ou=schema/cn=adsconfig/ou=objectclasses/m-oid=1.3.6.1.4.1.18060.0.4.1.3.100.ldif b/ldap-schema/src/main/resources/schema/ou=schema/cn=adsconfig/ou=objectclasses/m-oid=1.3.6.1.4.1.18060.0.4.1.3.100.ldif
index 1af04b2..d9266b1 100644
--- a/ldap-schema/src/main/resources/schema/ou=schema/cn=adsconfig/ou=objectclasses/m-oid=1.3.6.1.4.1.18060.0.4.1.3.100.ldif
+++ b/ldap-schema/src/main/resources/schema/ou=schema/cn=adsconfig/ou=objectclasses/m-oid=1.3.6.1.4.1.18060.0.4.1.3.100.ldif
@@ -1,12 +1,10 @@
 version: 1
-dn: m-oid=1.3.6.1.4.1.18060.0.4.1.3.100, ou=objectClasses, cn=adsconfig, ou=sche
- ma
+dn: m-oid=1.3.6.1.4.1.18060.0.4.1.3.100, ou=objectClasses, cn=adsconfig, ou=schema
 createtimestamp: 20100111145217Z
 m-must: ads-directoryServiceId
 m-must: ads-dsInterceptors
 m-must: ads-dsPartitions
 m-must: ads-dsReplicaId
-m-must: ads-dsWorkingDirectory
 m-oid: 1.3.6.1.4.1.18060.0.4.1.3.100
 entrycsn: 20100111202217.860000Z#000000#000#000000
 m-description: The DirectoryService ObjectClass
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapEncoder.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapEncoder.java
index e750411..84abbfd 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapEncoder.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapEncoder.java
@@ -31,7 +31,6 @@
 import org.apache.directory.shared.asn1.codec.stateful.EncoderMonitor;
 import org.apache.directory.shared.asn1.codec.stateful.StatefulEncoder;
 import org.apache.directory.shared.i18n.I18n;
-import org.apache.directory.shared.ldap.codec.add.AddRequestCodec;
 import org.apache.directory.shared.ldap.message.spi.Provider;
 import org.apache.directory.shared.ldap.message.spi.ProviderEncoder;
 import org.apache.directory.shared.ldap.message.spi.ProviderException;
@@ -287,47 +286,4 @@
             this.channel = Channels.newChannel( out );
         }
     }
-    
-    
-    private static ByteBuffer encodeAsn1( AddRequestCodec addRequest )
-    {
-        //int length = computeLength( addRequest );
-        return null;
-    }
-    
-    
-    private static ByteBuffer encodeAsn1( LdapMessageCodec message ) throws EncoderException
-    {
-        ByteBuffer buffer = null;
-        
-        switch ( message.getMessageType() )
-        {
-            case ABANDON_REQUEST :
-                return encodeAsn1( message );
-                
-            case ADD_REQUEST :
-            case ADD_RESPONSE :
-            case BIND_REQUEST :
-            case BIND_RESPONSE :
-            case COMPARE_REQUEST :
-            case COMPARE_RESPONSE :
-            case DEL_REQUEST :
-            case DEL_RESPONSE :
-            case EXTENDED_REQUEST :
-            case EXTENDED_RESPONSE :
-            case INTERMEDIATE_RESPONSE :
-            case MODIFY_REQUEST :
-            case MODIFY_RESPONSE :
-            case MODIFYDN_REQUEST :
-            case MODIFYDN_RESPONSE :
-            case SEARCH_REQUEST :
-            case SEARCH_RESULT_DONE :
-            case SEARCH_RESULT_ENTRY :
-            case SEARCH_RESULT_REFERENCE  :
-            case UNBIND_REQUEST :
-            
-        }
-        
-        return buffer;
-    }
 }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapTransformer.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapTransformer.java
index 7b96cfb..d723284 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapTransformer.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapTransformer.java
@@ -59,7 +59,6 @@
 import org.apache.directory.shared.ldap.codec.search.SearchResultEntryCodec;
 import org.apache.directory.shared.ldap.codec.search.SearchResultReferenceCodec;
 import org.apache.directory.shared.ldap.codec.search.SubstringFilter;
-import org.apache.directory.shared.ldap.codec.unbind.UnBindRequestCodec;
 import org.apache.directory.shared.ldap.codec.util.LdapURLEncodingException;
 import org.apache.directory.shared.ldap.entry.EntryAttribute;
 import org.apache.directory.shared.ldap.entry.Modification;
@@ -783,11 +782,10 @@
      * Transform an UnBindRequest message from a CodecMessage to a
      * InternalMessage
      * 
-     * @param codecMessage The message to transform
      * @param messageId The message Id
      * @return A Internal UnBindRequestImpl
      */
-    private static InternalMessage transformUnBindRequest( LdapMessageCodec codecMessage, int messageId )
+    private static InternalMessage transformUnBindRequest( int messageId )
     {
         return new UnbindRequestImpl( messageId );
     }
@@ -821,7 +819,7 @@
                 break;
 
             case UNBIND_REQUEST :
-                internalMessage = transformUnBindRequest( (UnBindRequestCodec)codecMessage, messageId );
+                internalMessage = transformUnBindRequest( messageId );
                 break;
 
             case SEARCH_REQUEST :
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/modify/ModifyRequestCodec.java b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/modify/ModifyRequestCodec.java
index 6b38b8a..ea3c484 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/codec/modify/ModifyRequestCodec.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/codec/modify/ModifyRequestCodec.java
@@ -34,14 +34,12 @@
 import org.apache.directory.shared.ldap.codec.LdapConstants;
 import org.apache.directory.shared.ldap.codec.LdapMessageCodec;
 import org.apache.directory.shared.ldap.codec.MessageTypeEnum;
-import org.apache.directory.shared.ldap.entry.DefaultModification;
 import org.apache.directory.shared.ldap.entry.DefaultEntryAttribute;
+import org.apache.directory.shared.ldap.entry.DefaultModification;
 import org.apache.directory.shared.ldap.entry.EntryAttribute;
 import org.apache.directory.shared.ldap.entry.Modification;
 import org.apache.directory.shared.ldap.entry.ModificationOperation;
 import org.apache.directory.shared.ldap.name.DN;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 
 /**
@@ -73,12 +71,6 @@
  */
 public class ModifyRequestCodec extends LdapMessageCodec
 {
-    // ~ Static fields/initializers
-    // -----------------------------------------------------------------
-
-    /** The logger */
-    private static final Logger LOG = LoggerFactory.getLogger( ModifyRequestCodec.class );
-
     // ~ Instance fields
     // ----------------------------------------------------------------------------
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/AndNode.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/AndNode.java
index 3c5c185..0f4efb2 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/AndNode.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/AndNode.java
@@ -53,15 +53,6 @@
 
     
     /**
-     * Clone the AndNode
-     */
-    @Override public ExprNode clone()
-    {
-        return super.clone();
-    }
-
-
-    /**
      * Creates an empty AndNode
      */
     public AndNode()
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/ApproximateNode.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/ApproximateNode.java
index 3f7c368..42ae989 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/ApproximateNode.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/ApproximateNode.java
@@ -42,15 +42,6 @@
 
     
     /**
-     * Return a cloned node
-     */
-    @Override public ExprNode clone()
-    {
-        return super.clone();
-    }
-    
-    
-    /**
      * @see Object#toString()
      * @return A string representing the AndNode
      */
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/EqualityNode.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/EqualityNode.java
index ef9f534..eaa7d75 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/EqualityNode.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/EqualityNode.java
@@ -43,17 +43,6 @@
     }
 
     /**
-     * Makes a full clone in new memory space of the current node and children
-     * 
-     * @return the clone
-     */
-    @Override public ExprNode clone()
-    {
-        return super.clone();
-    }
-
-
-    /**
      * Creates a new Equality object.
      * 
      * @param attribute the attribute name
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParser.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParser.java
index 17229b3..52fda96 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParser.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParser.java
@@ -83,7 +83,7 @@
                     pos.start++;
 
                     // Get the assertionValue
-                    node.setValue( parseAssertionValue( filter, pos, true ) );
+                    node.setValue( parseAssertionValue( filter, pos ) );
 
                     return node;
                 }
@@ -98,7 +98,7 @@
                         pos.start += 2;
 
                         // Get the assertionValue
-                        node.setValue( parseAssertionValue( filter, pos, true ) );
+                        node.setValue( parseAssertionValue( filter, pos ) );
 
                         return node;
                     }
@@ -145,7 +145,7 @@
                     pos.start++;
 
                     // Get the assertionValue
-                    node.setValue( parseAssertionValue( filter, pos, true ) );
+                    node.setValue( parseAssertionValue( filter, pos ) );
 
                     return node;
                 }
@@ -160,7 +160,7 @@
                         pos.start += 2;
 
                         // Get the assertionValue
-                        node.setValue( parseAssertionValue( filter, pos, true ) );
+                        node.setValue( parseAssertionValue( filter, pos ) );
 
                         return node;
                     }
@@ -211,9 +211,8 @@
      * HEX            = '0'-'9' / 'A'-'F' / 'a'-'f'
      * unicodeSubset     = %x01-27 / %x2B-5B / %x5D-FFFF
      */
-    private static Value<?> parseAssertionValue( String filter, Position pos, boolean preserveEscapedChars ) throws ParseException
+    private static Value<?> parseAssertionValue( String filter, Position pos ) throws ParseException
     {
-        int start = pos.start;
         char c = StringTools.charAt( filter, pos.start );
         
         // Create a buffer big enough to contain the value once converted
@@ -275,12 +274,6 @@
     }
 
 
-    private static Value<?> parseAssertionValue( String filter, Position pos ) throws ParseException
-    {
-        return parseAssertionValue( filter, pos, false );
-    }
-
-
     /**
      * Parse a substring
      */
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/GreaterEqNode.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/GreaterEqNode.java
index 39bd07e..3963d23 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/GreaterEqNode.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/GreaterEqNode.java
@@ -43,16 +43,6 @@
     }
 
     /**
-     * Makes a full clone in new memory space of the current node and children
-     * 
-     * @return the clone
-     */
-    @Override public ExprNode clone()
-    {
-        return super.clone();
-    }
-
-    /**
      * @see Object#toString()
      * @return A string representing the AndNode
      */
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/LeafNode.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/LeafNode.java
index 842eda7..447ab8c 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/LeafNode.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/LeafNode.java
@@ -45,17 +45,6 @@
     }
     
     /**
-     * Makes a full clone in new memory space of the current node and children
-     * 
-     * @return the clone
-     */
-    @Override public ExprNode clone()
-    {
-        return super.clone();
-    }
-    
-
-    /**
      * Gets whether this node is a leaf - the answer is always true here.
      * 
      * @return true always
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/LessEqNode.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/LessEqNode.java
index 59c8b88..91e1641 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/LessEqNode.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/LessEqNode.java
@@ -43,16 +43,6 @@
     }
 
     /**
-     * Makes a full clone in new memory space of the current node and children
-     * 
-     * @return the clone
-     */
-    @Override public ExprNode clone()
-    {
-        return super.clone();
-    }
-
-    /**
      * @see Object#toString()
      * @return A string representing the AndNode
      */
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/NotNode.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/NotNode.java
index 69bcc41..69eba0b 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/NotNode.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/NotNode.java
@@ -68,16 +68,6 @@
 
     
     /**
-     * Clone the Node
-     */
-    @Override public ExprNode clone()
-    {
-        return super.clone();
-    }
-    
-
-
-    /**
      * Creates an empty NotNode
      */
     public NotNode()
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/OrNode.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/OrNode.java
index 3a73783..3f3abc0 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/OrNode.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/OrNode.java
@@ -54,15 +54,6 @@
 
     
     /**
-     * Clone the Node
-     */
-    @Override public ExprNode clone()
-    {
-        return super.clone();
-    }
-
-
-    /**
      * Creates an empty OrNode
      */
     public OrNode()
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/PresenceNode.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/PresenceNode.java
index 3e00761..4ef599b 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/PresenceNode.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/PresenceNode.java
@@ -41,14 +41,6 @@
 
     
     /**
-     * Clone the Node
-     */
-    @Override public ExprNode clone()
-    {
-        return super.clone();
-    }
-
-    /**
      * @see java.lang.Object#toString()
      * @return A string representing the AndNode
      */
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/ScopeNode.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/ScopeNode.java
index 118f756..2ab1367 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/ScopeNode.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/ScopeNode.java
@@ -59,17 +59,6 @@
     }
 
     /**
-     * Makes a full clone in new memory space of the current node and children
-     * 
-     * @return the clone
-     */
-    @Override public ExprNode clone()
-    {
-        return super.clone();
-    }    
-
-
-    /**
      * Always returns true since a scope node has no children.
      * 
      * @see ExprNode#isLeaf()
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/SimpleNode.java b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/SimpleNode.java
index f8aefa7..227a953 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/filter/SimpleNode.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/filter/SimpleNode.java
@@ -60,7 +60,7 @@
 
     
     /**
-     * Clone the Node
+     * Makes a full clone in new memory space of the current node and children
      */
     @Override public ExprNode clone()
     {
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/AbstractAbandonableRequest.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/AbstractAbandonableRequest.java
index a13f14a..37de551 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/AbstractAbandonableRequest.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/AbstractAbandonableRequest.java
@@ -99,9 +99,12 @@
         } );
     }
 
-    
+
+    // False positive
+    @SuppressWarnings("PMD.UselessOverridingMethod")
     class RequestObservable extends Observable
     {
+        @Override
         public void setChanged()
         {
             super.setChanged();
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/BindResponseImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/BindResponseImpl.java
index 784393f..59f7cc2 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/BindResponseImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/BindResponseImpl.java
@@ -51,7 +51,7 @@
      * @param id
      *            the session unique message id
      */
-    public BindResponseImpl(final int id)
+    public BindResponseImpl( final int id )
     {
         super( id, TYPE );
     }
@@ -75,7 +75,7 @@
             return null;
         }
 
-        final byte[] copy = new byte[ serverSaslCreds.length ];
+        final byte[] copy = new byte[serverSaslCreds.length];
         System.arraycopy( serverSaslCreds, 0, copy, 0, serverSaslCreds.length );
         return copy;
     }
@@ -93,9 +93,11 @@
     {
         if ( serverSaslCreds != null )
         {
-            this.serverSaslCreds = new byte[ serverSaslCreds.length ];
+            this.serverSaslCreds = new byte[serverSaslCreds.length];
             System.arraycopy( serverSaslCreds, 0, this.serverSaslCreds, 0, serverSaslCreds.length );
-        } else {
+        }
+        else
+        {
             this.serverSaslCreds = null;
         }
     }
@@ -132,7 +134,7 @@
 
         InternalBindResponse response = ( InternalBindResponse ) obj;
         byte[] creds = response.getServerSaslCreds();
-        
+
         if ( serverSaslCreds == null )
         {
             if ( creds != null )
@@ -144,7 +146,7 @@
         {
             return false;
         }
-        
+
         return Arrays.equals( serverSaslCreds, creds );
     }
 
@@ -162,7 +164,8 @@
 
         if ( serverSaslCreds != null )
         {
-            sb.append( "        Server sasl credentials : '" ).append( StringTools.dumpBytes( serverSaslCreds ) ).append( "'\n" );
+            sb.append( "        Server sasl credentials : '" ).append( StringTools.dumpBytes( serverSaslCreds ) )
+                .append( "'\n" );
         }
 
         return sb.toString();
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/CompareRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/CompareRequestImpl.java
index c2d0e5b..6055f5e 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/CompareRequestImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/CompareRequestImpl.java
@@ -197,6 +197,36 @@
 
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( name != null )
+        {
+            hash = hash * 17 + name.hashCode();
+        }
+        if ( attrId != null )
+        {
+            hash = hash * 17 + attrId.hashCode();
+        }
+        if ( attrVal != null )
+        {
+            hash = hash * 17 + attrVal.hashCode();
+        }
+        Value<?> reqVal = getAssertionValue();
+        if ( reqVal != null )
+        {
+            hash = hash * 17 + reqVal.hashCode();
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
      * Checks to see if an object is equivalent to this CompareRequest.
      * 
      * @param obj the obj to compare with this CompareRequest
@@ -282,7 +312,7 @@
         sb.append( "        Entry : '" ).append( name.toString() ).append( "'\n" );
         sb.append( "        Attribute description : '" ).append( attrId ).append( "'\n" );
         sb.append( "        Attribute value : '" );
-        
+
         if ( !attrVal.isBinary() )
         {
             sb.append( attrVal.get() );
@@ -290,8 +320,8 @@
         else
         {
             byte[] binVal = attrVal.getBytes();
-            sb.append( StringTools.utf8ToString( binVal ) ).append( '/' ).append(
-                StringTools.dumpBytes( binVal ) ).append( "'\n" );
+            sb.append( StringTools.utf8ToString( binVal ) ).append( '/' ).append( StringTools.dumpBytes( binVal ) )
+                .append( "'\n" );
         }
 
         return sb.toString();
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/DeleteRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/DeleteRequestImpl.java
index 4ec28c0..7354266 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/DeleteRequestImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/DeleteRequestImpl.java
@@ -19,6 +19,7 @@
  */
 package org.apache.directory.shared.ldap.message;
 
+
 import org.apache.directory.shared.ldap.codec.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.internal.InternalDeleteRequest;
 import org.apache.directory.shared.ldap.message.internal.InternalDeleteResponse;
@@ -53,7 +54,7 @@
      * @param id
      *            the sequential message identifier
      */
-    public DeleteRequestImpl(final int id)
+    public DeleteRequestImpl( final int id )
     {
         super( id, TYPE );
     }
@@ -121,6 +122,23 @@
 
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( name != null )
+        {
+            hash = hash * 17 + name.hashCode();
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
      * Checks to see if an object is equivalent to this DeleteRequest. First
      * there's a quick test to see if the obj is the same object as this one -
      * if so true is returned. Next if the super method fails false is returned.
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/ExtendedRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/ExtendedRequestImpl.java
index 11dcf23..092c9de 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/ExtendedRequestImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/ExtendedRequestImpl.java
@@ -62,7 +62,7 @@
      * @param id
      *            the sequential message identifier
      */
-    public ExtendedRequestImpl(final int id)
+    public ExtendedRequestImpl( final int id )
     {
         super( id, TYPE, true );
     }
@@ -110,7 +110,7 @@
             return null;
         }
 
-        final byte[] copy = new byte[ payload.length ];
+        final byte[] copy = new byte[payload.length];
         System.arraycopy( payload, 0, copy, 0, payload.length );
         return copy;
     }
@@ -126,9 +126,11 @@
     {
         if ( payload != null )
         {
-            this.payload = new byte[ payload.length ];
+            this.payload = new byte[payload.length];
             System.arraycopy( payload, 0, this.payload, 0, payload.length );
-        } else {
+        }
+        else
+        {
             this.payload = null;
         }
     }
@@ -167,6 +169,27 @@
 
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( oid != null )
+        {
+            hash = hash * 17 + oid.hashCode();
+        }
+        if ( payload != null )
+        {
+            hash = hash * 17 + Arrays.hashCode( payload );
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
      * Checks to see if an object equals this ExtendedRequest.
      * 
      * @param obj
@@ -184,14 +207,14 @@
         {
             return false;
         }
-        
+
         if ( !( obj instanceof InternalExtendedRequest ) )
         {
             return false;
         }
 
         InternalExtendedRequest req = ( InternalExtendedRequest ) obj;
-        
+
         if ( ( oid != null ) && ( req.getOid() == null ) )
         {
             return false;
@@ -202,7 +225,7 @@
             return false;
         }
 
-        if ( ( oid != null ) && ( req.getOid() != null ) &&  !oid.equals( req.getOid() ) )
+        if ( ( oid != null ) && ( req.getOid() != null ) && !oid.equals( req.getOid() ) )
         {
             return false;
         }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/ExtendedResponseImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/ExtendedResponseImpl.java
index 13ceb07..1979d8c 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/ExtendedResponseImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/ExtendedResponseImpl.java
@@ -25,6 +25,7 @@
 import org.apache.directory.shared.ldap.message.internal.InternalAbstractResultResponse;
 import org.apache.directory.shared.ldap.message.internal.InternalExtendedResponse;
 
+
 /**
  * Lockable ExtendedResponse implementation
  * 
@@ -81,7 +82,7 @@
             return null;
         }
 
-        final byte[] copy = new byte[ value.length ];
+        final byte[] copy = new byte[value.length];
         System.arraycopy( value, 0, copy, 0, value.length );
         return copy;
     }
@@ -97,14 +98,16 @@
     {
         if ( value != null )
         {
-            this.value = new byte[ value.length ];
+            this.value = new byte[value.length];
             System.arraycopy( value, 0, this.value, 0, value.length );
-        } else {
+        }
+        else
+        {
             this.value = null;
         }
     }
-    
-    
+
+
     public void setOid( String oid )
     {
         this.oid = oid;
@@ -137,6 +140,27 @@
 
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( oid != null )
+        {
+            hash = hash * 17 + oid.hashCode();
+        }
+        if ( value != null )
+        {
+            hash = hash * 17 + Arrays.hashCode( value );
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
      * Checks to see if an object equals this ExtendedRequest.
      * 
      * @param obj
@@ -154,7 +178,7 @@
         {
             return false;
         }
-        
+
         if ( !( obj instanceof InternalExtendedResponse ) )
         {
             return false;
@@ -172,12 +196,9 @@
             return false;
         }
 
-        if ( oid != null && resp.getResponseName() != null )
+        if ( oid != null && resp.getResponseName() != null && !oid.equals( resp.getResponseName() ) )
         {
-            if ( !oid.equals( resp.getResponseName() ) )
-            {
-                return false;
-            }
+            return false;
         }
 
         if ( value != null && resp.getResponse() == null )
@@ -190,12 +211,9 @@
             return false;
         }
 
-        if ( value != null && resp.getResponse() != null )
+        if ( value != null && resp.getResponse() != null && !Arrays.equals( value, resp.getResponse() ) )
         {
-            if ( !Arrays.equals( value, resp.getResponse() ) )
-            {
-                return false;
-            }
+            return false;
         }
 
         return true;
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/IntermediateResponseImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/IntermediateResponseImpl.java
index 966bd4d..d646558 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/IntermediateResponseImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/IntermediateResponseImpl.java
@@ -25,6 +25,7 @@
 import org.apache.directory.shared.ldap.message.internal.InternalAbstractResultResponse;
 import org.apache.directory.shared.ldap.message.internal.InternalIntermediateResponse;
 
+
 /**
  * IntermediateResponse implementation
  * 
@@ -67,7 +68,7 @@
             return null;
         }
 
-        final byte[] copy = new byte[ value.length ];
+        final byte[] copy = new byte[value.length];
         System.arraycopy( value, 0, copy, 0, value.length );
         return copy;
     }
@@ -82,14 +83,16 @@
     {
         if ( value != null )
         {
-            this.value = new byte[ value.length ];
+            this.value = new byte[value.length];
             System.arraycopy( value, 0, this.value, 0, value.length );
-        } else {
+        }
+        else
+        {
             this.value = null;
         }
     }
-    
-    
+
+
     /**
      * Gets the OID uniquely identifying this Intemediate response (a.k.a. its
      * name).
@@ -115,6 +118,27 @@
 
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( oid != null )
+        {
+            hash = hash * 17 + oid.hashCode();
+        }
+        if ( value != null )
+        {
+            hash = hash * 17 + Arrays.hashCode( value );
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
      * Checks to see if an object equals this IntemediateResponse.
      * 
      * @param obj the object to be checked for equality
@@ -131,7 +155,7 @@
         {
             return false;
         }
-        
+
         if ( !( obj instanceof InternalIntermediateResponse ) )
         {
             return false;
@@ -149,12 +173,9 @@
             return false;
         }
 
-        if ( ( oid != null ) && ( resp.getResponseName() != null ) )
+        if ( ( oid != null ) && ( resp.getResponseName() != null ) && !oid.equals( resp.getResponseName() ) )
         {
-            if ( !oid.equals( resp.getResponseName() ) )
-            {
-                return false;
-            }
+            return false;
         }
 
         if ( ( value != null ) && ( resp.getResponseValue() == null ) )
@@ -167,12 +188,10 @@
             return false;
         }
 
-        if ( ( value != null ) && ( resp.getResponseValue() != null ) )
+        if ( ( value != null ) && ( resp.getResponseValue() != null )
+            && !Arrays.equals( value, resp.getResponseValue() ) )
         {
-            if ( !Arrays.equals( value, resp.getResponseValue() ) )
-            {
-                return false;
-            }
+            return false;
         }
 
         return true;
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/LdapResultImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/LdapResultImpl.java
index efb54a2..36ca34d 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/LdapResultImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/LdapResultImpl.java
@@ -20,6 +20,7 @@
 
 package org.apache.directory.shared.ldap.message;
 
+
 import org.apache.directory.shared.ldap.message.internal.InternalLdapResult;
 import org.apache.directory.shared.ldap.message.internal.InternalReferral;
 import org.apache.directory.shared.ldap.name.DN;
@@ -176,6 +177,31 @@
 
 
     /**
+     * @see Object#hashCode()
+     * @return the instance's hash code 
+     */
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( referral != null )
+        {
+            hash = hash * 17 + referral.hashCode();
+        }
+        hash = hash * 17 + resultCode.hashCode();
+        if ( errorMessage != null )
+        {
+            hash = hash * 17 + errorMessage.hashCode();
+        }
+        if ( matchedDn != null )
+        {
+            hash = hash * 17 + matchedDn.hashCode();
+        }
+
+        return hash;
+    }
+
+
+    /**
      * @param obj The object to compare with
      * @return <code>true</code> if both objects are equals
      */
@@ -206,12 +232,9 @@
             return false;
         }
 
-        if ( referral != null && result.getReferral() != null )
+        if ( referral != null && result.getReferral() != null && !referral.equals( result.getReferral() ) )
         {
-            if ( !referral.equals( result.getReferral() ) )
-            {
-                return false;
-            }
+            return false;
         }
 
         if ( !resultCode.equals( result.getResultCode() ) )
@@ -270,241 +293,241 @@
         switch ( resultCode )
         {
 
-            case SUCCESS :
+            case SUCCESS:
                 sb.append( " success\n" );
                 break;
 
-            case OPERATIONS_ERROR :
+            case OPERATIONS_ERROR:
                 sb.append( " operationsError\n" );
                 break;
 
-            case PROTOCOL_ERROR :
+            case PROTOCOL_ERROR:
                 sb.append( " protocolError\n" );
                 break;
 
-            case TIME_LIMIT_EXCEEDED :
+            case TIME_LIMIT_EXCEEDED:
                 sb.append( " timeLimitExceeded\n" );
                 break;
 
-            case SIZE_LIMIT_EXCEEDED :
+            case SIZE_LIMIT_EXCEEDED:
                 sb.append( " sizeLimitExceeded\n" );
                 break;
 
-            case COMPARE_FALSE :
+            case COMPARE_FALSE:
                 sb.append( " compareFalse\n" );
                 break;
 
-            case COMPARE_TRUE :
+            case COMPARE_TRUE:
                 sb.append( " compareTrue\n" );
                 break;
 
-            case AUTH_METHOD_NOT_SUPPORTED :
+            case AUTH_METHOD_NOT_SUPPORTED:
                 sb.append( " authMethodNotSupported\n" );
                 break;
 
-            case STRONG_AUTH_REQUIRED :
+            case STRONG_AUTH_REQUIRED:
                 sb.append( " strongAuthRequired\n" );
                 break;
 
-            case REFERRAL :
+            case REFERRAL:
                 sb.append( " referral -- new\n" );
                 break;
 
-            case ADMIN_LIMIT_EXCEEDED :
+            case ADMIN_LIMIT_EXCEEDED:
                 sb.append( " adminLimitExceeded -- new\n" );
                 break;
 
-            case UNAVAILABLE_CRITICAL_EXTENSION :
+            case UNAVAILABLE_CRITICAL_EXTENSION:
                 sb.append( " unavailableCriticalExtension -- new\n" );
                 break;
 
-            case CONFIDENTIALITY_REQUIRED :
+            case CONFIDENTIALITY_REQUIRED:
                 sb.append( " confidentialityRequired -- new\n" );
                 break;
 
-            case SASL_BIND_IN_PROGRESS :
+            case SASL_BIND_IN_PROGRESS:
                 sb.append( " saslBindInProgress -- new\n" );
                 break;
 
-            case NO_SUCH_ATTRIBUTE :
+            case NO_SUCH_ATTRIBUTE:
                 sb.append( " noSuchAttribute\n" );
                 break;
 
-            case UNDEFINED_ATTRIBUTE_TYPE :
+            case UNDEFINED_ATTRIBUTE_TYPE:
                 sb.append( " undefinedAttributeType\n" );
                 break;
 
-            case INAPPROPRIATE_MATCHING :
+            case INAPPROPRIATE_MATCHING:
                 sb.append( " inappropriateMatching\n" );
                 break;
 
-            case CONSTRAINT_VIOLATION :
+            case CONSTRAINT_VIOLATION:
                 sb.append( " constraintViolation\n" );
                 break;
 
-            case ATTRIBUTE_OR_VALUE_EXISTS :
+            case ATTRIBUTE_OR_VALUE_EXISTS:
                 sb.append( " attributeOrValueExists\n" );
                 break;
 
-            case INVALID_ATTRIBUTE_SYNTAX :
+            case INVALID_ATTRIBUTE_SYNTAX:
                 sb.append( " invalidAttributeSyntax\n" );
                 break;
 
-            case NO_SUCH_OBJECT :
+            case NO_SUCH_OBJECT:
                 sb.append( " noSuchObject\n" );
                 break;
 
-            case ALIAS_PROBLEM :
+            case ALIAS_PROBLEM:
                 sb.append( " aliasProblem\n" );
                 break;
 
-            case INVALID_DN_SYNTAX :
+            case INVALID_DN_SYNTAX:
                 sb.append( " invalidDNSyntax\n" );
                 break;
 
-            case ALIAS_DEREFERENCING_PROBLEM :
+            case ALIAS_DEREFERENCING_PROBLEM:
                 sb.append( " aliasDereferencingProblem\n" );
                 break;
 
-            case INAPPROPRIATE_AUTHENTICATION :
+            case INAPPROPRIATE_AUTHENTICATION:
                 sb.append( " inappropriateAuthentication\n" );
                 break;
 
-            case INVALID_CREDENTIALS :
+            case INVALID_CREDENTIALS:
                 sb.append( " invalidCredentials\n" );
                 break;
 
-            case INSUFFICIENT_ACCESS_RIGHTS :
+            case INSUFFICIENT_ACCESS_RIGHTS:
                 sb.append( " insufficientAccessRights\n" );
                 break;
 
-            case BUSY :
+            case BUSY:
                 sb.append( " busy\n" );
                 break;
 
-            case UNAVAILABLE :
+            case UNAVAILABLE:
                 sb.append( " unavailable\n" );
                 break;
 
-            case UNWILLING_TO_PERFORM :
+            case UNWILLING_TO_PERFORM:
                 sb.append( " unwillingToPerform\n" );
                 break;
 
-            case LOOP_DETECT :
+            case LOOP_DETECT:
                 sb.append( " loopDetect\n" );
                 break;
 
-            case NAMING_VIOLATION :
+            case NAMING_VIOLATION:
                 sb.append( " namingViolation\n" );
                 break;
 
-            case OBJECT_CLASS_VIOLATION :
+            case OBJECT_CLASS_VIOLATION:
                 sb.append( " objectClassViolation\n" );
                 break;
 
-            case NOT_ALLOWED_ON_NON_LEAF :
+            case NOT_ALLOWED_ON_NON_LEAF:
                 sb.append( " notAllowedOnNonLeaf\n" );
                 break;
 
-            case NOT_ALLOWED_ON_RDN :
+            case NOT_ALLOWED_ON_RDN:
                 sb.append( " notAllowedOnRDN\n" );
                 break;
 
-            case ENTRY_ALREADY_EXISTS :
+            case ENTRY_ALREADY_EXISTS:
                 sb.append( " entryAlreadyExists\n" );
                 break;
 
-            case OBJECT_CLASS_MODS_PROHIBITED :
+            case OBJECT_CLASS_MODS_PROHIBITED:
                 sb.append( " objectClassModsProhibited\n" );
                 break;
 
-            case AFFECTS_MULTIPLE_DSAS :
+            case AFFECTS_MULTIPLE_DSAS:
                 sb.append( " affectsMultipleDSAs -- new\n" );
                 break;
 
-            case OTHER :
+            case OTHER:
                 sb.append( " other\n" );
                 break;
-                
-            default :
+
+            default:
                 switch ( resultCode.getResultCode() )
                 {
-                    case 9 :
+                    case 9:
                         sb.append( " -- 9 reserved --\n" );
                         break;
-                        
-                    case 22 :
+
+                    case 22:
                     case 23:
-                    case 24 :
-                    case 25 :
-                    case 26 :
-                    case 27 :
-                    case 28 :
-                    case 29 :
-                    case 30 :
-                    case 31 :
+                    case 24:
+                    case 25:
+                    case 26:
+                    case 27:
+                    case 28:
+                    case 29:
+                    case 30:
+                    case 31:
                         sb.append( " -- 22-31 unused --\n" );
                         break;
 
-                    case 35 :
+                    case 35:
                         sb.append( " -- 35 reserved for undefined isLeaf --\n" );
                         break;
-                                
-                    case 37 :
-                    case 38 :
-                    case 39 :
-                    case 40 :
-                    case 41 :
-                    case 42 :
-                    case 43 :
-                    case 44 :
-                    case 45 :
-                    case 46 :
-                    case 47 :
+
+                    case 37:
+                    case 38:
+                    case 39:
+                    case 40:
+                    case 41:
+                    case 42:
+                    case 43:
+                    case 44:
+                    case 45:
+                    case 46:
+                    case 47:
                         sb.append( " -- 37-47 unused --\n" );
                         break;
 
-                    case 55 :
-                    case 56 :
-                    case 57 :
-                    case 58 :
-                    case 59 :
-                    case 60 :
-                    case 61 :
-                    case 62 :
-                    case 63 :
+                    case 55:
+                    case 56:
+                    case 57:
+                    case 58:
+                    case 59:
+                    case 60:
+                    case 61:
+                    case 62:
+                    case 63:
                         sb.append( " -- 55-63 unused --\n" );
                         break;
 
-                    case 70 :
+                    case 70:
                         sb.append( " -- 70 reserved for CLDAP --\n" );
                         break;
 
-                    case 72 :
-                    case 73 :
-                    case 74 :
-                    case 75 :
-                    case 76 :
-                    case 77 :
-                    case 78 :
-                    case 79 :
+                    case 72:
+                    case 73:
+                    case 74:
+                    case 75:
+                    case 76:
+                    case 77:
+                    case 78:
+                    case 79:
                         sb.append( " -- 72-79 unused --\n" );
                         break;
 
-                    case 81 :
-                    case 82 :
-                    case 83 :
-                    case 84 :
-                    case 85 :
-                    case 86 :
-                    case 87 :
-                    case 88 :
-                    case 89 :
-                    case 90 :
+                    case 81:
+                    case 82:
+                    case 83:
+                    case 84:
+                    case 85:
+                    case 86:
+                    case 87:
+                    case 88:
+                    case 89:
+                    case 90:
                         sb.append( " -- 81-90 reserved for APIs --" );
                         break;
-                        
-                    default :
+
+                    default:
                         sb.append( "Unknown error code : " ).append( resultCode );
                         break;
                 }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyDnRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyDnRequestImpl.java
index 7b6c78f..b525724 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyDnRequestImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyDnRequestImpl.java
@@ -19,6 +19,7 @@
  */
 package org.apache.directory.shared.ldap.message;
 
+
 import org.apache.directory.shared.ldap.codec.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.internal.InternalModifyDnRequest;
 import org.apache.directory.shared.ldap.message.internal.InternalModifyDnResponse;
@@ -63,7 +64,7 @@
      * @param id
      *            the seq id of this message
      */
-    public ModifyDnRequestImpl(final int id)
+    public ModifyDnRequestImpl( final int id )
     {
         super( id, TYPE );
     }
@@ -232,6 +233,33 @@
 
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( name != null )
+        {
+            hash = hash * 17 + name.hashCode();
+        }
+        hash = hash * 17 + ( deleteOldRdn ? 0 : 1 );
+
+        if ( newRdn != null )
+        {
+            hash = hash * 17 + newRdn.hashCode();
+        }
+        if ( newSuperior != null )
+        {
+            hash = hash * 17 + newSuperior.hashCode();
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
      * Checks to see of an object equals this ModifyDnRequest stub. The equality
      * presumes all ModifyDnRequest specific properties are the same.
      * 
@@ -263,12 +291,9 @@
             return false;
         }
 
-        if ( name != null && req.getName() != null )
+        if ( name != null && req.getName() != null && !name.equals( req.getName() ) )
         {
-            if ( !name.equals( req.getName() ) )
-            {
-                return false;
-            }
+            return false;
         }
 
         if ( deleteOldRdn != req.getDeleteOldRdn() )
@@ -286,12 +311,9 @@
             return false;
         }
 
-        if ( newRdn != null && req.getNewRdn() != null )
+        if ( newRdn != null && req.getNewRdn() != null && !newRdn.equals( req.getNewRdn() ) )
         {
-            if ( !newRdn.equals( req.getNewRdn() ) )
-            {
-                return false;
-            }
+            return false;
         }
 
         if ( newSuperior != null && req.getNewSuperior() == null )
@@ -304,12 +326,9 @@
             return false;
         }
 
-        if ( newSuperior != null && req.getNewSuperior() != null )
+        if ( newSuperior != null && req.getNewSuperior() != null && !newSuperior.equals( req.getNewSuperior() ) )
         {
-            if ( !newSuperior.equals( req.getNewSuperior() ) )
-            {
-                return false;
-            }
+            return false;
         }
 
         return true;
@@ -328,7 +347,7 @@
 
         sb.append( "    ModifyDN Response\n" );
         sb.append( "        Entry : '" ).append( name ).append( "'\n" );
-        if( newRdn != null )
+        if ( newRdn != null )
         {
             sb.append( "        New RDN : '" ).append( newRdn.toString() ).append( "'\n" );
         }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyRequestImpl.java
index 3a039ca..738b65e 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyRequestImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyRequestImpl.java
@@ -21,6 +21,7 @@
 
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
@@ -33,8 +34,6 @@
 import org.apache.directory.shared.ldap.message.internal.InternalModifyResponse;
 import org.apache.directory.shared.ldap.message.internal.InternalResultResponse;
 import org.apache.directory.shared.ldap.name.DN;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 
 /**
@@ -47,9 +46,6 @@
 {
     static final long serialVersionUID = -505803669028990304L;
 
-    /** The logger */
-    private static final transient Logger LOG = LoggerFactory.getLogger( ModifyRequestImpl.class );
-
     /** Dn of the entry to modify or PDU's <b>object</b> field */
     private DN name;
 
@@ -70,7 +66,7 @@
      * @param id
      *            the sequential message identifier
      */
-    public ModifyRequestImpl(final int id)
+    public ModifyRequestImpl( final int id )
     {
         super( id, TYPE );
     }
@@ -173,6 +169,28 @@
 
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( name != null )
+        {
+            hash = hash * 17 + name.hashCode();
+        }
+        hash = hash * 17 + mods.size();
+        for ( int i = 0; i < mods.size(); i++ )
+        {
+            hash = hash * 17 + ( ( DefaultModification ) mods.get( i ) ).hashCode();
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
      * Checks to see if ModifyRequest stub equals another by factoring in checks
      * for the name and modification items of the request.
      * 
@@ -204,12 +222,9 @@
             return false;
         }
 
-        if ( name != null && req.getName() != null )
+        if ( name != null && req.getName() != null && !name.equals( req.getName() ) )
         {
-            if ( !name.equals( req.getName() ) )
-            {
-                return false;
-            }
+            return false;
         }
 
         if ( req.getModificationItems().size() != mods.size() )
@@ -231,8 +246,8 @@
                 }
             }
             else
-                
-            if ( !item.equals((DefaultModification) mods.get( i ) ) )
+
+            if ( !item.equals( ( DefaultModification ) mods.get( i ) ) )
             {
                 return false;
             }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/ReferralImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/ReferralImpl.java
index 1a7058a..ff79f39 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/ReferralImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/ReferralImpl.java
@@ -19,6 +19,7 @@
  */
 package org.apache.directory.shared.ldap.message;
 
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -28,7 +29,6 @@
 import org.apache.directory.shared.ldap.message.internal.InternalReferral;
 
 
-
 /**
  * A Referral implementation. For the time being this implementation uses a
  * String representation for LDAPURLs. In the future an LdapUrl interface with
@@ -85,6 +85,25 @@
 
 
     /**
+     * @see Object#hashCode()
+     * @return the instance's hash code 
+     */
+    public int hashCode()
+    {
+        int hash = 37;
+        hash = hash * 17 + urls.size();
+
+        // Order doesn't matter, so just add the url hashCode
+        for ( String url : urls )
+        {
+            hash = hash + url.hashCode();
+        }
+
+        return hash;
+    }
+
+
+    /**
      * Compares this Referral implementation to see if it is the same as
      * another. The classes do not have to be the same implementation to return
      * true. Both this and the compared Referral must have the same entries
@@ -113,7 +132,7 @@
             }
 
             Iterator<String> list = urls.iterator();
-            
+
             while ( list.hasNext() )
             {
                 // if one of our urls is not contained in the obj return false
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchRequestImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchRequestImpl.java
index a0f0830..5ef9ab5 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchRequestImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchRequestImpl.java
@@ -85,7 +85,7 @@
      * @param id
      *            the sequential message identifier
      */
-    public SearchRequestImpl(final int id)
+    public SearchRequestImpl( final int id )
     {
         super( id, MessageTypeEnum.SEARCH_REQUEST );
     }
@@ -354,6 +354,41 @@
 
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( baseDn != null )
+        {
+            hash = hash * 17 + baseDn.hashCode();
+        }
+        hash = hash * 17 + aliasDerefMode.hashCode();
+        hash = hash * 17 + scope.hashCode();
+        hash = hash * 17 + Long.valueOf( sizeLimit ).hashCode();
+        hash = hash * 17 + timeLimit;
+        hash = hash * 17 + ( typesOnly ? 0 : 1 );
+        if ( attributes != null )
+        {
+            hash = hash * 17 + attributes.size();
+
+            // Order doesn't matter, thus just add hashCode
+            for ( String attr : attributes )
+            {
+                hash = hash + attr.hashCode();
+            }
+        }
+        BranchNormalizedVisitor visitor = new BranchNormalizedVisitor();
+        filter.accept( visitor );
+        hash = hash * 17 + filter.toString().hashCode();
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
      * Checks to see if two search requests are equal. The Lockable properties
      * and the get/set context specific parameters are not consulted to
      * determine equality. The filter expression tree comparison will normalize
@@ -410,20 +445,14 @@
             return false;
         }
 
-        if ( req.getAttributes() == null && attributes != null )
+        if ( req.getAttributes() == null && attributes != null && attributes.size() > 0 )
         {
-            if ( attributes.size() > 0 )
-            {
-                return false;
-            }
+            return false;
         }
 
-        if ( req.getAttributes() != null && attributes == null )
+        if ( req.getAttributes() != null && attributes == null && req.getAttributes().size() > 0 )
         {
-            if ( req.getAttributes().size() > 0 )
-            {
-                return false;
-            }
+            return false;
         }
 
         if ( req.getAttributes() != null && attributes != null )
@@ -434,7 +463,7 @@
             }
 
             Iterator<String> list = attributes.iterator();
-            
+
             while ( list.hasNext() )
             {
                 if ( !req.getAttributes().contains( list.next() ) )
@@ -454,25 +483,26 @@
         return myFilterString.equals( reqFilterString );
     }
 
+
     /**
      * Return a string the represent a SearchRequest
      */
     public String toString()
     {
-        StringBuilder    sb = new StringBuilder();
+        StringBuilder sb = new StringBuilder();
 
         sb.append( "    SearchRequest\n" );
         sb.append( "        baseDn : '" ).append( baseDn ).append( "'\n" );
-        
+
         if ( filter != null )
         {
             sb.append( "        filter : '" );
             sb.append( filter.toString() );
             sb.append( "'\n" );
         }
-        
+
         sb.append( "        scope : " );
-        
+
         switch ( scope )
         {
             case OBJECT:
@@ -487,9 +517,9 @@
                 sb.append( "whole subtree" );
                 break;
         }
-        
+
         sb.append( '\n' );
-        
+
         sb.append( "        typesOnly : " ).append( typesOnly ).append( '\n' );
 
         sb.append( "        Size Limit : " );
@@ -542,12 +572,12 @@
         sb.append( '\n' );
         sb.append( "        attributes : " );
 
-        boolean         isFirst = true;
+        boolean isFirst = true;
 
         if ( attributes != null )
         {
             Iterator<String> it = attributes.iterator();
-            
+
             while ( it.hasNext() )
             {
                 if ( isFirst )
@@ -558,10 +588,10 @@
                 {
                     sb.append( ", " );
                 }
-                
+
                 sb.append( '\'' ).append( it.next() ).append( '\'' );
             }
-            
+
         }
 
         sb.append( '\n' );
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseDoneImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseDoneImpl.java
index fcae1db..09da28d 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseDoneImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseDoneImpl.java
@@ -19,6 +19,7 @@
  */
 package org.apache.directory.shared.ldap.message;
 
+
 import org.apache.directory.shared.ldap.message.internal.InternalAbstractResultResponse;
 import org.apache.directory.shared.ldap.message.internal.InternalLdapResult;
 import org.apache.directory.shared.ldap.message.internal.InternalSearchResponseDone;
@@ -47,13 +48,27 @@
      * @param id
      *            the session unique message id
      */
-    public SearchResponseDoneImpl(final int id)
+    public SearchResponseDoneImpl( final int id )
     {
         super( id, TYPE );
     }
 
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        hash = hash * 17 + getLdapResult().hashCode();
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
      * Checks for equality by using the underlying LdapResult objects of this
      * SearchResponseDone stub.
      * 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseEntryImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseEntryImpl.java
index 2a3c66f..2f629ed 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseEntryImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseEntryImpl.java
@@ -109,6 +109,23 @@
 
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( entry != null )
+        {
+            hash = hash * 17 + entry.hashCode();
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
      * Checks for equality by comparing the objectName, and attributes
      * properties of this Message after delegating to the super.equals() method.
      * 
@@ -132,7 +149,7 @@
         {
             return false;
         }
-        
+
         InternalSearchResponseEntry resp = ( InternalSearchResponseEntry ) obj;
 
         return entry.equals( resp.getEntry() );
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseReferenceImpl.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseReferenceImpl.java
index 11b2f7a..8a60ac6 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseReferenceImpl.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/SearchResponseReferenceImpl.java
@@ -19,6 +19,7 @@
  */
 package org.apache.directory.shared.ldap.message;
 
+
 import org.apache.directory.shared.ldap.message.internal.InternalAbstractResponse;
 import org.apache.directory.shared.ldap.message.internal.InternalReferral;
 import org.apache.directory.shared.ldap.message.internal.InternalSearchResponseReference;
@@ -49,7 +50,7 @@
      * @param id
      *            the session unique message id
      */
-    public SearchResponseReferenceImpl(final int id)
+    public SearchResponseReferenceImpl( final int id )
     {
         super( id, TYPE );
     }
@@ -83,6 +84,23 @@
 
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = 37;
+        if ( this.referral != null )
+        {
+            hash = hash * 17 + this.referral.hashCode();
+        }
+        hash = hash * 17 + super.hashCode();
+
+        return hash;
+    }
+
+
+    /**
      * Checks to see if an object is equal to this SearchResponseReference stub.
      * 
      * @param obj
@@ -113,12 +131,9 @@
             return false;
         }
 
-        if ( this.referral != null && resp.getReferral() != null )
+        if ( this.referral != null && resp.getReferral() != null && !this.referral.equals( resp.getReferral() ) )
         {
-            if ( !this.referral.equals( resp.getReferral() ) )
-            {
-                return false;
-            }
+            return false;
         }
 
         return true;
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CancelRequest.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CancelRequest.java
index 5b49642..b749145 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CancelRequest.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CancelRequest.java
@@ -61,6 +61,7 @@
     /** The requestName for this extended request */
     public static final String EXTENSION_OID = "1.3.6.1.1.8";
 
+
     /**
      * 
      * Creates a new instance of CancelRequest.
@@ -72,11 +73,11 @@
     {
         super( messageId );
         setOid( EXTENSION_OID );
-        
+
         this.cancelId = cancelId;
     }
 
-    
+
     /**
      * Encode the request
      */
@@ -87,7 +88,8 @@
 
         payload = cancel.encode().array();
     }
-    
+
+
     /**
      * Gets the extended request's <b>requestValue</b> portion of the PDU. The
      * form of the data is request specific and is determined by the extended
@@ -109,7 +111,7 @@
                 throw new RuntimeException( e );
             }
         }
-        
+
         return super.getPayload();
     }
 
@@ -119,19 +121,21 @@
      * 
      * @param payload byte array of data encapsulating ext. req. parameters
      */
-    public void setPayload( byte[] payload ) 
+    public void setPayload( byte[] payload )
     {
         CancelDecoder decoder = new CancelDecoder();
-        
+
         try
         {
             Cancel cancel = ( Cancel ) decoder.decode( payload );
 
             if ( payload != null )
             {
-                this.payload = new byte[ payload.length ];
+                this.payload = new byte[payload.length];
                 System.arraycopy( payload, 0, this.payload, 0, payload.length );
-            } else {
+            }
+            else
+            {
                 this.payload = null;
             }
             this.cancelId = cancel.getCancelId();
@@ -167,4 +171,3 @@
         return response;
     }
 }
-
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CancelResponse.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CancelResponse.java
index c5d2306..0fd2e8a 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CancelResponse.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CancelResponse.java
@@ -19,10 +19,13 @@
  */
 package org.apache.directory.shared.ldap.message.extended;
 
+
 import org.apache.directory.shared.i18n.I18n;
 import org.apache.directory.shared.ldap.message.ExtendedResponseImpl;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.util.StringTools;
+
+
 /**
  * 
  * The response sent back from the server after the Cancel extended operation is performed.
@@ -35,6 +38,7 @@
     /** The serial version UUID */
     private static final long serialVersionUID = 1L;
 
+
     /**
      * Create a new CancelResponse object
      * @param messageId The messageId
@@ -46,18 +50,18 @@
 
         switch ( rcode )
         {
-            case SUCCESS :
+            case SUCCESS:
             case CANCELED:
-            case CANNOT_CANCEL :
-            case NO_SUCH_OPERATION :
-            case TOO_LATE :
+            case CANNOT_CANCEL:
+            case NO_SUCH_OPERATION:
+            case TOO_LATE:
                 break;
-            
+
             default:
                 throw new IllegalArgumentException( I18n.err( I18n.ERR_04166, ResultCodeEnum.SUCCESS,
-                		ResultCodeEnum.OPERATIONS_ERROR, ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS ) );
+                    ResultCodeEnum.OPERATIONS_ERROR, ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS ) );
         }
-        
+
         super.getLdapResult().setMatchedDn( null );
         super.getLdapResult().setResultCode( rcode );
     }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationRequest.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationRequest.java
index bb275ac..a7cc9fd 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationRequest.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationRequest.java
@@ -53,6 +53,7 @@
 
     public static final String EXTENSION_OID = "1.3.6.1.4.1.18060.0.1.8";
 
+
     /**
      * 
      * Creates a new instance of CertGenerationRequest.
@@ -67,7 +68,7 @@
     {
         super( messageId );
         setOid( EXTENSION_OID );
-        
+
         this.certGenObj = new CertGenerationObject();
         certGenObj.setTargetDN( targerDN );
         certGenObj.setIssuerDN( issuerDN );
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationResponse.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationResponse.java
index cc30a58..cee90c0 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationResponse.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/CertGenerationResponse.java
@@ -19,10 +19,13 @@
  */
 package org.apache.directory.shared.ldap.message.extended;
 
+
 import org.apache.directory.shared.i18n.I18n;
 import org.apache.directory.shared.ldap.message.ExtendedResponseImpl;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.util.StringTools;
+
+
 /**
  * 
  * The response sent back from the server after the CertGeneration extended operation is performed.
@@ -34,32 +37,33 @@
 {
     /** The serial version UUID */
     private static final long serialVersionUID = 1L;
-    
+
     /** The CertGenerationResponse OID */
     public static final String EXTENSION_OID = "1.3.6.1.4.1.18060.0.1.9";
 
-    public CertGenerationResponse(int messageId, ResultCodeEnum rcode)
+
+    public CertGenerationResponse( int messageId, ResultCodeEnum rcode )
     {
         super( messageId, EXTENSION_OID );
 
         switch ( rcode )
         {
-            case SUCCESS :
-            case OPERATIONS_ERROR :
-            case INSUFFICIENT_ACCESS_RIGHTS :
+            case SUCCESS:
+            case OPERATIONS_ERROR:
+            case INSUFFICIENT_ACCESS_RIGHTS:
                 break;
-            
+
             default:
                 throw new IllegalArgumentException( I18n.err( I18n.ERR_04166, ResultCodeEnum.SUCCESS,
-                		ResultCodeEnum.OPERATIONS_ERROR, ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS ) );
+                    ResultCodeEnum.OPERATIONS_ERROR, ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS ) );
         }
-        
+
         super.getLdapResult().setMatchedDn( null );
         super.getLdapResult().setResultCode( rcode );
     }
 
 
-    public CertGenerationResponse(int messageId)
+    public CertGenerationResponse( int messageId )
     {
         super( messageId, EXTENSION_OID );
         super.getLdapResult().setMatchedDn( null );
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulDisconnect.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulDisconnect.java
index 3e6c272..e0e3cd9 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulDisconnect.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulDisconnect.java
@@ -68,21 +68,23 @@
     private InternalReferral replicatedContexts = new ReferralImpl();
 
 
-    public GracefulDisconnect(byte[] value) throws DecoderException
+    public GracefulDisconnect( byte[] value ) throws DecoderException
     {
         super( 0, EXTENSION_OID );
         if ( value != null )
         {
-            this.value = new byte[ value.length ];
+            this.value = new byte[value.length];
             System.arraycopy( value, 0, this.value, 0, value.length );
-        } else {
+        }
+        else
+        {
             this.value = null;
         }
         decodeValue();
     }
 
 
-    public GracefulDisconnect(int timeOffline, int delay)
+    public GracefulDisconnect( int timeOffline, int delay )
     {
         super( 0, EXTENSION_OID );
         super.oid = EXTENSION_OID;
@@ -114,7 +116,7 @@
             this.delay = codec.getDelay();
             super.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS );
             List<LdapURL> contexts = codec.getReplicatedContexts();
-            
+
             for ( int ii = 0; ii < contexts.size(); ii++ )
             {
                 replicatedContexts.addLdapUrl( contexts.get( ii ).toString() );
@@ -134,7 +136,7 @@
         codec.setTimeOffline( this.timeOffline );
         codec.setDelay( this.delay );
         Iterator<String> contexts = this.replicatedContexts.getLdapUrls().iterator();
-        
+
         while ( contexts.hasNext() )
         {
             String urlstr = ( String ) contexts.next();
@@ -179,7 +181,7 @@
             encodeResponse();
         }
 
-        final byte[] copy = new byte[ value.length ];
+        final byte[] copy = new byte[value.length];
         System.arraycopy( value, 0, copy, 0, value.length );
         return copy;
     }
@@ -210,7 +212,7 @@
         this.delay = codec.getDelay();
         this.timeOffline = codec.getTimeOffline();
         List<LdapURL> contexts = codec.getReplicatedContexts();
-        
+
         for ( int ii = 0; ii < contexts.size(); ii++ )
         {
             LdapURL url = contexts.get( ii );
@@ -219,9 +221,11 @@
 
         if ( value != null )
         {
-            this.value = new byte[ value.length ];
+            this.value = new byte[value.length];
             System.arraycopy( value, 0, this.value, 0, value.length );
-        } else {
+        }
+        else
+        {
             this.value = null;
         }
     }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulShutdownRequest.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulShutdownRequest.java
index f85e889..1cde889 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulShutdownRequest.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulShutdownRequest.java
@@ -65,13 +65,13 @@
     private int delay;
 
 
-    public GracefulShutdownRequest(int messageId)
+    public GracefulShutdownRequest( int messageId )
     {
         this( messageId, UNDETERMINED, NOW );
     }
 
 
-    public GracefulShutdownRequest(int messageId, int timeOffline, int delay)
+    public GracefulShutdownRequest( int messageId, int timeOffline, int delay )
     {
         super( messageId );
         setOid( EXTENSION_OID );
@@ -97,9 +97,11 @@
             GracefulShutdown gs = ( GracefulShutdown ) decoder.decode( payload );
             if ( payload != null )
             {
-                this.payload = new byte[ payload.length ];
+                this.payload = new byte[payload.length];
                 System.arraycopy( payload, 0, this.payload, 0, payload.length );
-            } else {
+            }
+            else
+            {
                 this.payload = null;
             }
             this.timeOffline = gs.getTimeOffline();
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulShutdownResponse.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulShutdownResponse.java
index c3b5ae2..a398434 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulShutdownResponse.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/GracefulShutdownResponse.java
@@ -42,32 +42,32 @@
     private static final byte[] EMPTY_RESPONSE = new byte[0];
 
 
-    public GracefulShutdownResponse(int messageId, ResultCodeEnum rcode)
+    public GracefulShutdownResponse( int messageId, ResultCodeEnum rcode )
     {
         super( messageId, EXTENSION_OID );
 
         switch ( rcode )
         {
-            case SUCCESS :
+            case SUCCESS:
                 break;
-            
-            case OPERATIONS_ERROR :
+
+            case OPERATIONS_ERROR:
                 break;
-            
-            case INSUFFICIENT_ACCESS_RIGHTS :
+
+            case INSUFFICIENT_ACCESS_RIGHTS:
                 break;
-            
+
             default:
                 throw new IllegalArgumentException( I18n.err( I18n.ERR_04166, ResultCodeEnum.SUCCESS,
-                		ResultCodeEnum.OPERATIONS_ERROR, ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS ) );
+                    ResultCodeEnum.OPERATIONS_ERROR, ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS ) );
         }
-        
+
         super.getLdapResult().setMatchedDn( null );
         super.getLdapResult().setResultCode( rcode );
     }
 
 
-    public GracefulShutdownResponse(int messageId)
+    public GracefulShutdownResponse( int messageId )
     {
         super( messageId, EXTENSION_OID );
         super.getLdapResult().setMatchedDn( null );
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/LaunchDiagnosticUiRequest.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/LaunchDiagnosticUiRequest.java
index 4120b2f..df8684e 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/LaunchDiagnosticUiRequest.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/LaunchDiagnosticUiRequest.java
@@ -43,7 +43,7 @@
     private static final byte[] EMPTY_PAYLOAD = new byte[0];
 
 
-    public LaunchDiagnosticUiRequest(int messageId)
+    public LaunchDiagnosticUiRequest( int messageId )
     {
         super( messageId );
         setOid( EXTENSION_OID );
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/LaunchDiagnosticUiResponse.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/LaunchDiagnosticUiResponse.java
index 1b45b0d..8412417 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/LaunchDiagnosticUiResponse.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/LaunchDiagnosticUiResponse.java
@@ -41,35 +41,35 @@
     private static final byte[] EMPTY_RESPONSE = new byte[0];
 
 
-    public LaunchDiagnosticUiResponse(int messageId, ResultCodeEnum rcode)
+    public LaunchDiagnosticUiResponse( int messageId, ResultCodeEnum rcode )
     {
         super( messageId, EXTENSION_OID );
 
         switch ( rcode )
         {
-            case SUCCESS :
+            case SUCCESS:
                 break;
-            
-            case OPERATIONS_ERROR :
+
+            case OPERATIONS_ERROR:
                 break;
-            
-            case INSUFFICIENT_ACCESS_RIGHTS :
+
+            case INSUFFICIENT_ACCESS_RIGHTS:
                 break;
-            
+
             default:
                 throw new IllegalArgumentException( I18n.err( I18n.ERR_04166, ResultCodeEnum.SUCCESS,
                     ResultCodeEnum.OPERATIONS_ERROR, ResultCodeEnum.INSUFFICIENT_ACCESS_RIGHTS ) );
         }
-        
+
         super.getLdapResult().setMatchedDn( null );
         super.getLdapResult().setResultCode( rcode );
     }
 
 
-    public LaunchDiagnosticUiResponse(int messageId)
+    public LaunchDiagnosticUiResponse( int messageId )
     {
         super( messageId, EXTENSION_OID );
-        super.getLdapResult().setMatchedDn( null);
+        super.getLdapResult().setMatchedDn( null );
         super.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS );
     }
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/NoticeOfDisconnect.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/NoticeOfDisconnect.java
index becce11..86f00e5 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/NoticeOfDisconnect.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/NoticeOfDisconnect.java
@@ -114,7 +114,8 @@
 
     public static final NoticeOfDisconnect PROTOCOLERROR = new NoticeOfDisconnect( ResultCodeEnum.PROTOCOL_ERROR );
 
-    public static final NoticeOfDisconnect STRONGAUTHREQUIRED = new NoticeOfDisconnect( ResultCodeEnum.STRONG_AUTH_REQUIRED );
+    public static final NoticeOfDisconnect STRONGAUTHREQUIRED = new NoticeOfDisconnect(
+        ResultCodeEnum.STRONG_AUTH_REQUIRED );
 
 
     private NoticeOfDisconnect( ResultCodeEnum rcode )
@@ -123,20 +124,20 @@
 
         switch ( rcode )
         {
-            case UNAVAILABLE :
+            case UNAVAILABLE:
                 break;
-                
-            case PROTOCOL_ERROR :
+
+            case PROTOCOL_ERROR:
                 break;
-                
-            case STRONG_AUTH_REQUIRED :
+
+            case STRONG_AUTH_REQUIRED:
                 break;
-                
+
             default:
                 throw new IllegalArgumentException( I18n.err( I18n.ERR_04166, ResultCodeEnum.UNAVAILABLE,
                     ResultCodeEnum.PROTOCOL_ERROR, ResultCodeEnum.STRONG_AUTH_REQUIRED ) );
         }
-        
+
         super.getLdapResult().setErrorMessage( rcode.toString() + ": The server will disconnect!" );
         super.getLdapResult().setMatchedDn( null );
         super.getLdapResult().setResultCode( rcode );
@@ -147,7 +148,6 @@
     // ExtendedResponse Interface Method Implementations
     // ------------------------------------------------------------------------
 
-    
     /**
      * Gets the reponse OID specific encoded response values.
      * 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/StoredProcedureRequest.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/StoredProcedureRequest.java
index 8d91a50..a28e529 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/StoredProcedureRequest.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/extended/StoredProcedureRequest.java
@@ -19,6 +19,7 @@
  */
 package org.apache.directory.shared.ldap.message.extended;
 
+
 import java.nio.ByteBuffer;
 
 import javax.naming.NamingException;
@@ -52,7 +53,7 @@
 
     private StoredProcedure procedure;
 
-    
+
     public StoredProcedureRequest( int messageId )
     {
         super( messageId );
@@ -81,7 +82,7 @@
     {
         StoredProcedureDecoder decoder = new StoredProcedureDecoder();
         StoredProcedureContainer container = new StoredProcedureContainer();
-        
+
         try
         {
             decoder.decode( ByteBuffer.wrap( payload ), container );
@@ -147,71 +148,70 @@
     // Parameters of the Extended Request Payload
     // -----------------------------------------------------------------------
 
-
     public String getLanguage()
     {
         return procedure.getLanguage();
     }
-    
-    
+
+
     public void setLanguage( String language )
     {
         this.procedure.setLanguage( language );
     }
 
-    
+
     public void setProcedure( String procedure )
     {
         this.procedure.setProcedure( StringTools.getBytesUtf8( procedure ) );
     }
 
-    
+
     public String getProcedureSpecification()
     {
         return StringTools.utf8ToString( procedure.getProcedure() );
     }
-    
-    
+
+
     public int size()
     {
         return this.procedure.getParameters().size();
     }
-    
-    
+
+
     public Object getParameterType( int index )
     {
-        if ( ! this.procedure.getLanguage().equals( "java" ) )
+        if ( !this.procedure.getLanguage().equals( "java" ) )
         {
             return procedure.getParameters().get( index ).getType();
         }
 
         return getJavaParameterType( index );
     }
-    
-    
+
+
     public Class<?> getJavaParameterType( int index )
     {
         throw new NotImplementedException( I18n.err( I18n.ERR_04175 ) );
     }
-    
-    
+
+
     public Object getParameterValue( int index )
     {
-        if ( ! this.procedure.getLanguage().equals( "java" ) )
+        if ( !this.procedure.getLanguage().equals( "java" ) )
         {
             return procedure.getParameters().get( index ).getValue();
         }
 
         return getJavaParameterValue( index );
     }
-    
-    
+
+
     public Object getJavaParameterValue( int index )
     {
         throw new NotImplementedException( I18n.err( I18n.ERR_04176 ) );
     }
-    
-    
+
+
     public void addParameter( Object type, Object value )
     {
         /**
@@ -230,14 +230,14 @@
          * Replacing this code with the one below without the conditional check.
          
          */
-        
+
         StoredProcedureParameter parameter = new StoredProcedureParameter();
         parameter.setType( ( byte[] ) type );
         parameter.setValue( ( byte[] ) value );
         this.procedure.addParameter( parameter );
 
         // below here try to convert parameters to their appropriate byte[] representations
-        
+
         /**
          * FIXME: What is this for?
          * 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/internal/InternalAbstractRequest.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/internal/InternalAbstractRequest.java
index 176a2a7..24625fa 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/internal/InternalAbstractRequest.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/internal/InternalAbstractRequest.java
@@ -19,6 +19,7 @@
  */
 package org.apache.directory.shared.ldap.message.internal;
 
+
 import org.apache.directory.shared.ldap.codec.MessageTypeEnum;
 
 
@@ -46,7 +47,7 @@
      * @param hasResponse
      *            flag indicating if this request generates a response
      */
-    protected InternalAbstractRequest(final int id, final MessageTypeEnum type, boolean hasResponse)
+    protected InternalAbstractRequest( final int id, final MessageTypeEnum type, boolean hasResponse )
     {
         super( id, type );
 
@@ -64,7 +65,8 @@
     {
         return hasResponse;
     }
-    
+
+
     /**
      * @see Object#hashCode()
      * @return the instance's hash code 
@@ -72,9 +74,9 @@
     public int hashCode()
     {
         int hash = 37;
-        hash = hash*17 + (hasResponse ? 0 : 1 );
-        hash = hash*17 + super.hashCode();
-        
+        hash = hash * 17 + ( hasResponse ? 0 : 1 );
+        hash = hash * 17 + super.hashCode();
+
         return hash;
     }
 }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/message/internal/InternalAbstractResultResponse.java b/ldap/src/main/java/org/apache/directory/shared/ldap/message/internal/InternalAbstractResultResponse.java
index 218b15a..f7f79ba 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/message/internal/InternalAbstractResultResponse.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/message/internal/InternalAbstractResultResponse.java
@@ -19,6 +19,7 @@
  */
 package org.apache.directory.shared.ldap.message.internal;
 
+
 import org.apache.directory.shared.ldap.codec.MessageTypeEnum;
 import org.apache.directory.shared.ldap.message.LdapResultImpl;
 
@@ -48,7 +49,7 @@
      * @param type
      *            the message type of the response
      */
-    protected InternalAbstractResultResponse(final int id, final MessageTypeEnum type)
+    protected InternalAbstractResultResponse( final int id, final MessageTypeEnum type )
     {
         super( id, type );
     }
@@ -110,12 +111,9 @@
             return false;
         }
 
-        if ( getLdapResult() != null && resp.getLdapResult() != null )
+        if ( getLdapResult() != null && resp.getLdapResult() != null && !getLdapResult().equals( resp.getLdapResult() ) )
         {
-            if ( !getLdapResult().equals( resp.getLdapResult() ) )
-            {
-                return false;
-            }
+            return false;
         }
 
         return true;
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/name/AVASerializer.java b/ldap/src/main/java/org/apache/directory/shared/ldap/name/AVASerializer.java
index 0c22e69..85ba8d2 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/name/AVASerializer.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/name/AVASerializer.java
@@ -153,8 +153,8 @@
     public static AVA deserialize( ObjectInput in ) throws IOException
     {
         String upName = in.readUTF();
-        int start = in.readInt();
-        int length = in.readInt();
+        in.readInt(); // start
+        in.readInt(); // length
         String upType = in.readUTF();
         String normType = in.readUTF();
         
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/name/RDN.java b/ldap/src/main/java/org/apache/directory/shared/ldap/name/RDN.java
index 4d878ac..74752b3 100755
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/name/RDN.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/name/RDN.java
@@ -35,7 +35,6 @@
 import org.apache.directory.shared.i18n.I18n;
 import org.apache.directory.shared.ldap.entry.StringValue;
 import org.apache.directory.shared.ldap.entry.Value;
-import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
 import org.apache.directory.shared.ldap.schema.normalizers.OidNormalizer;
 import org.apache.directory.shared.ldap.util.StringTools;
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/AttributeType.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/AttributeType.java
index e11d7d4..c9b4530 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/AttributeType.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/AttributeType.java
@@ -529,7 +529,7 @@
     /**
      * Check the constraints for the Usage field.
      */
-    private void checkUsage( List<Throwable> errors, Registries registries )
+    private void checkUsage( List<Throwable> errors )
     {
         // Check that the AT usage is the same that its superior
         if ( ( superior != null ) && ( usage != superior.getUsage() ) )
@@ -559,15 +559,12 @@
     /**
      * Check the constraints for the Collective field.
      */
-    private void checkCollective( List<Throwable> errors, Registries registries )
+    private void checkCollective( List<Throwable> errors )
     {
-        if ( superior != null )
+        if ( superior != null && superior.isCollective() )
         {
-            if ( superior.isCollective() )
-            {
-                // An AttributeType will be collective if its superior is collective
-                this.isCollective = true;
-            }
+            // An AttributeType will be collective if its superior is collective
+            this.isCollective = true;
         }
 
         if ( isCollective() && ( usage != UsageEnum.USER_APPLICATIONS ) )
@@ -618,10 +615,10 @@
             buildSubstring( errors, registries );
 
             // Check the USAGE
-            checkUsage( errors, registries );
+            checkUsage( errors );
 
             // Check the COLLECTIVE element
-            checkCollective( errors, registries );
+            checkCollective( errors );
 
             // Inject the attributeType into the oid/normalizer map
             attributeTypeRegistry.addMappingFor( this );
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/DITContentRule.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/DITContentRule.java
index d7fd75c..5b7f104 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/DITContentRule.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/DITContentRule.java
@@ -207,13 +207,10 @@
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
         }
         
-        if ( !isReadOnly )
+        if ( !isReadOnly && !auxObjectClassOids.contains( objectClass.getOid() ) )
         {
-            if ( !auxObjectClassOids.contains( objectClass.getOid() ) )
-            {
-                auxObjectClasses.add( objectClass );
-                auxObjectClassOids.add( objectClass.getOid() );
-            }
+            auxObjectClasses.add( objectClass );
+            auxObjectClassOids.add( objectClass.getOid() );
         }
     }
 
@@ -309,13 +306,10 @@
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
         }
         
-        if ( !isReadOnly )
+        if ( !isReadOnly && !mayAttributeTypeOids.contains( attributeType.getOid() ) )
         {
-            if ( !mayAttributeTypeOids.contains( attributeType.getOid() ) )
-            {
-                mayAttributeTypes.add( attributeType );
-                mayAttributeTypeOids.add( attributeType.getOid() );
-            }
+            mayAttributeTypes.add( attributeType );
+            mayAttributeTypeOids.add( attributeType.getOid() );
         }
     }
 
@@ -413,13 +407,10 @@
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
         }
         
-        if ( !isReadOnly )
+        if ( !isReadOnly && !mustAttributeTypeOids.contains( attributeType.getOid() ) )
         {
-            if ( !mustAttributeTypeOids.contains( attributeType.getOid() ) )
-            {
-                mustAttributeTypes.add( attributeType );
-                mustAttributeTypeOids.add( attributeType.getOid() );
-            }
+            mustAttributeTypes.add( attributeType );
+            mustAttributeTypeOids.add( attributeType.getOid() );
         }
     }
 
@@ -517,13 +508,10 @@
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
         }
         
-        if ( !isReadOnly )
+        if ( !isReadOnly && !notAttributeTypeOids.contains( attributeType.getOid() ) )
         {
-            if ( !notAttributeTypeOids.contains( attributeType.getOid() ) )
-            {
-                notAttributeTypes.add( attributeType );
-                notAttributeTypeOids.add( attributeType.getOid() );
-            }
+            notAttributeTypes.add( attributeType );
+            notAttributeTypeOids.add( attributeType.getOid() );
         }
     }
 
@@ -708,6 +696,7 @@
     /**
      * @see Object#equals(Object)
      */
+    @SuppressWarnings("PMD.UnusedLocalVariable") // Remove me when the TODO is fixed 
     public boolean equals( Object o )
     {
         if ( !super.equals( o ) )
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/DITStructureRule.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/DITStructureRule.java
index 07b6ad4..ff5f24f 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/DITStructureRule.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/DITStructureRule.java
@@ -254,6 +254,7 @@
     /**
      * @see Object#equals(Object)
      */
+    @SuppressWarnings("PMD.UnusedLocalVariable") // Remove me when the TODO is fixed 
     public boolean equals( Object o )
     {
         if ( !super.equals( o ) )
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/LdapSyntax.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/LdapSyntax.java
index 0bf5f4b..98420b7 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/LdapSyntax.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/LdapSyntax.java
@@ -247,6 +247,7 @@
      * @param registries The Registries
      * @exception If the Syntx is not valid 
      */
+    @SuppressWarnings("PMD.CollapsibleIfStatements") // Used because of comments
     public void removeFromRegistries( List<Throwable> errors, Registries registries ) throws LdapException
     {
         if ( registries != null )
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/MatchingRuleUse.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/MatchingRuleUse.java
index 821c958..dd4ed9c 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/MatchingRuleUse.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/MatchingRuleUse.java
@@ -217,12 +217,9 @@
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
         }
         
-        if ( !isReadOnly )
+        if ( !isReadOnly && !applicableAttributeOids.contains( oid ) )
         {
-            if ( !applicableAttributeOids.contains( oid ) )
-            {
-                applicableAttributeOids.add( oid );
-            }
+            applicableAttributeOids.add( oid );
         }
     }
 
@@ -239,13 +236,10 @@
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
         }
         
-        if ( !isReadOnly )
+        if ( !isReadOnly && !applicableAttributeOids.contains( attributeType.getOid() ) )
         {
-            if ( !applicableAttributeOids.contains( attributeType.getOid() ) )
-            {
-                applicableAttributes.add( attributeType );
-                applicableAttributeOids.add( attributeType.getOid() );
-            }
+            applicableAttributes.add( attributeType );
+            applicableAttributeOids.add( attributeType.getOid() );
         }
     }
 
@@ -288,6 +282,7 @@
     /**
      * @see Object#equals(Object)
      */
+    @SuppressWarnings("PMD.UnusedLocalVariable") // Remove me when the TODO is fixed 
     public boolean equals( Object o )
     {
         if ( !super.equals( o ) )
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/NameForm.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/NameForm.java
index 9ec3754..23833b4 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/NameForm.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/NameForm.java
@@ -342,13 +342,10 @@
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
         }
         
-        if ( !isReadOnly )
+        if ( !isReadOnly && !mustAttributeTypeOids.contains( attributeType.getOid() ) )
         {
-            if ( !mustAttributeTypeOids.contains( attributeType.getOid() ) )
-            {
-                mustAttributeTypes.add( attributeType );
-                mustAttributeTypeOids.add( attributeType.getOid() );
-            }
+            mustAttributeTypes.add( attributeType );
+            mustAttributeTypeOids.add( attributeType.getOid() );
         }
     }
 
@@ -457,13 +454,10 @@
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
         }
         
-        if ( !isReadOnly )
+        if ( !isReadOnly && !mayAttributeTypeOids.contains( attributeType.getOid() ) )
         {
-            if ( !mayAttributeTypeOids.contains( attributeType.getOid() ) )
-            {
-                mayAttributeTypes.add( attributeType );
-                mayAttributeTypeOids.add( attributeType.getOid() );
-            }
+            mayAttributeTypes.add( attributeType );
+            mayAttributeTypeOids.add( attributeType.getOid() );
         }
     }
 
@@ -522,6 +516,7 @@
     /**
      * @see Object#equals(Object)
      */
+    @SuppressWarnings("PMD.UnusedLocalVariable") // Remove me when the TODO is fixed 
     public boolean equals( Object o )
     {
         if ( !super.equals( o ) )
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SchemaUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SchemaUtils.java
index 8f06e77..cc40004 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SchemaUtils.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SchemaUtils.java
@@ -1105,6 +1105,7 @@
     /**
      * NOT FULLY IMPLEMENTED!
      */
+    @SuppressWarnings("PMD.UnusedLocalVariable") // Remove me when the TODO is fixed 
     public static StringBuffer render( DITStructureRule dsr )
     {
         StringBuffer buf = new StringBuffer();
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/comparators/DeepTrimToLowerCachingNormalizingComparator.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/comparators/DeepTrimToLowerCachingNormalizingComparator.java
index b4d3757..98c49a2 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/comparators/DeepTrimToLowerCachingNormalizingComparator.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/comparators/DeepTrimToLowerCachingNormalizingComparator.java
@@ -20,7 +20,6 @@
 package org.apache.directory.shared.ldap.schema.comparators;
 
 
-import org.apache.directory.shared.ldap.schema.SchemaManager;
 import org.apache.directory.shared.ldap.schema.normalizers.CachingNormalizer;
 import org.apache.directory.shared.ldap.schema.normalizers.DeepTrimToLowerNormalizer;
 
@@ -41,15 +40,4 @@
         super( oid, new CachingNormalizer( new DeepTrimToLowerNormalizer( oid ), 10 ), 
             new ComparableComparator( oid ) );
     }
-    
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setSchemaManager( SchemaManager schemaManager )
-    {
-        super.setSchemaManager( schemaManager );
-    }
-    
 }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/comparators/UniqueMemberComparator.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/comparators/UniqueMemberComparator.java
index 6591e56..2028853 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/comparators/UniqueMemberComparator.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/comparators/UniqueMemberComparator.java
@@ -20,15 +20,12 @@
 package org.apache.directory.shared.ldap.schema.comparators;
 
 
+import org.apache.directory.shared.i18n.I18n;
 import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
-
-import org.apache.directory.shared.i18n.I18n;
 import org.apache.directory.shared.ldap.name.DN;
 import org.apache.directory.shared.ldap.schema.LdapComparator;
 import org.apache.directory.shared.ldap.schema.SchemaManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 
 /**
@@ -41,9 +38,6 @@
  */
 public class UniqueMemberComparator extends LdapComparator<String>
 {
-    /** A logger for this class */
-    private static final Logger LOG = LoggerFactory.getLogger( UniqueMemberComparator.class );
-
     /** The serialVersionUID */
     private static final long serialVersionUID = 1L;
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDeepTrimNormalizer.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDeepTrimNormalizer.java
index d3610e7..84c211c 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDeepTrimNormalizer.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDeepTrimNormalizer.java
@@ -20,7 +20,6 @@
 package org.apache.directory.shared.ldap.schema.normalizers;
 
 
-import org.apache.directory.shared.ldap.schema.registries.Registries;
 
 
 /**
@@ -43,13 +42,4 @@
     {
         super( new DeepTrimNormalizer() );
     }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setRegistries( Registries registries )
-    {
-        super.setRegistries( registries );
-    }
 }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDeepTrimToLowerNormalizer.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDeepTrimToLowerNormalizer.java
index d538707..1141976 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDeepTrimToLowerNormalizer.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDeepTrimToLowerNormalizer.java
@@ -20,7 +20,6 @@
 package org.apache.directory.shared.ldap.schema.normalizers;
 
 
-import org.apache.directory.shared.ldap.schema.registries.Registries;
 
 
 /**
@@ -43,13 +42,4 @@
     {
         super( new DeepTrimToLowerNormalizer() );
     }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setRegistries( Registries registries )
-    {
-        super.setRegistries( registries );
-    }
 }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDnNormalizer.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDnNormalizer.java
index 23e0b27..54cad92 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDnNormalizer.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/normalizers/CachingDnNormalizer.java
@@ -21,7 +21,6 @@
 
 
 import org.apache.directory.shared.ldap.schema.SchemaManager;
-import org.apache.directory.shared.ldap.schema.registries.Registries;
 
 
 /**
@@ -49,15 +48,6 @@
     /**
      * {@inheritDoc}
      */
-    public void setRegistries( Registries registries )
-    {
-        super.setRegistries( registries );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
     public void setSchemaManager( SchemaManager schemaManager )
     {
         super.normalizer.setSchemaManager( schemaManager );
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/OpenLdapSchemaParser.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/OpenLdapSchemaParser.java
index a52d21a..ef95e11 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/OpenLdapSchemaParser.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/OpenLdapSchemaParser.java
@@ -31,12 +31,12 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.directory.shared.i18n.I18n;
 import org.apache.directory.shared.ldap.schema.AttributeType;
 import org.apache.directory.shared.ldap.schema.ObjectClass;
 import org.apache.directory.shared.ldap.schema.SchemaObject;
 import org.apache.directory.shared.ldap.schema.syntaxCheckers.OpenLdapObjectIdentifierMacro;
-import org.apache.directory.shared.ldap.util.ExceptionUtils;
 
 import antlr.RecognitionException;
 import antlr.TokenStreamException;
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/ParserDescriptionUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/ParserDescriptionUtils.java
index 8134549..255d06d 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/ParserDescriptionUtils.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/ParserDescriptionUtils.java
@@ -234,12 +234,9 @@
         }
         
         // check that the obsolete flag is equal but not for syntaxes
-        if ( ( so0 instanceof LdapSyntax ) || ( so1 instanceof LdapSyntax ) )
+        if ( ( ( so0 instanceof LdapSyntax ) || ( so1 instanceof LdapSyntax ) ) && so0.isObsolete() != so1.isObsolete() )
         {
-            if ( so0.isObsolete() != so1.isObsolete() )
-            {
-                return false;
-            }
+            return false;
         }
         
         // check that the description matches
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/AbstractSchemaLoader.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/AbstractSchemaLoader.java
index 7a3ff8c..7002c7b 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/AbstractSchemaLoader.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/AbstractSchemaLoader.java
@@ -35,8 +35,6 @@
 import org.apache.directory.shared.ldap.entry.EntryAttribute;
 import org.apache.directory.shared.ldap.entry.Value;
 import org.apache.directory.shared.ldap.util.StringTools;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 
 /**
@@ -47,9 +45,6 @@
  */
 public abstract class AbstractSchemaLoader implements SchemaLoader
 {
-    /** static class logger */
-    private static final Logger LOG = LoggerFactory.getLogger( AbstractSchemaLoader.class );
-
     protected SchemaLoaderListener listener;
 
     /** 
@@ -73,13 +68,10 @@
             listener.schemaLoaded( schema );
         }
 
-        if ( registries instanceof SchemaLoaderListener )
+        if ( registries instanceof SchemaLoaderListener && registries != listener )
         {
-            if ( registries != listener )
-            {
-                SchemaLoaderListener listener = ( SchemaLoaderListener ) registries;
-                listener.schemaLoaded( schema );
-            }
+            SchemaLoaderListener listener = ( SchemaLoaderListener ) registries;
+            listener.schemaLoaded( schema );
         }
     }
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/DefaultAttributeTypeRegistry.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/DefaultAttributeTypeRegistry.java
index 094e07c..08555bb 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/DefaultAttributeTypeRegistry.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/DefaultAttributeTypeRegistry.java
@@ -50,9 +50,6 @@
     /** static class logger */
     private static final Logger LOG = LoggerFactory.getLogger( DefaultAttributeTypeRegistry.class );
 
-    /** Speedup for DEBUG mode */
-    private static final boolean IS_DEBUG = LOG.isDebugEnabled();
-
     /** cached Oid/normalizer mapping */
     private transient Map<String, OidNormalizer> oidNormalizerMap;
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/DefaultObjectClassRegistry.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/DefaultObjectClassRegistry.java
index f9678de..60e9407 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/DefaultObjectClassRegistry.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/DefaultObjectClassRegistry.java
@@ -33,8 +33,6 @@
 import org.apache.directory.shared.ldap.schema.ObjectClass;
 import org.apache.directory.shared.ldap.schema.SchemaObject;
 import org.apache.directory.shared.ldap.schema.SchemaObjectType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 
 /**
@@ -46,12 +44,6 @@
 public class DefaultObjectClassRegistry extends DefaultSchemaObjectRegistry<ObjectClass> 
     implements ObjectClassRegistry
 {
-    /** static class logger */
-    private static final Logger LOG = LoggerFactory.getLogger( DefaultObjectClassRegistry.class );
-
-    /** Speedup for DEBUG mode */
-    private static final boolean IS_DEBUG = LOG.isDebugEnabled();
-
     /** maps OIDs to a Set of descendants for that OID */
     private Map<String,Set<ObjectClass>> oidToDescendants;
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/OidRegistry.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/OidRegistry.java
index 3351032..b33739e 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/OidRegistry.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/OidRegistry.java
@@ -26,11 +26,11 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang.ArrayUtils;
 import org.apache.directory.shared.asn1.primitives.OID;
 import org.apache.directory.shared.i18n.I18n;
 import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.schema.SchemaObject;
-import org.apache.directory.shared.ldap.util.ArrayUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/Registries.java b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/Registries.java
index 542358a..22b9c77 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/Registries.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/schema/registries/Registries.java
@@ -134,6 +134,7 @@
     protected Map<SchemaObjectWrapper, Set<SchemaObjectWrapper>> using;
 
     /** A reference on the schema Manager */
+    @SuppressWarnings("PMD.UnusedPrivateField") // False positive 
     private SchemaManager schemaManager;
 
 
@@ -666,6 +667,8 @@
     /**
      * Build the DitContentRule references
      */
+    // Remove me when TODO is implemented
+    @SuppressWarnings("PMD.UnusedFormalParameter")
     private void buildDitContentRuleReferences( List<Throwable> errors )
     {
         for ( DITContentRule ditContentRule : ditContentRuleRegistry )
@@ -678,6 +681,8 @@
     /**
      * Build the DitStructureRule references
      */
+    // Remove me when TODO is implemented
+    @SuppressWarnings("PMD.UnusedFormalParameter")
     private void buildDitStructureRuleReferences( List<Throwable> errors )
     {
         for ( DITStructureRule ditStructureRule : ditStructureRuleRegistry )
@@ -781,6 +786,8 @@
     /**
      * Build the NameForm references
      */
+    // Remove me when TODO is implemented
+    @SuppressWarnings("PMD.UnusedFormalParameter")
     private void buildNameFormReferences( List<Throwable> errors )
     {
         for ( NameForm nameFormRule : nameFormRegistry )
@@ -1730,6 +1737,8 @@
      * @param schemaObject The SchemaObject we want to deregister
      * @throws LdapException If the removal failed
      */
+    // Remove me when TODO is implemented
+    @SuppressWarnings("PMD.UnusedFormalParameter")
     private SchemaObject unregister( List<Throwable> errors, SchemaObject schemaObject ) throws LdapException
     {
         LOG.debug( "Unregistering {}:{}", schemaObject.getObjectType(), schemaObject.getOid() );
@@ -2601,8 +2610,6 @@
                 }
                 catch ( LdapException ne )
                 {
-                    int i = 0;
-                    i++;
                     // Nothing to do
                 }
             }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ArrayUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/ArrayUtils.java
deleted file mode 100644
index ff9dc0f..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ArrayUtils.java
+++ /dev/null
@@ -1,5355 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.lang.reflect.Array;
-
-import org.apache.commons.lang.builder.HashCodeBuilder;
-import org.apache.directory.shared.i18n.I18n;
-
-
-/**
- * <p>
- * Operations on arrays, primitive arrays (like <code>int[]</code>) and
- * primitive wrapper arrays (like <code>Integer[]</code>).
- * </p>
- * <p>
- * This class tries to handle <code>null</code> input gracefully. An exception
- * will not be thrown for a <code>null</code> array input. However, an Object
- * array that contains a <code>null</code> element may throw an exception.
- * Each method documents its behaviour.
- * </p>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @since 2.0
- */
-public class ArrayUtils
-{
-
-    /**
-     * An empty immutable <code>Object</code> array.
-     */
-    public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
-
-    /**
-     * An empty immutable <code>Class</code> array.
-     */
-    public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
-
-    /**
-     * An empty immutable <code>String</code> array.
-     */
-    public static final String[] EMPTY_STRING_ARRAY = new String[0];
-
-    /**
-     * An empty immutable <code>long</code> array.
-     */
-    public static final long[] EMPTY_LONG_ARRAY = new long[0];
-
-    /**
-     * An empty immutable <code>Long</code> array.
-     */
-    public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0];
-
-    /**
-     * An empty immutable <code>int</code> array.
-     */
-    public static final int[] EMPTY_INT_ARRAY = new int[0];
-
-    /**
-     * An empty immutable <code>Integer</code> array.
-     */
-    public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0];
-
-    /**
-     * An empty immutable <code>short</code> array.
-     */
-    public static final short[] EMPTY_SHORT_ARRAY = new short[0];
-
-    /**
-     * An empty immutable <code>Short</code> array.
-     */
-    public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0];
-
-    /**
-     * An empty immutable <code>byte</code> array.
-     */
-    public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-
-    /**
-     * An empty immutable <code>Byte</code> array.
-     */
-    public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0];
-
-    /**
-     * An empty immutable <code>double</code> array.
-     */
-    public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
-
-    /**
-     * An empty immutable <code>Double</code> array.
-     */
-    public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0];
-
-    /**
-     * An empty immutable <code>float</code> array.
-     */
-    public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
-
-    /**
-     * An empty immutable <code>Float</code> array.
-     */
-    public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0];
-
-    /**
-     * An empty immutable <code>boolean</code> array.
-     */
-    public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
-
-    /**
-     * An empty immutable <code>Boolean</code> array.
-     */
-    public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0];
-
-    /**
-     * An empty immutable <code>char</code> array.
-     */
-    public static final char[] EMPTY_CHAR_ARRAY = new char[0];
-
-    /**
-     * An empty immutable <code>Character</code> array.
-     */
-    public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0];
-
-
-    /**
-     * <p>
-     * ArrayUtils instances should NOT be constructed in standard programming.
-     * Instead, the class should be used as
-     * <code>ArrayUtils.clone(new int[] {2})</code>.
-     * </p>
-     * <p>
-     * This constructor is public to permit tools that require a JavaBean
-     * instance to operate.
-     * </p>
-     */
-    public ArrayUtils()
-    {
-    }
-
-
-    // Basic methods handling multi-dimensional arrays
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Outputs an array as a String, treating <code>null</code> as an empty
-     * array.
-     * </p>
-     * <p>
-     * Multi-dimensional arrays are handled correctly, including
-     * multi-dimensional primitive arrays.
-     * </p>
-     * <p>
-     * The format is that of Java source code, for example <code>{a,b}</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to get a toString for, may be <code>null</code>
-     * @return a String representation of the array, '{}' if null array input
-     */
-    public static String toString( Object array )
-    {
-        return toString( array, "{}" );
-    }
-
-
-    /**
-     * <p>
-     * Outputs an array as a String handling <code>null</code>s.
-     * </p>
-     * <p>
-     * Multi-dimensional arrays are handled correctly, including
-     * multi-dimensional primitive arrays.
-     * </p>
-     * <p>
-     * The format is that of Java source code, for example <code>{a,b}</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to get a toString for, may be <code>null</code>
-     * @param stringIfNull
-     *            the String to return if the array is <code>null</code>
-     * @return a String representation of the array
-     */
-    public static String toString( Object array, String stringIfNull )
-    {
-        if ( array == null )
-        {
-            return stringIfNull;
-        }
-        
-        return new ToStringBuilder( array, ToStringStyle.SIMPLE_STYLE ).append( array ).toString();
-    }
-
-
-    /**
-     * <p>
-     * Get a hashCode for an array handling multi-dimensional arrays correctly.
-     * </p>
-     * <p>
-     * Multi-dimensional primitive arrays are also handled correctly by this
-     * method.
-     * </p>
-     * 
-     * @param array
-     *            the array to get a hashCode for, may be <code>null</code>
-     * @return a hashCode for the array, zero if null array input
-     */
-    public static int hashCode( Object array )
-    {
-        return new HashCodeBuilder().append( array ).toHashCode();
-    }
-
-
-    /**
-     * <p>
-     * Compares two arrays, using equals(), handling multi-dimensional arrays
-     * correctly.
-     * </p>
-     * <p>
-     * Multi-dimensional primitive arrays are also handled correctly by this
-     * method.
-     * </p>
-     * 
-     * @param array1
-     *            the left hand array to compare, may be <code>null</code>
-     * @param array2
-     *            the right hand array to compare, may be <code>null</code>
-     * @return <code>true</code> if the arrays are equal
-     */
-    public static boolean isEquals( Object array1, Object array2 )
-    {
-        return new EqualsBuilder().append( array1, array2 ).isEquals();
-    }
-
-    // Clone
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Shallow clones an array returning a typecast result and handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * The objects in the array are not cloned, thus there is no special
-     * handling for multi-dimensional arrays.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            the array to shallow clone, may be <code>null</code>
-     * @return the cloned array, <code>null</code> if <code>null</code>
-     *         input
-     */
-    public static Object[] clone( Object[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        return array.clone();
-    }
-
-
-    /**
-     * <p>
-     * Clones an array returning a typecast result and handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            the array to clone, may be <code>null</code>
-     * @return the cloned array, <code>null</code> if <code>null</code>
-     *         input
-     */
-    public static long[] clone( long[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        return array.clone();
-    }
-
-
-    /**
-     * <p>
-     * Clones an array returning a typecast result and handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            the array to clone, may be <code>null</code>
-     * @return the cloned array, <code>null</code> if <code>null</code>
-     *         input
-     */
-    public static int[] clone( int[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        return array.clone();
-    }
-
-
-    /**
-     * <p>
-     * Clones an array returning a typecast result and handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            the array to clone, may be <code>null</code>
-     * @return the cloned array, <code>null</code> if <code>null</code>
-     *         input
-     */
-    public static short[] clone( short[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        return array.clone();
-    }
-
-
-    /**
-     * <p>
-     * Clones an array returning a typecast result and handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            the array to clone, may be <code>null</code>
-     * @return the cloned array, <code>null</code> if <code>null</code>
-     *         input
-     */
-    public static char[] clone( char[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        return array.clone();
-    }
-
-
-    /**
-     * <p>
-     * Clones an array returning a typecast result and handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            the array to clone, may be <code>null</code>
-     * @return the cloned array, <code>null</code> if <code>null</code>
-     *         input
-     */
-    public static byte[] clone( byte[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        return array.clone();
-    }
-
-
-    /**
-     * <p>
-     * Clones an array returning a typecast result and handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            the array to clone, may be <code>null</code>
-     * @return the cloned array, <code>null</code> if <code>null</code>
-     *         input
-     */
-    public static double[] clone( double[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        return array.clone();
-    }
-
-
-    /**
-     * <p>
-     * Clones an array returning a typecast result and handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            the array to clone, may be <code>null</code>
-     * @return the cloned array, <code>null</code> if <code>null</code>
-     *         input
-     */
-    public static float[] clone( float[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        return array.clone();
-    }
-
-
-    /**
-     * <p>
-     * Clones an array returning a typecast result and handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            the array to clone, may be <code>null</code>
-     * @return the cloned array, <code>null</code> if <code>null</code>
-     *         input
-     */
-    public static boolean[] clone( boolean[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        return array.clone();
-    }
-
-
-    // Subarrays
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Produces a new array containing the elements between the start and end
-     * indices.
-     * </p>
-     * <p>
-     * The start index is inclusive, the end index exclusive. Null array input
-     * produces null output.
-     * </p>
-     * <p>
-     * The component type of the subarray is always the same as that of the
-     * input array. Thus, if the input is an array of type <code>Date</code>,
-     * the following usage is envisaged:
-     * </p>
-     * 
-     * <pre>
-     * Date[] someDates = ( Date[] ) ArrayUtils.subarray( allDates, 2, 5 );
-     * </pre>
-     * 
-     * @param array
-     *            the array
-     * @param startIndexInclusive
-     *            the starting index. Undervalue (&lt;0) is promoted to 0,
-     *            overvalue (&gt;array.length) results in an empty array.
-     * @param endIndexExclusive
-     *            elements up to endIndex-1 are present in the returned
-     *            subarray. Undervalue (&lt; startIndex) produces empty array,
-     *            overvalue (&gt;array.length) is demoted to array length.
-     * @return a new array containing the elements between the start and end
-     *         indices.
-     */
-    public static Object[] subarray( Object[] array, int startIndexInclusive, int endIndexExclusive )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        if ( startIndexInclusive < 0 )
-        {
-            startIndexInclusive = 0;
-        }
-        if ( endIndexExclusive > array.length )
-        {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        Class<?> type = array.getClass().getComponentType();
-        if ( newSize <= 0 )
-        {
-            return ( Object[] ) Array.newInstance( type, 0 );
-        }
-        Object[] subarray = ( Object[] ) Array.newInstance( type, newSize );
-        System.arraycopy( array, startIndexInclusive, subarray, 0, newSize );
-        return subarray;
-    }
-
-
-    /**
-     * <p>
-     * Produces a new <code>long</code> array containing the elements between
-     * the start and end indices.
-     * </p>
-     * <p>
-     * The start index is inclusive, the end index exclusive. Null array input
-     * produces null output.
-     * </p>
-     * 
-     * @param array
-     *            the array
-     * @param startIndexInclusive
-     *            the starting index. Undervalue (&lt;0) is promoted to 0,
-     *            overvalue (&gt;array.length) results in an empty array.
-     * @param endIndexExclusive
-     *            elements up to endIndex-1 are present in the returned
-     *            subarray. Undervalue (&lt; startIndex) produces empty array,
-     *            overvalue (&gt;array.length) is demoted to array length.
-     * @return a new array containing the elements between the start and end
-     *         indices.
-     */
-    public static long[] subarray( long[] array, int startIndexInclusive, int endIndexExclusive )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        if ( startIndexInclusive < 0 )
-        {
-            startIndexInclusive = 0;
-        }
-        if ( endIndexExclusive > array.length )
-        {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if ( newSize <= 0 )
-        {
-            return EMPTY_LONG_ARRAY;
-        }
-
-        long[] subarray = new long[newSize];
-        System.arraycopy( array, startIndexInclusive, subarray, 0, newSize );
-        return subarray;
-    }
-
-
-    /**
-     * <p>
-     * Produces a new <code>int</code> array containing the elements between
-     * the start and end indices.
-     * </p>
-     * <p>
-     * The start index is inclusive, the end index exclusive. Null array input
-     * produces null output.
-     * </p>
-     * 
-     * @param array
-     *            the array
-     * @param startIndexInclusive
-     *            the starting index. Undervalue (&lt;0) is promoted to 0,
-     *            overvalue (&gt;array.length) results in an empty array.
-     * @param endIndexExclusive
-     *            elements up to endIndex-1 are present in the returned
-     *            subarray. Undervalue (&lt; startIndex) produces empty array,
-     *            overvalue (&gt;array.length) is demoted to array length.
-     * @return a new array containing the elements between the start and end
-     *         indices.
-     */
-    public static int[] subarray( int[] array, int startIndexInclusive, int endIndexExclusive )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        if ( startIndexInclusive < 0 )
-        {
-            startIndexInclusive = 0;
-        }
-        if ( endIndexExclusive > array.length )
-        {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if ( newSize <= 0 )
-        {
-            return EMPTY_INT_ARRAY;
-        }
-
-        int[] subarray = new int[newSize];
-        System.arraycopy( array, startIndexInclusive, subarray, 0, newSize );
-        return subarray;
-    }
-
-
-    /**
-     * <p>
-     * Produces a new <code>short</code> array containing the elements between
-     * the start and end indices.
-     * </p>
-     * <p>
-     * The start index is inclusive, the end index exclusive. Null array input
-     * produces null output.
-     * </p>
-     * 
-     * @param array
-     *            the array
-     * @param startIndexInclusive
-     *            the starting index. Undervalue (&lt;0) is promoted to 0,
-     *            overvalue (&gt;array.length) results in an empty array.
-     * @param endIndexExclusive
-     *            elements up to endIndex-1 are present in the returned
-     *            subarray. Undervalue (&lt; startIndex) produces empty array,
-     *            overvalue (&gt;array.length) is demoted to array length.
-     * @return a new array containing the elements between the start and end
-     *         indices.
-     */
-    public static short[] subarray( short[] array, int startIndexInclusive, int endIndexExclusive )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        if ( startIndexInclusive < 0 )
-        {
-            startIndexInclusive = 0;
-        }
-        if ( endIndexExclusive > array.length )
-        {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if ( newSize <= 0 )
-        {
-            return EMPTY_SHORT_ARRAY;
-        }
-
-        short[] subarray = new short[newSize];
-        System.arraycopy( array, startIndexInclusive, subarray, 0, newSize );
-        return subarray;
-    }
-
-
-    /**
-     * <p>
-     * Produces a new <code>char</code> array containing the elements between
-     * the start and end indices.
-     * </p>
-     * <p>
-     * The start index is inclusive, the end index exclusive. Null array input
-     * produces null output.
-     * </p>
-     * 
-     * @param array
-     *            the array
-     * @param startIndexInclusive
-     *            the starting index. Undervalue (&lt;0) is promoted to 0,
-     *            overvalue (&gt;array.length) results in an empty array.
-     * @param endIndexExclusive
-     *            elements up to endIndex-1 are present in the returned
-     *            subarray. Undervalue (&lt; startIndex) produces empty array,
-     *            overvalue (&gt;array.length) is demoted to array length.
-     * @return a new array containing the elements between the start and end
-     *         indices.
-     */
-    public static char[] subarray( char[] array, int startIndexInclusive, int endIndexExclusive )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        if ( startIndexInclusive < 0 )
-        {
-            startIndexInclusive = 0;
-        }
-        if ( endIndexExclusive > array.length )
-        {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if ( newSize <= 0 )
-        {
-            return EMPTY_CHAR_ARRAY;
-        }
-
-        char[] subarray = new char[newSize];
-        System.arraycopy( array, startIndexInclusive, subarray, 0, newSize );
-        return subarray;
-    }
-
-
-    /**
-     * <p>
-     * Produces a new <code>byte</code> array containing the elements between
-     * the start and end indices.
-     * </p>
-     * <p>
-     * The start index is inclusive, the end index exclusive. Null array input
-     * produces null output.
-     * </p>
-     * 
-     * @param array
-     *            the array
-     * @param startIndexInclusive
-     *            the starting index. Undervalue (&lt;0) is promoted to 0,
-     *            overvalue (&gt;array.length) results in an empty array.
-     * @param endIndexExclusive
-     *            elements up to endIndex-1 are present in the returned
-     *            subarray. Undervalue (&lt; startIndex) produces empty array,
-     *            overvalue (&gt;array.length) is demoted to array length.
-     * @return a new array containing the elements between the start and end
-     *         indices.
-     */
-    public static byte[] subarray( byte[] array, int startIndexInclusive, int endIndexExclusive )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        if ( startIndexInclusive < 0 )
-        {
-            startIndexInclusive = 0;
-        }
-        if ( endIndexExclusive > array.length )
-        {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if ( newSize <= 0 )
-        {
-            return EMPTY_BYTE_ARRAY;
-        }
-
-        byte[] subarray = new byte[newSize];
-        System.arraycopy( array, startIndexInclusive, subarray, 0, newSize );
-        return subarray;
-    }
-
-
-    /**
-     * <p>
-     * Produces a new <code>double</code> array containing the elements
-     * between the start and end indices.
-     * </p>
-     * <p>
-     * The start index is inclusive, the end index exclusive. Null array input
-     * produces null output.
-     * </p>
-     * 
-     * @param array
-     *            the array
-     * @param startIndexInclusive
-     *            the starting index. Undervalue (&lt;0) is promoted to 0,
-     *            overvalue (&gt;array.length) results in an empty array.
-     * @param endIndexExclusive
-     *            elements up to endIndex-1 are present in the returned
-     *            subarray. Undervalue (&lt; startIndex) produces empty array,
-     *            overvalue (&gt;array.length) is demoted to array length.
-     * @return a new array containing the elements between the start and end
-     *         indices.
-     */
-    public static double[] subarray( double[] array, int startIndexInclusive, int endIndexExclusive )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        if ( startIndexInclusive < 0 )
-        {
-            startIndexInclusive = 0;
-        }
-        if ( endIndexExclusive > array.length )
-        {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if ( newSize <= 0 )
-        {
-            return EMPTY_DOUBLE_ARRAY;
-        }
-
-        double[] subarray = new double[newSize];
-        System.arraycopy( array, startIndexInclusive, subarray, 0, newSize );
-        return subarray;
-    }
-
-
-    /**
-     * <p>
-     * Produces a new <code>float</code> array containing the elements between
-     * the start and end indices.
-     * </p>
-     * <p>
-     * The start index is inclusive, the end index exclusive. Null array input
-     * produces null output.
-     * </p>
-     * 
-     * @param array
-     *            the array
-     * @param startIndexInclusive
-     *            the starting index. Undervalue (&lt;0) is promoted to 0,
-     *            overvalue (&gt;array.length) results in an empty array.
-     * @param endIndexExclusive
-     *            elements up to endIndex-1 are present in the returned
-     *            subarray. Undervalue (&lt; startIndex) produces empty array,
-     *            overvalue (&gt;array.length) is demoted to array length.
-     * @return a new array containing the elements between the start and end
-     *         indices.
-     */
-    public static float[] subarray( float[] array, int startIndexInclusive, int endIndexExclusive )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        if ( startIndexInclusive < 0 )
-        {
-            startIndexInclusive = 0;
-        }
-        if ( endIndexExclusive > array.length )
-        {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if ( newSize <= 0 )
-        {
-            return EMPTY_FLOAT_ARRAY;
-        }
-
-        float[] subarray = new float[newSize];
-        System.arraycopy( array, startIndexInclusive, subarray, 0, newSize );
-        return subarray;
-    }
-
-
-    /**
-     * <p>
-     * Produces a new <code>boolean</code> array containing the elements
-     * between the start and end indices.
-     * </p>
-     * <p>
-     * The start index is inclusive, the end index exclusive. Null array input
-     * produces null output.
-     * </p>
-     * 
-     * @param array
-     *            the array
-     * @param startIndexInclusive
-     *            the starting index. Undervalue (&lt;0) is promoted to 0,
-     *            overvalue (&gt;array.length) results in an empty array.
-     * @param endIndexExclusive
-     *            elements up to endIndex-1 are present in the returned
-     *            subarray. Undervalue (&lt; startIndex) produces empty array,
-     *            overvalue (&gt;array.length) is demoted to array length.
-     * @return a new array containing the elements between the start and end
-     *         indices.
-     */
-    public static boolean[] subarray( boolean[] array, int startIndexInclusive, int endIndexExclusive )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        if ( startIndexInclusive < 0 )
-        {
-            startIndexInclusive = 0;
-        }
-        if ( endIndexExclusive > array.length )
-        {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if ( newSize <= 0 )
-        {
-            return EMPTY_BOOLEAN_ARRAY;
-        }
-
-        boolean[] subarray = new boolean[newSize];
-        System.arraycopy( array, startIndexInclusive, subarray, 0, newSize );
-        return subarray;
-    }
-
-
-    // Is same length
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Checks whether two arrays are the same length, treating <code>null</code>
-     * arrays as length <code>0</code>.
-     * <p>
-     * Any multi-dimensional aspects of the arrays are ignored.
-     * </p>
-     * 
-     * @param array1
-     *            the first array, may be <code>null</code>
-     * @param array2
-     *            the second array, may be <code>null</code>
-     * @return <code>true</code> if length of arrays matches, treating
-     *         <code>null</code> as an empty array
-     */
-    public static boolean isSameLength( Object[] array1, Object[] array2 )
-    {
-        if ( ( array1 == null && array2 != null && array2.length > 0 )
-            || ( array2 == null && array1 != null && array1.length > 0 )
-            || ( array1 != null && array2 != null && array1.length != array2.length ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-
-    /**
-     * <p>
-     * Checks whether two arrays are the same length, treating <code>null</code>
-     * arrays as length <code>0</code>.
-     * </p>
-     * 
-     * @param array1
-     *            the first array, may be <code>null</code>
-     * @param array2
-     *            the second array, may be <code>null</code>
-     * @return <code>true</code> if length of arrays matches, treating
-     *         <code>null</code> as an empty array
-     */
-    public static boolean isSameLength( long[] array1, long[] array2 )
-    {
-        if ( ( array1 == null && array2 != null && array2.length > 0 )
-            || ( array2 == null && array1 != null && array1.length > 0 )
-            || ( array1 != null && array2 != null && array1.length != array2.length ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-
-    /**
-     * <p>
-     * Checks whether two arrays are the same length, treating <code>null</code>
-     * arrays as length <code>0</code>.
-     * </p>
-     * 
-     * @param array1
-     *            the first array, may be <code>null</code>
-     * @param array2
-     *            the second array, may be <code>null</code>
-     * @return <code>true</code> if length of arrays matches, treating
-     *         <code>null</code> as an empty array
-     */
-    public static boolean isSameLength( int[] array1, int[] array2 )
-    {
-        if ( ( array1 == null && array2 != null && array2.length > 0 )
-            || ( array2 == null && array1 != null && array1.length > 0 )
-            || ( array1 != null && array2 != null && array1.length != array2.length ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-
-    /**
-     * <p>
-     * Checks whether two arrays are the same length, treating <code>null</code>
-     * arrays as length <code>0</code>.
-     * </p>
-     * 
-     * @param array1
-     *            the first array, may be <code>null</code>
-     * @param array2
-     *            the second array, may be <code>null</code>
-     * @return <code>true</code> if length of arrays matches, treating
-     *         <code>null</code> as an empty array
-     */
-    public static boolean isSameLength( short[] array1, short[] array2 )
-    {
-        if ( ( array1 == null && array2 != null && array2.length > 0 )
-            || ( array2 == null && array1 != null && array1.length > 0 )
-            || ( array1 != null && array2 != null && array1.length != array2.length ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-
-    /**
-     * <p>
-     * Checks whether two arrays are the same length, treating <code>null</code>
-     * arrays as length <code>0</code>.
-     * </p>
-     * 
-     * @param array1
-     *            the first array, may be <code>null</code>
-     * @param array2
-     *            the second array, may be <code>null</code>
-     * @return <code>true</code> if length of arrays matches, treating
-     *         <code>null</code> as an empty array
-     */
-    public static boolean isSameLength( char[] array1, char[] array2 )
-    {
-        if ( ( array1 == null && array2 != null && array2.length > 0 )
-            || ( array2 == null && array1 != null && array1.length > 0 )
-            || ( array1 != null && array2 != null && array1.length != array2.length ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-
-    /**
-     * <p>
-     * Checks whether two arrays are the same length, treating <code>null</code>
-     * arrays as length <code>0</code>.
-     * </p>
-     * 
-     * @param array1
-     *            the first array, may be <code>null</code>
-     * @param array2
-     *            the second array, may be <code>null</code>
-     * @return <code>true</code> if length of arrays matches, treating
-     *         <code>null</code> as an empty array
-     */
-    public static boolean isSameLength( byte[] array1, byte[] array2 )
-    {
-        if ( ( array1 == null && array2 != null && array2.length > 0 )
-            || ( array2 == null && array1 != null && array1.length > 0 )
-            || ( array1 != null && array2 != null && array1.length != array2.length ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-
-    /**
-     * <p>
-     * Checks whether two arrays are the same length, treating <code>null</code>
-     * arrays as length <code>0</code>.
-     * </p>
-     * 
-     * @param array1
-     *            the first array, may be <code>null</code>
-     * @param array2
-     *            the second array, may be <code>null</code>
-     * @return <code>true</code> if length of arrays matches, treating
-     *         <code>null</code> as an empty array
-     */
-    public static boolean isSameLength( double[] array1, double[] array2 )
-    {
-        if ( ( array1 == null && array2 != null && array2.length > 0 )
-            || ( array2 == null && array1 != null && array1.length > 0 )
-            || ( array1 != null && array2 != null && array1.length != array2.length ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-
-    /**
-     * <p>
-     * Checks whether two arrays are the same length, treating <code>null</code>
-     * arrays as length <code>0</code>.
-     * </p>
-     * 
-     * @param array1
-     *            the first array, may be <code>null</code>
-     * @param array2
-     *            the second array, may be <code>null</code>
-     * @return <code>true</code> if length of arrays matches, treating
-     *         <code>null</code> as an empty array
-     */
-    public static boolean isSameLength( float[] array1, float[] array2 )
-    {
-        if ( ( array1 == null && array2 != null && array2.length > 0 )
-            || ( array2 == null && array1 != null && array1.length > 0 )
-            || ( array1 != null && array2 != null && array1.length != array2.length ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-
-    /**
-     * <p>
-     * Checks whether two arrays are the same length, treating <code>null</code>
-     * arrays as length <code>0</code>.
-     * </p>
-     * 
-     * @param array1
-     *            the first array, may be <code>null</code>
-     * @param array2
-     *            the second array, may be <code>null</code>
-     * @return <code>true</code> if length of arrays matches, treating
-     *         <code>null</code> as an empty array
-     */
-    public static boolean isSameLength( boolean[] array1, boolean[] array2 )
-    {
-        if ( ( array1 == null && array2 != null && array2.length > 0 )
-            || ( array2 == null && array1 != null && array1.length > 0 )
-            || ( array1 != null && array2 != null && array1.length != array2.length ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Returns the length of the specified array. This method can deal with
-     * <code>Object</code> arrays and with primitive arrays.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, <code>0</code> is returned.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.getLength(null)            = 0
-     *  ArrayUtils.getLength([])              = 0
-     *  ArrayUtils.getLength([null])          = 1
-     *  ArrayUtils.getLength([true, false])   = 2
-     *  ArrayUtils.getLength([1, 2, 3])       = 3
-     *  ArrayUtils.getLength([&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]) = 3
-     * </pre>
-     * 
-     * @param array
-     *            the array to retrieve the length from, may be null
-     * @return The length of the array, or <code>0</code> if the array is
-     *         <code>null</code>
-     * @throws IllegalArgumentException
-     *             if the object arguement is not an array.
-     */
-    public static int getLength( Object array )
-    {
-        if ( array == null )
-        {
-            return 0;
-        }
-        else
-        {
-            return Array.getLength( array );
-        }
-    }
-
-
-    /**
-     * Returns the last index of the given array or -1 if empty or null. This
-     * method can deal with <code>Object</code> arrays and with primitive
-     * arrays. This value is one less than the size since arrays indices are
-     * 0-based.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.lastIndex(null)            = -1
-     *  ArrayUtils.lastIndex([])              = -1
-     *  ArrayUtils.lastIndex([null])          = 0
-     *  ArrayUtils.lastIndex([true, false])   = 1
-     *  ArrayUtils.lastIndex([1, 2, 3])       = 2
-     *  ArrayUtils.lastIndex([&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]) = 2
-     * </pre>
-     * 
-     * @param array
-     *            the array to return the last index for, may be null
-     * @return the last index, -1 if empty or null
-     * @throws IllegalArgumentException
-     *             if the object arguement is not an array.
-     */
-    public static int lastIndex( Object array )
-    {
-        return ArrayUtils.getLength( array ) - 1;
-    }
-
-
-    /**
-     * <p>
-     * Checks whether two arrays are the same type taking into account
-     * multi-dimensional arrays.
-     * </p>
-     * 
-     * @param array1
-     *            the first array, must not be <code>null</code>
-     * @param array2
-     *            the second array, must not be <code>null</code>
-     * @return <code>true</code> if type of arrays matches
-     * @throws IllegalArgumentException
-     *             if either array is <code>null</code>
-     */
-    public static boolean isSameType( Object array1, Object array2 )
-    {
-        if ( array1 == null || array2 == null )
-        {
-            throw new IllegalArgumentException( I18n.err( I18n.ERR_04337 ) );
-        }
-        return array1.getClass().getName().equals( array2.getClass().getName() );
-    }
-
-
-    // Reverse
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Reverses the order of the given array.
-     * </p>
-     * <p>
-     * There is no special handling for multi-dimensional arrays.
-     * </p>
-     * <p>
-     * This method does nothing if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to reverse, may be <code>null</code>
-     */
-    public static void reverse( Object[] array )
-    {
-        if ( array == null )
-        {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        Object tmp;
-        while ( j > i )
-        {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-
-    /**
-     * <p>
-     * Reverses the order of the given array.
-     * </p>
-     * <p>
-     * This method does nothing if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to reverse, may be <code>null</code>
-     */
-    public static void reverse( long[] array )
-    {
-        if ( array == null )
-        {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        long tmp;
-        while ( j > i )
-        {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-
-    /**
-     * <p>
-     * Reverses the order of the given array.
-     * </p>
-     * <p>
-     * This method does nothing if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to reverse, may be <code>null</code>
-     */
-    public static void reverse( int[] array )
-    {
-        if ( array == null )
-        {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        int tmp;
-        while ( j > i )
-        {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-
-    /**
-     * <p>
-     * Reverses the order of the given array.
-     * </p>
-     * <p>
-     * This method does nothing if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to reverse, may be <code>null</code>
-     */
-    public static void reverse( short[] array )
-    {
-        if ( array == null )
-        {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        short tmp;
-        while ( j > i )
-        {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-
-    /**
-     * <p>
-     * Reverses the order of the given array.
-     * </p>
-     * <p>
-     * This method does nothing if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to reverse, may be <code>null</code>
-     */
-    public static void reverse( char[] array )
-    {
-        if ( array == null )
-        {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        char tmp;
-        while ( j > i )
-        {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-
-    /**
-     * <p>
-     * Reverses the order of the given array.
-     * </p>
-     * <p>
-     * This method does nothing if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to reverse, may be <code>null</code>
-     */
-    public static void reverse( byte[] array )
-    {
-        if ( array == null )
-        {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        byte tmp;
-        while ( j > i )
-        {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-
-    /**
-     * <p>
-     * Reverses the order of the given array.
-     * </p>
-     * <p>
-     * This method does nothing if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to reverse, may be <code>null</code>
-     */
-    public static void reverse( double[] array )
-    {
-        if ( array == null )
-        {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        double tmp;
-        while ( j > i )
-        {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-
-    /**
-     * <p>
-     * Reverses the order of the given array.
-     * </p>
-     * <p>
-     * This method does nothing if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to reverse, may be <code>null</code>
-     */
-    public static void reverse( float[] array )
-    {
-        if ( array == null )
-        {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        float tmp;
-        while ( j > i )
-        {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-
-    /**
-     * <p>
-     * Reverses the order of the given array.
-     * </p>
-     * <p>
-     * This method does nothing if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to reverse, may be <code>null</code>
-     */
-    public static void reverse( boolean[] array )
-    {
-        if ( array == null )
-        {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        boolean tmp;
-        while ( j > i )
-        {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-
-    // IndexOf search
-    // ----------------------------------------------------------------------
-
-    // Object IndexOf
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Find the index of the given object in the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param objectToFind
-     *            the object to find, may be <code>null</code>
-     * @return the index of the object within the array, <code>-1</code> if
-     *         not found or <code>null</code> array input
-     */
-    public static int indexOf( Object[] array, Object objectToFind )
-    {
-        return indexOf( array, objectToFind, 0 );
-    }
-
-
-    /**
-     * <p>
-     * Find the index of the given object in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex is treated as zero. A startIndex larger than the
-     * array length will return <code>-1</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param objectToFind
-     *            the object to find, may be <code>null</code>
-     * @param startIndex
-     *            the index to start searching at
-     * @return the index of the object within the array starting at the index,
-     *         <code>-1</code> if not found or <code>null</code> array input
-     */
-    public static int indexOf( Object[] array, Object objectToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            startIndex = 0;
-        }
-        if ( objectToFind == null )
-        {
-            for ( int i = startIndex; i < array.length; i++ )
-            {
-                if ( array[i] == null )
-                {
-                    return i;
-                }
-            }
-        }
-        else
-        {
-            for ( int i = startIndex; i < array.length; i++ )
-            {
-                if ( objectToFind.equals( array[i] ) )
-                {
-                    return i;
-                }
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given object within the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to travers backwords looking for the object, may be
-     *            <code>null</code>
-     * @param objectToFind
-     *            the object to find, may be <code>null</code>
-     * @return the last index of the object within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( Object[] array, Object objectToFind )
-    {
-        return lastIndexOf( array, objectToFind, Integer.MAX_VALUE );
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given object in the array starting at the
-     * given index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex will return <code>-1</code>. A startIndex larger
-     * than the array length will search from the end of the array.
-     * </p>
-     * 
-     * @param array
-     *            the array to traverse for looking for the object, may be
-     *            <code>null</code>
-     * @param objectToFind
-     *            the object to find, may be <code>null</code>
-     * @param startIndex
-     *            the start index to travers backwards from
-     * @return the last index of the object within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( Object[] array, Object objectToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            return -1;
-        }
-        else if ( startIndex >= array.length )
-        {
-            startIndex = array.length - 1;
-        }
-        if ( objectToFind == null )
-        {
-            for ( int i = startIndex; i >= 0; i-- )
-            {
-                if ( array[i] == null )
-                {
-                    return i;
-                }
-            }
-        }
-        else
-        {
-            for ( int i = startIndex; i >= 0; i-- )
-            {
-                if ( objectToFind.equals( array[i] ) )
-                {
-                    return i;
-                }
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Checks if the object is in the given array.
-     * </p>
-     * <p>
-     * The method returns <code>false</code> if a <code>null</code> array is
-     * passed in.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through
-     * @param objectToFind
-     *            the object to find
-     * @return <code>true</code> if the array contains the object
-     */
-    public static boolean contains( Object[] array, Object objectToFind )
-    {
-        return ( indexOf( array, objectToFind ) != -1 );
-    }
-
-
-    // long IndexOf
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Find the index of the given value in the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( long[] array, long valueToFind )
-    {
-        return indexOf( array, valueToFind, 0 );
-    }
-
-
-    /**
-     * <p>
-     * Find the index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex is treated as zero. A startIndex larger than the
-     * array length will return -1.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the index to start searching at
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( long[] array, long valueToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            startIndex = 0;
-        }
-        for ( int i = startIndex; i < array.length; i++ )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value within the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to travers backwords looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the object to find
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( long[] array, long valueToFind )
-    {
-        return lastIndexOf( array, valueToFind, Integer.MAX_VALUE );
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex will return -1. A startIndex larger than the array
-     * length will search from the end of the array.
-     * </p>
-     * 
-     * @param array
-     *            the array to traverse for looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the start index to travers backwards from
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( long[] array, long valueToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            return -1;
-        }
-        else if ( startIndex >= array.length )
-        {
-            startIndex = array.length - 1;
-        }
-        for ( int i = startIndex; i >= 0; i-- )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Checks if the value is in the given array.
-     * </p>
-     * <p>
-     * The method returns <code>false</code> if a <code>null</code> array is
-     * passed in.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through
-     * @param valueToFind
-     *            the value to find
-     * @return <code>true</code> if the array contains the object
-     */
-    public static boolean contains( long[] array, long valueToFind )
-    {
-        return ( indexOf( array, valueToFind ) != -1 );
-    }
-
-
-    // int IndexOf
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Find the index of the given value in the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( int[] array, int valueToFind )
-    {
-        return indexOf( array, valueToFind, 0 );
-    }
-
-
-    /**
-     * <p>
-     * Find the index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex is treated as zero. A startIndex larger than the
-     * array length will return -1.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the index to start searching at
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( int[] array, int valueToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            startIndex = 0;
-        }
-        for ( int i = startIndex; i < array.length; i++ )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value within the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to travers backwords looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the object to find
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( int[] array, int valueToFind )
-    {
-        return lastIndexOf( array, valueToFind, Integer.MAX_VALUE );
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex will return -1. A startIndex larger than the array
-     * length will search from the end of the array.
-     * </p>
-     * 
-     * @param array
-     *            the array to traverse for looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the start index to travers backwards from
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( int[] array, int valueToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            return -1;
-        }
-        else if ( startIndex >= array.length )
-        {
-            startIndex = array.length - 1;
-        }
-        for ( int i = startIndex; i >= 0; i-- )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Checks if the value is in the given array.
-     * </p>
-     * <p>
-     * The method returns <code>false</code> if a <code>null</code> array is
-     * passed in.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through
-     * @param valueToFind
-     *            the value to find
-     * @return <code>true</code> if the array contains the object
-     */
-    public static boolean contains( int[] array, int valueToFind )
-    {
-        return ( indexOf( array, valueToFind ) != -1 );
-    }
-
-
-    // short IndexOf
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Find the index of the given value in the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( short[] array, short valueToFind )
-    {
-        return indexOf( array, valueToFind, 0 );
-    }
-
-
-    /**
-     * <p>
-     * Find the index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex is treated as zero. A startIndex larger than the
-     * array length will return -1.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the index to start searching at
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( short[] array, short valueToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            startIndex = 0;
-        }
-        for ( int i = startIndex; i < array.length; i++ )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value within the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to travers backwords looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the object to find
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( short[] array, short valueToFind )
-    {
-        return lastIndexOf( array, valueToFind, Integer.MAX_VALUE );
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex will return -1. A startIndex larger than the array
-     * length will search from the end of the array.
-     * </p>
-     * 
-     * @param array
-     *            the array to traverse for looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the start index to travers backwards from
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( short[] array, short valueToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            return -1;
-        }
-        else if ( startIndex >= array.length )
-        {
-            startIndex = array.length - 1;
-        }
-        for ( int i = startIndex; i >= 0; i-- )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Checks if the value is in the given array.
-     * </p>
-     * <p>
-     * The method returns <code>false</code> if a <code>null</code> array is
-     * passed in.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through
-     * @param valueToFind
-     *            the value to find
-     * @return <code>true</code> if the array contains the object
-     */
-    public static boolean contains( short[] array, short valueToFind )
-    {
-        return ( indexOf( array, valueToFind ) != -1 );
-    }
-
-
-    // char IndexOf
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Find the index of the given value in the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( char[] array, char valueToFind )
-    {
-        return indexOf( array, valueToFind, 0 );
-    }
-
-
-    /**
-     * <p>
-     * Find the index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex is treated as zero. A startIndex larger than the
-     * array length will return -1.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the index to start searching at
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( char[] array, char valueToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            startIndex = 0;
-        }
-        for ( int i = startIndex; i < array.length; i++ )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value within the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to travers backwords looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the object to find
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( char[] array, char valueToFind )
-    {
-        return lastIndexOf( array, valueToFind, Integer.MAX_VALUE );
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex will return -1. A startIndex larger than the array
-     * length will search from the end of the array.
-     * </p>
-     * 
-     * @param array
-     *            the array to traverse for looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the start index to travers backwards from
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( char[] array, char valueToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            return -1;
-        }
-        else if ( startIndex >= array.length )
-        {
-            startIndex = array.length - 1;
-        }
-        for ( int i = startIndex; i >= 0; i-- )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Checks if the value is in the given array.
-     * </p>
-     * <p>
-     * The method returns <code>false</code> if a <code>null</code> array is
-     * passed in.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through
-     * @param valueToFind
-     *            the value to find
-     * @return <code>true</code> if the array contains the object
-     */
-    public static boolean contains( char[] array, char valueToFind )
-    {
-        return ( indexOf( array, valueToFind ) != -1 );
-    }
-
-
-    // byte IndexOf
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Find the index of the given value in the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( byte[] array, byte valueToFind )
-    {
-        return indexOf( array, valueToFind, 0 );
-    }
-
-
-    /**
-     * <p>
-     * Find the index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex is treated as zero. A startIndex larger than the
-     * array length will return -1.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the index to start searching at
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( byte[] array, byte valueToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            startIndex = 0;
-        }
-        for ( int i = startIndex; i < array.length; i++ )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value within the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to travers backwords looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the object to find
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( byte[] array, byte valueToFind )
-    {
-        return lastIndexOf( array, valueToFind, Integer.MAX_VALUE );
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex will return -1. A startIndex larger than the array
-     * length will search from the end of the array.
-     * </p>
-     * 
-     * @param array
-     *            the array to traverse for looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the start index to travers backwards from
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( byte[] array, byte valueToFind, int startIndex )
-    {
-        if ( array == null )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            return -1;
-        }
-        else if ( startIndex >= array.length )
-        {
-            startIndex = array.length - 1;
-        }
-        for ( int i = startIndex; i >= 0; i-- )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Checks if the value is in the given array.
-     * </p>
-     * <p>
-     * The method returns <code>false</code> if a <code>null</code> array is
-     * passed in.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through
-     * @param valueToFind
-     *            the value to find
-     * @return <code>true</code> if the array contains the object
-     */
-    public static boolean contains( byte[] array, byte valueToFind )
-    {
-        return ( indexOf( array, valueToFind ) != -1 );
-    }
-
-
-    // double IndexOf
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Find the index of the given value in the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( double[] array, double valueToFind )
-    {
-        return indexOf( array, valueToFind, 0 );
-    }
-
-
-    /**
-     * <p>
-     * Find the index of the given value within a given tolerance in the array.
-     * This method will return the index of the first value which falls between
-     * the region defined by valueToFind - tolerance and valueToFind +
-     * tolerance.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param tolerance
-     *            tolerance of the search
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( double[] array, double valueToFind, double tolerance )
-    {
-        return indexOf( array, valueToFind, 0, tolerance );
-    }
-
-
-    /**
-     * <p>
-     * Find the index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex is treated as zero. A startIndex larger than the
-     * array length will return -1.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the index to start searching at
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( double[] array, double valueToFind, int startIndex )
-    {
-        if ( ArrayUtils.isEmpty( array ) )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            startIndex = 0;
-        }
-        for ( int i = startIndex; i < array.length; i++ )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Find the index of the given value in the array starting at the given
-     * index. This method will return the index of the first value which falls
-     * between the region defined by valueToFind - tolerance and valueToFind +
-     * tolerance.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex is treated as zero. A startIndex larger than the
-     * array length will return -1.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the index to start searching at
-     * @param tolerance
-     *            tolerance of the search
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( double[] array, double valueToFind, int startIndex, double tolerance )
-    {
-        if ( ArrayUtils.isEmpty( array ) )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            startIndex = 0;
-        }
-        double min = valueToFind - tolerance;
-        double max = valueToFind + tolerance;
-        for ( int i = startIndex; i < array.length; i++ )
-        {
-            if ( array[i] >= min && array[i] <= max )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value within the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to travers backwords looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the object to find
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( double[] array, double valueToFind )
-    {
-        return lastIndexOf( array, valueToFind, Integer.MAX_VALUE );
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value within a given tolerance in the
-     * array. This method will return the index of the last value which falls
-     * between the region defined by valueToFind - tolerance and valueToFind +
-     * tolerance.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param tolerance
-     *            tolerance of the search
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int lastIndexOf( double[] array, double valueToFind, double tolerance )
-    {
-        return lastIndexOf( array, valueToFind, Integer.MAX_VALUE, tolerance );
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex will return -1. A startIndex larger than the array
-     * length will search from the end of the array.
-     * </p>
-     * 
-     * @param array
-     *            the array to traverse for looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the start index to travers backwards from
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( double[] array, double valueToFind, int startIndex )
-    {
-        if ( ArrayUtils.isEmpty( array ) )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            return -1;
-        }
-        else if ( startIndex >= array.length )
-        {
-            startIndex = array.length - 1;
-        }
-        for ( int i = startIndex; i >= 0; i-- )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value in the array starting at the given
-     * index. This method will return the index of the last value which falls
-     * between the region defined by valueToFind - tolerance and valueToFind +
-     * tolerance.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex will return -1. A startIndex larger than the array
-     * length will search from the end of the array.
-     * </p>
-     * 
-     * @param array
-     *            the array to traverse for looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the start index to travers backwards from
-     * @param tolerance
-     *            search for value within plus/minus this amount
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( double[] array, double valueToFind, int startIndex, double tolerance )
-    {
-        if ( ArrayUtils.isEmpty( array ) )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            return -1;
-        }
-        else if ( startIndex >= array.length )
-        {
-            startIndex = array.length - 1;
-        }
-        double min = valueToFind - tolerance;
-        double max = valueToFind + tolerance;
-        for ( int i = startIndex; i >= 0; i-- )
-        {
-            if ( array[i] >= min && array[i] <= max )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Checks if the value is in the given array.
-     * </p>
-     * <p>
-     * The method returns <code>false</code> if a <code>null</code> array is
-     * passed in.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through
-     * @param valueToFind
-     *            the value to find
-     * @return <code>true</code> if the array contains the object
-     */
-    public static boolean contains( double[] array, double valueToFind )
-    {
-        return ( indexOf( array, valueToFind ) != -1 );
-    }
-
-
-    /**
-     * <p>
-     * Checks if a value falling within the given tolerance is in the given
-     * array. If the array contains a value within the inclusive range defined
-     * by (value - tolerance) to (value + tolerance).
-     * </p>
-     * <p>
-     * The method returns <code>false</code> if a <code>null</code> array is
-     * passed in.
-     * </p>
-     * 
-     * @param array
-     *            the array to search
-     * @param valueToFind
-     *            the value to find
-     * @param tolerance
-     *            the array contains the tolerance of the search
-     * @return true if value falling within tolerance is in array
-     */
-    public static boolean contains( double[] array, double valueToFind, double tolerance )
-    {
-        return ( indexOf( array, valueToFind, 0, tolerance ) != -1 );
-    }
-
-
-    // float IndexOf
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Find the index of the given value in the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( float[] array, float valueToFind )
-    {
-        return indexOf( array, valueToFind, 0 );
-    }
-
-
-    /**
-     * <p>
-     * Find the index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex is treated as zero. A startIndex larger than the
-     * array length will return -1.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the index to start searching at
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( float[] array, float valueToFind, int startIndex )
-    {
-        if ( ArrayUtils.isEmpty( array ) )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            startIndex = 0;
-        }
-        for ( int i = startIndex; i < array.length; i++ )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value within the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to travers backwords looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the object to find
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( float[] array, float valueToFind )
-    {
-        return lastIndexOf( array, valueToFind, Integer.MAX_VALUE );
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex will return -1. A startIndex larger than the array
-     * length will search from the end of the array.
-     * </p>
-     * 
-     * @param array
-     *            the array to traverse for looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the start index to travers backwards from
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( float[] array, float valueToFind, int startIndex )
-    {
-        if ( ArrayUtils.isEmpty( array ) )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            return -1;
-        }
-        else if ( startIndex >= array.length )
-        {
-            startIndex = array.length - 1;
-        }
-        for ( int i = startIndex; i >= 0; i-- )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Checks if the value is in the given array.
-     * </p>
-     * <p>
-     * The method returns <code>false</code> if a <code>null</code> array is
-     * passed in.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through
-     * @param valueToFind
-     *            the value to find
-     * @return <code>true</code> if the array contains the object
-     */
-    public static boolean contains( float[] array, float valueToFind )
-    {
-        return ( indexOf( array, valueToFind ) != -1 );
-    }
-
-
-    // boolean IndexOf
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Find the index of the given value in the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( boolean[] array, boolean valueToFind )
-    {
-        return indexOf( array, valueToFind, 0 );
-    }
-
-
-    /**
-     * <p>
-     * Find the index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex is treated as zero. A startIndex larger than the
-     * array length will return -1.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the index to start searching at
-     * @return the index of the value within the array, <code>-1</code> if not
-     *         found or <code>null</code> array input
-     */
-    public static int indexOf( boolean[] array, boolean valueToFind, int startIndex )
-    {
-        if ( ArrayUtils.isEmpty( array ) )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            startIndex = 0;
-        }
-        for ( int i = startIndex; i < array.length; i++ )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value within the array.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * 
-     * @param array
-     *            the array to travers backwords looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the object to find
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( boolean[] array, boolean valueToFind )
-    {
-        return lastIndexOf( array, valueToFind, Integer.MAX_VALUE );
-    }
-
-
-    /**
-     * <p>
-     * Find the last index of the given value in the array starting at the given
-     * index.
-     * </p>
-     * <p>
-     * This method returns <code>-1</code> if <code>null</code> array input.
-     * </p>
-     * <p>
-     * A negative startIndex will return -1. A startIndex larger than the array
-     * length will search from the end of the array.
-     * </p>
-     * 
-     * @param array
-     *            the array to traverse for looking for the object, may be
-     *            <code>null</code>
-     * @param valueToFind
-     *            the value to find
-     * @param startIndex
-     *            the start index to travers backwards from
-     * @return the last index of the value within the array, <code>-1</code>
-     *         if not found or <code>null</code> array input
-     */
-    public static int lastIndexOf( boolean[] array, boolean valueToFind, int startIndex )
-    {
-        if ( ArrayUtils.isEmpty( array ) )
-        {
-            return -1;
-        }
-        if ( startIndex < 0 )
-        {
-            return -1;
-        }
-        else if ( startIndex >= array.length )
-        {
-            startIndex = array.length - 1;
-        }
-        for ( int i = startIndex; i >= 0; i-- )
-        {
-            if ( valueToFind == array[i] )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * <p>
-     * Checks if the value is in the given array.
-     * </p>
-     * <p>
-     * The method returns <code>false</code> if a <code>null</code> array is
-     * passed in.
-     * </p>
-     * 
-     * @param array
-     *            the array to search through
-     * @param valueToFind
-     *            the value to find
-     * @return <code>true</code> if the array contains the object
-     */
-    public static boolean contains( boolean[] array, boolean valueToFind )
-    {
-        return ( indexOf( array, valueToFind ) != -1 );
-    }
-
-
-    // Primitive/Object array converters
-    // ----------------------------------------------------------------------
-
-    // Long array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts an array of object Longs to primitives.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Long</code> array, may be <code>null</code>
-     * @return a <code>long</code> array, <code>null</code> if null array
-     *         input
-     * @throws NullPointerException
-     *             if array content is <code>null</code>
-     */
-    public static long[] toPrimitive( Long[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_LONG_ARRAY;
-        }
-        final long[] result = new long[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = array[i].longValue();
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of object Long to primitives handling <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Long</code> array, may be <code>null</code>
-     * @param valueForNull
-     *            the value to insert if <code>null</code> found
-     * @return a <code>long</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static long[] toPrimitive( Long[] array, long valueForNull )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_LONG_ARRAY;
-        }
-        final long[] result = new long[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            Long b = array[i];
-            result[i] = ( b == null ? valueForNull : b.longValue() );
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of primitive longs to objects.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>long</code> array
-     * @return a <code>Long</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static Long[] toObject( long[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_LONG_OBJECT_ARRAY;
-        }
-        final Long[] result = new Long[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = Long.valueOf( array[i] );
-        }
-        return result;
-    }
-
-
-    // Int array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts an array of object Integers to primitives.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Integer</code> array, may be <code>null</code>
-     * @return an <code>int</code> array, <code>null</code> if null array
-     *         input
-     * @throws NullPointerException
-     *             if array content is <code>null</code>
-     */
-    public static int[] toPrimitive( Integer[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_INT_ARRAY;
-        }
-        final int[] result = new int[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = array[i].intValue();
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of object Integer to primitives handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Integer</code> array, may be <code>null</code>
-     * @param valueForNull
-     *            the value to insert if <code>null</code> found
-     * @return an <code>int</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static int[] toPrimitive( Integer[] array, int valueForNull )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_INT_ARRAY;
-        }
-        final int[] result = new int[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            Integer b = array[i];
-            result[i] = ( b == null ? valueForNull : b.intValue() );
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of primitive ints to objects.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            an <code>int</code> array
-     * @return an <code>Integer</code> array, <code>null</code> if null
-     *         array input
-     */
-    public static Integer[] toObject( int[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_INTEGER_OBJECT_ARRAY;
-        }
-        final Integer[] result = new Integer[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = Integer.valueOf( array[i] );
-        }
-        return result;
-    }
-
-
-    // Short array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts an array of object Shorts to primitives.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Short</code> array, may be <code>null</code>
-     * @return a <code>byte</code> array, <code>null</code> if null array
-     *         input
-     * @throws NullPointerException
-     *             if array content is <code>null</code>
-     */
-    public static short[] toPrimitive( Short[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_SHORT_ARRAY;
-        }
-        final short[] result = new short[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = array[i].shortValue();
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of object Short to primitives handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Short</code> array, may be <code>null</code>
-     * @param valueForNull
-     *            the value to insert if <code>null</code> found
-     * @return a <code>byte</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static short[] toPrimitive( Short[] array, short valueForNull )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_SHORT_ARRAY;
-        }
-        final short[] result = new short[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            Short b = array[i];
-            result[i] = ( b == null ? valueForNull : b.shortValue() );
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of primitive shorts to objects.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>short</code> array
-     * @return a <code>Short</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static Short[] toObject( short[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_SHORT_OBJECT_ARRAY;
-        }
-        final Short[] result = new Short[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = Short.valueOf( array[i] );
-        }
-        return result;
-    }
-
-
-    // Byte array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts an array of object Bytes to primitives.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Byte</code> array, may be <code>null</code>
-     * @return a <code>byte</code> array, <code>null</code> if null array
-     *         input
-     * @throws NullPointerException
-     *             if array content is <code>null</code>
-     */
-    public static byte[] toPrimitive( Byte[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_BYTE_ARRAY;
-        }
-        final byte[] result = new byte[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = array[i].byteValue();
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of object Bytes to primitives handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Byte</code> array, may be <code>null</code>
-     * @param valueForNull
-     *            the value to insert if <code>null</code> found
-     * @return a <code>byte</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static byte[] toPrimitive( Byte[] array, byte valueForNull )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_BYTE_ARRAY;
-        }
-        final byte[] result = new byte[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            Byte b = array[i];
-            result[i] = ( b == null ? valueForNull : b.byteValue() );
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of primitive bytes to objects.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>byte</code> array
-     * @return a <code>Byte</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static Byte[] toObject( byte[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_BYTE_OBJECT_ARRAY;
-        }
-        final Byte[] result = new Byte[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = Byte.valueOf( array[i] );
-        }
-        return result;
-    }
-
-
-    // Double array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts an array of object Doubles to primitives.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Double</code> array, may be <code>null</code>
-     * @return a <code>double</code> array, <code>null</code> if null array
-     *         input
-     * @throws NullPointerException
-     *             if array content is <code>null</code>
-     */
-    public static double[] toPrimitive( Double[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_DOUBLE_ARRAY;
-        }
-        final double[] result = new double[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = array[i].doubleValue();
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of object Doubles to primitives handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Double</code> array, may be <code>null</code>
-     * @param valueForNull
-     *            the value to insert if <code>null</code> found
-     * @return a <code>double</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static double[] toPrimitive( Double[] array, double valueForNull )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_DOUBLE_ARRAY;
-        }
-        final double[] result = new double[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            Double b = array[i];
-            result[i] = ( b == null ? valueForNull : b.doubleValue() );
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of primitive doubles to objects.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>double</code> array
-     * @return a <code>Double</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static Double[] toObject( double[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_DOUBLE_OBJECT_ARRAY;
-        }
-        final Double[] result = new Double[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = Double.valueOf( array[i] );
-        }
-        return result;
-    }
-
-
-    // Float array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts an array of object Floats to primitives.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Float</code> array, may be <code>null</code>
-     * @return a <code>float</code> array, <code>null</code> if null array
-     *         input
-     * @throws NullPointerException
-     *             if array content is <code>null</code>
-     */
-    public static float[] toPrimitive( Float[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_FLOAT_ARRAY;
-        }
-        final float[] result = new float[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = array[i].floatValue();
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of object Floats to primitives handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Float</code> array, may be <code>null</code>
-     * @param valueForNull
-     *            the value to insert if <code>null</code> found
-     * @return a <code>float</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static float[] toPrimitive( Float[] array, float valueForNull )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_FLOAT_ARRAY;
-        }
-        final float[] result = new float[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            Float b = array[i];
-            result[i] = ( b == null ? valueForNull : b.floatValue() );
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of primitive floats to objects.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>float</code> array
-     * @return a <code>Float</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static Float[] toObject( float[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_FLOAT_OBJECT_ARRAY;
-        }
-        final Float[] result = new Float[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = Float.valueOf( array[i] );
-        }
-        return result;
-    }
-
-
-    // Boolean array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts an array of object Booleans to primitives.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Boolean</code> array, may be <code>null</code>
-     * @return a <code>boolean</code> array, <code>null</code> if null array
-     *         input
-     * @throws NullPointerException
-     *             if array content is <code>null</code>
-     */
-    public static boolean[] toPrimitive( Boolean[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_BOOLEAN_ARRAY;
-        }
-        final boolean[] result = new boolean[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = array[i].booleanValue();
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of object Booleans to primitives handling
-     * <code>null</code>.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>Boolean</code> array, may be <code>null</code>
-     * @param valueForNull
-     *            the value to insert if <code>null</code> found
-     * @return a <code>boolean</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static boolean[] toPrimitive( Boolean[] array, boolean valueForNull )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_BOOLEAN_ARRAY;
-        }
-        final boolean[] result = new boolean[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            Boolean b = array[i];
-            result[i] = ( b == null ? valueForNull : b.booleanValue() );
-        }
-        return result;
-    }
-
-
-    /**
-     * <p>
-     * Converts an array of primitive booleans to objects.
-     * </p>
-     * <p>
-     * This method returns <code>null</code> if <code>null</code> array
-     * input.
-     * </p>
-     * 
-     * @param array
-     *            a <code>boolean</code> array
-     * @return a <code>Boolean</code> array, <code>null</code> if null array
-     *         input
-     */
-    public static Boolean[] toObject( boolean[] array )
-    {
-        if ( array == null )
-        {
-            return null;
-        }
-        else if ( array.length == 0 )
-        {
-            return EMPTY_BOOLEAN_OBJECT_ARRAY;
-        }
-        final Boolean[] result = new Boolean[array.length];
-        for ( int i = 0; i < array.length; i++ )
-        {
-            result[i] = ( array[i] ? Boolean.TRUE : Boolean.FALSE );
-        }
-        return result;
-    }
-
-
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Checks if an array of Objects is empty or <code>null</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to test
-     * @return <code>true</code> if the array is empty or <code>null</code>
-     * @since 2.1
-     */
-    public static boolean isEmpty( Object[] array )
-    {
-        if ( array == null || array.length == 0 )
-        {
-            return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * <p>
-     * Checks if an array of primitive longs is empty or <code>null</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to test
-     * @return <code>true</code> if the array is empty or <code>null</code>
-     * @since 2.1
-     */
-    public static boolean isEmpty( long[] array )
-    {
-        if ( array == null || array.length == 0 )
-        {
-            return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * <p>
-     * Checks if an array of primitive ints is empty or <code>null</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to test
-     * @return <code>true</code> if the array is empty or <code>null</code>
-     * @since 2.1
-     */
-    public static boolean isEmpty( int[] array )
-    {
-        if ( array == null || array.length == 0 )
-        {
-            return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * <p>
-     * Checks if an array of primitive shorts is empty or <code>null</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to test
-     * @return <code>true</code> if the array is empty or <code>null</code>
-     * @since 2.1
-     */
-    public static boolean isEmpty( short[] array )
-    {
-        if ( array == null || array.length == 0 )
-        {
-            return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * <p>
-     * Checks if an array of primitive chars is empty or <code>null</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to test
-     * @return <code>true</code> if the array is empty or <code>null</code>
-     * @since 2.1
-     */
-    public static boolean isEmpty( char[] array )
-    {
-        if ( array == null || array.length == 0 )
-        {
-            return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * <p>
-     * Checks if an array of primitive bytes is empty or <code>null</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to test
-     * @return <code>true</code> if the array is empty or <code>null</code>
-     * @since 2.1
-     */
-    public static boolean isEmpty( byte[] array )
-    {
-        if ( array == null || array.length == 0 )
-        {
-            return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * <p>
-     * Checks if an array of primitive doubles is empty or <code>null</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to test
-     * @return <code>true</code> if the array is empty or <code>null</code>
-     * @since 2.1
-     */
-    public static boolean isEmpty( double[] array )
-    {
-        if ( array == null || array.length == 0 )
-        {
-            return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * <p>
-     * Checks if an array of primitive floats is empty or <code>null</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to test
-     * @return <code>true</code> if the array is empty or <code>null</code>
-     * @since 2.1
-     */
-    public static boolean isEmpty( float[] array )
-    {
-        if ( array == null || array.length == 0 )
-        {
-            return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * <p>
-     * Checks if an array of primitive booleans is empty or <code>null</code>.
-     * </p>
-     * 
-     * @param array
-     *            the array to test
-     * @return <code>true</code> if the array is empty or <code>null</code>
-     * @since 2.1
-     */
-    public static boolean isEmpty( boolean[] array )
-    {
-        if ( array == null || array.length == 0 )
-        {
-            return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * <p>
-     * Adds all the elements of the given arrays into a new array.
-     * </p>
-     * <p>
-     * The new array contains all of the element of <code>array1</code>
-     * followed by all of the elements <code>array2</code>. When an array is
-     * returned, it is always a new array.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.addAll(null, null)     = null
-     *  ArrayUtils.addAll(array1, null)   = cloned copy of array1
-     *  ArrayUtils.addAll(null, array2)   = cloned copy of array2
-     *  ArrayUtils.addAll([], [])         = []
-     *  ArrayUtils.addAll([null], [null]) = [null, null]
-     *  ArrayUtils.addAll([&quot;a&quot;, &quot;b&quot;, &quot;c&quot;], [&quot;1&quot;, &quot;2&quot;, &quot;3&quot;]) = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;1&quot;, &quot;2&quot;, &quot;3&quot;]
-     * </pre>
-     * 
-     * @param array1
-     *            the first array whose elements are added to the new array, may
-     *            be <code>null</code>
-     * @param array2
-     *            the second array whose elements are added to the new array,
-     *            may be <code>null</code>
-     * @return The new array, <code>null</code> if <code>null</code> array
-     *         inputs. The type of the new array is the type of the first array.
-     * @since 2.1
-     */
-    public static Object[] addAll( Object[] array1, Object[] array2 )
-    {
-        if ( array1 == null )
-        {
-            return clone( array2 );
-        }
-        else if ( array2 == null )
-        {
-            return clone( array1 );
-        }
-        else
-        {
-            Object[] joinedArray = ( Object[] ) Array.newInstance( array1.getClass().getComponentType(), array1.length
-                + array2.length );
-            System.arraycopy( array1, 0, joinedArray, 0, array1.length );
-            System.arraycopy( array2, 0, joinedArray, array1.length, array2.length );
-            return joinedArray;
-        }
-    }
-
-
-    /**
-     * <p>
-     * Copies the given array and adds the given element at the end of the new
-     * array.
-     * </p>
-     * <p>
-     * The new array contains the same elements of the input array plus the
-     * given element in the last position. The component type of the new array
-     * is the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, a new one element array is
-     * returned whose component type is the same as the element.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.add(null, null)      = [null]
-     *  ArrayUtils.add(null, &quot;a&quot;)       = [&quot;a&quot;]
-     *  ArrayUtils.add([&quot;a&quot;], null)     = [&quot;a&quot;, null]
-     *  ArrayUtils.add([&quot;a&quot;], &quot;b&quot;)      = [&quot;a&quot;, &quot;b&quot;]
-     *  ArrayUtils.add([&quot;a&quot;, &quot;b&quot;], &quot;c&quot;) = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]
-     * </pre>
-     * 
-     * @param array
-     *            the array to "add" the element to, may be <code>null</code>
-     * @param element
-     *            the object to add
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static Object[] add( Object[] array, Object element )
-    {
-        Object newArray = copyArrayGrow1( array, element != null ? element.getClass() : Object.class );
-        Array.set( newArray, lastIndex( newArray ), element );
-        return ( Object[] ) newArray;
-    }
-
-
-    /**
-     * <p>
-     * Copies the given array and adds the given element at the end of the new
-     * array.
-     * </p>
-     * <p>
-     * The new array contains the same elements of the input array plus the
-     * given element in the last position. The component type of the new array
-     * is the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, a new one element array is
-     * returned whose component type is the same as the element.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.add(null, true)          = [true]
-     *  ArrayUtils.add([true], false)       = [true, false]
-     *  ArrayUtils.add([true, false], true) = [true, false, true]
-     * </pre>
-     * 
-     * @param array
-     *            the array to copy and add the element to, may be
-     *            <code>null</code>
-     * @param element
-     *            the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static boolean[] add( boolean[] array, boolean element )
-    {
-        boolean[] newArray = ( boolean[] ) copyArrayGrow1( array, Boolean.TYPE );
-        newArray[lastIndex( newArray )] = element;
-        return newArray;
-    }
-
-
-    /**
-     * <p>
-     * Copies the given array and adds the given element at the end of the new
-     * array.
-     * </p>
-     * <p>
-     * The new array contains the same elements of the input array plus the
-     * given element in the last position. The component type of the new array
-     * is the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, a new one element array is
-     * returned whose component type is the same as the element.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.add(null, 0)   = [0]
-     *  ArrayUtils.add([1], 0)    = [1, 0]
-     *  ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to copy and add the element to, may be
-     *            <code>null</code>
-     * @param element
-     *            the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static byte[] add( byte[] array, byte element )
-    {
-        byte[] newArray = ( byte[] ) copyArrayGrow1( array, Byte.TYPE );
-        newArray[lastIndex( newArray )] = element;
-        return newArray;
-    }
-
-
-    /**
-     * <p>
-     * Copies the given array and adds the given element at the end of the new
-     * array.
-     * </p>
-     * <p>
-     * The new array contains the same elements of the input array plus the
-     * given element in the last position. The component type of the new array
-     * is the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, a new one element array is
-     * returned whose component type is the same as the element.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.add(null, '0')       = ['0']
-     *  ArrayUtils.add(['1'], '0')      = ['1', '0']
-     *  ArrayUtils.add(['1', '0'], '1') = ['1', '0', '1']
-     * </pre>
-     * 
-     * @param array
-     *            the array to copy and add the element to, may be
-     *            <code>null</code>
-     * @param element
-     *            the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static char[] add( char[] array, char element )
-    {
-        char[] newArray = ( char[] ) copyArrayGrow1( array, Character.TYPE );
-        newArray[lastIndex( newArray )] = element;
-        return newArray;
-    }
-
-
-    /**
-     * <p>
-     * Copies the given array and adds the given element at the end of the new
-     * array.
-     * </p>
-     * <p>
-     * The new array contains the same elements of the input array plus the
-     * given element in the last position. The component type of the new array
-     * is the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, a new one element array is
-     * returned whose component type is the same as the element.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.add(null, 0)   = [0]
-     *  ArrayUtils.add([1], 0)    = [1, 0]
-     *  ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to copy and add the element to, may be
-     *            <code>null</code>
-     * @param element
-     *            the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static double[] add( double[] array, double element )
-    {
-        double[] newArray = ( double[] ) copyArrayGrow1( array, Double.TYPE );
-        newArray[lastIndex( newArray )] = element;
-        return newArray;
-    }
-
-
-    /**
-     * <p>
-     * Copies the given array and adds the given element at the end of the new
-     * array.
-     * </p>
-     * <p>
-     * The new array contains the same elements of the input array plus the
-     * given element in the last position. The component type of the new array
-     * is the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, a new one element array is
-     * returned whose component type is the same as the element.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.add(null, 0)   = [0]
-     *  ArrayUtils.add([1], 0)    = [1, 0]
-     *  ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to copy and add the element to, may be
-     *            <code>null</code>
-     * @param element
-     *            the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static float[] add( float[] array, float element )
-    {
-        float[] newArray = ( float[] ) copyArrayGrow1( array, Float.TYPE );
-        newArray[lastIndex( newArray )] = element;
-        return newArray;
-    }
-
-
-    /**
-     * <p>
-     * Copies the given array and adds the given element at the end of the new
-     * array.
-     * </p>
-     * <p>
-     * The new array contains the same elements of the input array plus the
-     * given element in the last position. The component type of the new array
-     * is the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, a new one element array is
-     * returned whose component type is the same as the element.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.add(null, 0)   = [0]
-     *  ArrayUtils.add([1], 0)    = [1, 0]
-     *  ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to copy and add the element to, may be
-     *            <code>null</code>
-     * @param element
-     *            the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static int[] add( int[] array, int element )
-    {
-        int[] newArray = ( int[] ) copyArrayGrow1( array, Integer.TYPE );
-        newArray[lastIndex( newArray )] = element;
-        return newArray;
-    }
-
-
-    /**
-     * <p>
-     * Copies the given array and adds the given element at the end of the new
-     * array.
-     * </p>
-     * <p>
-     * The new array contains the same elements of the input array plus the
-     * given element in the last position. The component type of the new array
-     * is the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, a new one element array is
-     * returned whose component type is the same as the element.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.add(null, 0)   = [0]
-     *  ArrayUtils.add([1], 0)    = [1, 0]
-     *  ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to copy and add the element to, may be
-     *            <code>null</code>
-     * @param element
-     *            the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static long[] add( long[] array, long element )
-    {
-        long[] newArray = ( long[] ) copyArrayGrow1( array, Long.TYPE );
-        newArray[lastIndex( newArray )] = element;
-        return newArray;
-    }
-
-
-    /**
-     * <p>
-     * Copies the given array and adds the given element at the end of the new
-     * array.
-     * </p>
-     * <p>
-     * The new array contains the same elements of the input array plus the
-     * given element in the last position. The component type of the new array
-     * is the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, a new one element array is
-     * returned whose component type is the same as the element.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.add(null, 0)   = [0]
-     *  ArrayUtils.add([1], 0)    = [1, 0]
-     *  ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to copy and add the element to, may be
-     *            <code>null</code>
-     * @param element
-     *            the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static short[] add( short[] array, short element )
-    {
-        short[] newArray = ( short[] ) copyArrayGrow1( array, Short.TYPE );
-        newArray[lastIndex( newArray )] = element;
-        return newArray;
-    }
-
-
-    /**
-     * Returns a copy of the given array of size 1 greater than the argument.
-     * The last value of the array is left to the default value.
-     * 
-     * @param array
-     *            The array to copy, must not be <code>null</code>.
-     * @param newArrayComponentType
-     *            If <code>array</code> is <code>null</code>, create a size
-     *            1 array of this type.
-     * @return A new copy of the array of size 1 greater than the input.
-     */
-    private static Object copyArrayGrow1( Object array, Class<?> newArrayComponentType )
-    {
-        if ( array != null )
-        {
-            int arrayLength = Array.getLength( array );
-            Object newArray = Array.newInstance( array.getClass().getComponentType(), arrayLength + 1 );
-            System.arraycopy( array, 0, newArray, 0, arrayLength );
-            return newArray;
-        }
-        else
-        {
-            return Array.newInstance( newArrayComponentType, 1 );
-        }
-    }
-
-
-    /**
-     * <p>
-     * Inserts the specified element at the specified position in the array.
-     * Shifts the element currently at that position (if any) and any subsequent
-     * elements to the right (adds one to their indices).
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * plus the given element on the specified position. The component type of
-     * the returned array is always the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, a new one element array is
-     * returned whose component type is the same as the element.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.add(null, 0, null)      = [null]
-     *  ArrayUtils.add(null, 0, &quot;a&quot;)       = [&quot;a&quot;]
-     *  ArrayUtils.add([&quot;a&quot;], 1, null)     = [&quot;a&quot;, null]
-     *  ArrayUtils.add([&quot;a&quot;], 1, &quot;b&quot;)      = [&quot;a&quot;, &quot;b&quot;]
-     *  ArrayUtils.add([&quot;a&quot;, &quot;b&quot;], 3, &quot;c&quot;) = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]
-     * </pre>
-     * 
-     * @param array
-     *            the array to add the element to, may be <code>null</code>
-     * @param index
-     *            the position of the new object
-     * @param element
-     *            the object to add
-     * @return A new array containing the existing elements and the new element
-     * @throws IndexOutOfBoundsException
-     *             if the index is out of range (index < 0 || index >
-     *             array.length).
-     */
-    public static Object[] add( Object[] array, int index, Object element )
-    {
-        if ( array == null )
-        {
-            if ( index != 0 )
-            {
-                throw new IndexOutOfBoundsException( I18n.err( I18n.ERR_04338, index ,0 ) );
-            }
-            Object joinedArray = Array.newInstance( element != null ? element.getClass() : Object.class, 1 );
-            Array.set( joinedArray, 0, element );
-            return ( Object[] ) joinedArray;
-        }
-        int length = array.length;
-        if ( index > length || index < 0 )
-        {
-            throw new IndexOutOfBoundsException( I18n.err( I18n.ERR_04338, index, length ) );
-        }
-        Object result = Array.newInstance( array.getClass().getComponentType(), length + 1 );
-        System.arraycopy( array, 0, result, 0, index );
-        Array.set( result, index, element );
-        if ( index < length )
-        {
-            System.arraycopy( array, index, result, index + 1, length - index );
-        }
-        return ( Object[] ) result;
-    }
-
-
-    /**
-     * <p>
-     * Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (substracts one from
-     * their indices).
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the element on the specified position. The component type of the
-     * returned array is always the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.remove([&quot;a&quot;], 0)           = []
-     *  ArrayUtils.remove([&quot;a&quot;, &quot;b&quot;], 0)      = [&quot;b&quot;]
-     *  ArrayUtils.remove([&quot;a&quot;, &quot;b&quot;], 1)      = [&quot;a&quot;]
-     *  ArrayUtils.remove([&quot;a&quot;, &quot;b&quot;, &quot;c&quot;], 1) = [&quot;a&quot;, &quot;c&quot;]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may not be
-     *            <code>null</code>
-     * @param index
-     *            the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException
-     *             if the index is out of range (index < 0 || index >=
-     *             array.length), or if the array is <code>null</code>.
-     * @since 2.1
-     */
-    public static Object[] remove( Object[] array, int index )
-    {
-        return ( Object[] ) remove( ( Object ) array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the first occurrence of the specified element from the specified
-     * array. All subsequent elements are shifted to the left (substracts one
-     * from their indices). If the array doesn't contains such an element, no
-     * elements are removed from the array.
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the first occurrence of the specified element. The component type
-     * of the returned array is always the same as that of the input array.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.removeElement(null, &quot;a&quot;)            = null
-     *  ArrayUtils.removeElement([], &quot;a&quot;)              = []
-     *  ArrayUtils.removeElement([&quot;a&quot;], &quot;b&quot;)           = [&quot;a&quot;]
-     *  ArrayUtils.removeElement([&quot;a&quot;, &quot;b&quot;], &quot;a&quot;)      = [&quot;b&quot;]
-     *  ArrayUtils.removeElement([&quot;a&quot;, &quot;b&quot;, &quot;a&quot;], &quot;a&quot;) = [&quot;b&quot;, &quot;a&quot;]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may be <code>null</code>
-     * @param element
-     *            the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static Object[] removeElement( Object[] array, Object element )
-    {
-        int index = indexOf( array, element );
-        if ( index == -1 )
-        {
-            return clone( array );
-        }
-        return remove( array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (substracts one from
-     * their indices).
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the element on the specified position. The component type of the
-     * returned array is always the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.remove([true], 0)              = []
-     *  ArrayUtils.remove([true, false], 0)       = [false]
-     *  ArrayUtils.remove([true, false], 1)       = [true]
-     *  ArrayUtils.remove([true, true, false], 1) = [true, false]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may not be
-     *            <code>null</code>
-     * @param index
-     *            the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException
-     *             if the index is out of range (index < 0 || index >=
-     *             array.length), or if the array is <code>null</code>.
-     * @since 2.1
-     */
-    public static boolean[] remove( boolean[] array, int index )
-    {
-        return ( boolean[] ) remove( ( Object ) array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the first occurrence of the specified element from the specified
-     * array. All subsequent elements are shifted to the left (substracts one
-     * from their indices). If the array doesn't contains such an element, no
-     * elements are removed from the array.
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the first occurrence of the specified element. The component type
-     * of the returned array is always the same as that of the input array.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.removeElement(null, true)                = null
-     *  ArrayUtils.removeElement([], true)                  = []
-     *  ArrayUtils.removeElement([true], false)             = [true]
-     *  ArrayUtils.removeElement([true, false], false)      = [true]
-     *  ArrayUtils.removeElement([true, false, true], true) = [false, true]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may be <code>null</code>
-     * @param element
-     *            the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static boolean[] removeElement( boolean[] array, boolean element )
-    {
-        int index = indexOf( array, element );
-        if ( index == -1 )
-        {
-            return clone( array );
-        }
-        return remove( array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (substracts one from
-     * their indices).
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the element on the specified position. The component type of the
-     * returned array is always the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.remove([1], 0)          = []
-     *  ArrayUtils.remove([1, 0], 0)       = [0]
-     *  ArrayUtils.remove([1, 0], 1)       = [1]
-     *  ArrayUtils.remove([1, 0, 1], 1)    = [1, 1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may not be
-     *            <code>null</code>
-     * @param index
-     *            the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException
-     *             if the index is out of range (index < 0 || index >=
-     *             array.length), or if the array is <code>null</code>.
-     * @since 2.1
-     */
-    public static byte[] remove( byte[] array, int index )
-    {
-        return ( byte[] ) remove( ( Object ) array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the first occurrence of the specified element from the specified
-     * array. All subsequent elements are shifted to the left (substracts one
-     * from their indices). If the array doesn't contains such an element, no
-     * elements are removed from the array.
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the first occurrence of the specified element. The component type
-     * of the returned array is always the same as that of the input array.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.removeElement(null, 1)        = null
-     *  ArrayUtils.removeElement([], 1)          = []
-     *  ArrayUtils.removeElement([1], 0)         = [1]
-     *  ArrayUtils.removeElement([1, 0], 0)      = [1]
-     *  ArrayUtils.removeElement([1, 0, 1], 1)   = [0, 1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may be <code>null</code>
-     * @param element
-     *            the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static byte[] removeElement( byte[] array, byte element )
-    {
-        int index = indexOf( array, element );
-        if ( index == -1 )
-        {
-            return clone( array );
-        }
-        return remove( array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (substracts one from
-     * their indices).
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the element on the specified position. The component type of the
-     * returned array is always the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.remove(['a'], 0)           = []
-     *  ArrayUtils.remove(['a', 'b'], 0)      = ['b']
-     *  ArrayUtils.remove(['a', 'b'], 1)      = ['a']
-     *  ArrayUtils.remove(['a', 'b', 'c'], 1) = ['a', 'c']
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may not be
-     *            <code>null</code>
-     * @param index
-     *            the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException
-     *             if the index is out of range (index < 0 || index >=
-     *             array.length), or if the array is <code>null</code>.
-     * @since 2.1
-     */
-    public static char[] remove( char[] array, int index )
-    {
-        return ( char[] ) remove( ( Object ) array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the first occurrence of the specified element from the specified
-     * array. All subsequent elements are shifted to the left (substracts one
-     * from their indices). If the array doesn't contains such an element, no
-     * elements are removed from the array.
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the first occurrence of the specified element. The component type
-     * of the returned array is always the same as that of the input array.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.removeElement(null, 'a')            = null
-     *  ArrayUtils.removeElement([], 'a')              = []
-     *  ArrayUtils.removeElement(['a'], 'b')           = ['a']
-     *  ArrayUtils.removeElement(['a', 'b'], 'a')      = ['b']
-     *  ArrayUtils.removeElement(['a', 'b', 'a'], 'a') = ['b', 'a']
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may be <code>null</code>
-     * @param element
-     *            the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static char[] removeElement( char[] array, char element )
-    {
-        int index = indexOf( array, element );
-        if ( index == -1 )
-        {
-            return clone( array );
-        }
-        return remove( array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (substracts one from
-     * their indices).
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the element on the specified position. The component type of the
-     * returned array is always the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.remove([1.1], 0)           = []
-     *  ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
-     *  ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
-     *  ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may not be
-     *            <code>null</code>
-     * @param index
-     *            the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException
-     *             if the index is out of range (index < 0 || index >=
-     *             array.length), or if the array is <code>null</code>.
-     * @since 2.1
-     */
-    public static double[] remove( double[] array, int index )
-    {
-        return ( double[] ) remove( ( Object ) array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the first occurrence of the specified element from the specified
-     * array. All subsequent elements are shifted to the left (substracts one
-     * from their indices). If the array doesn't contains such an element, no
-     * elements are removed from the array.
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the first occurrence of the specified element. The component type
-     * of the returned array is always the same as that of the input array.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.removeElement(null, 1.1)            = null
-     *  ArrayUtils.removeElement([], 1.1)              = []
-     *  ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
-     *  ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
-     *  ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may be <code>null</code>
-     * @param element
-     *            the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static double[] removeElement( double[] array, double element )
-    {
-        int index = indexOf( array, element );
-        if ( index == -1 )
-        {
-            return clone( array );
-        }
-        return remove( array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (substracts one from
-     * their indices).
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the element on the specified position. The component type of the
-     * returned array is always the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.remove([1.1], 0)           = []
-     *  ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
-     *  ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
-     *  ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may not be
-     *            <code>null</code>
-     * @param index
-     *            the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException
-     *             if the index is out of range (index < 0 || index >=
-     *             array.length), or if the array is <code>null</code>.
-     * @since 2.1
-     */
-    public static float[] remove( float[] array, int index )
-    {
-        return ( float[] ) remove( ( Object ) array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the first occurrence of the specified element from the specified
-     * array. All subsequent elements are shifted to the left (substracts one
-     * from their indices). If the array doesn't contains such an element, no
-     * elements are removed from the array.
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the first occurrence of the specified element. The component type
-     * of the returned array is always the same as that of the input array.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.removeElement(null, 1.1)            = null
-     *  ArrayUtils.removeElement([], 1.1)              = []
-     *  ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
-     *  ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
-     *  ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may be <code>null</code>
-     * @param element
-     *            the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static float[] removeElement( float[] array, float element )
-    {
-        int index = indexOf( array, element );
-        if ( index == -1 )
-        {
-            return clone( array );
-        }
-        return remove( array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (substracts one from
-     * their indices).
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the element on the specified position. The component type of the
-     * returned array is always the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.remove([1], 0)         = []
-     *  ArrayUtils.remove([2, 6], 0)      = [6]
-     *  ArrayUtils.remove([2, 6], 1)      = [2]
-     *  ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may not be
-     *            <code>null</code>
-     * @param index
-     *            the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException
-     *             if the index is out of range (index < 0 || index >=
-     *             array.length), or if the array is <code>null</code>.
-     * @since 2.1
-     */
-    public static int[] remove( int[] array, int index )
-    {
-        return ( int[] ) remove( ( Object ) array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the first occurrence of the specified element from the specified
-     * array. All subsequent elements are shifted to the left (substracts one
-     * from their indices). If the array doesn't contains such an element, no
-     * elements are removed from the array.
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the first occurrence of the specified element. The component type
-     * of the returned array is always the same as that of the input array.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.removeElement(null, 1)      = null
-     *  ArrayUtils.removeElement([], 1)        = []
-     *  ArrayUtils.removeElement([1], 2)       = [1]
-     *  ArrayUtils.removeElement([1, 3], 1)    = [3]
-     *  ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may be <code>null</code>
-     * @param element
-     *            the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static int[] removeElement( int[] array, int element )
-    {
-        int index = indexOf( array, element );
-        if ( index == -1 )
-        {
-            return clone( array );
-        }
-        return remove( array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (substracts one from
-     * their indices).
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the element on the specified position. The component type of the
-     * returned array is always the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.remove([1], 0)         = []
-     *  ArrayUtils.remove([2, 6], 0)      = [6]
-     *  ArrayUtils.remove([2, 6], 1)      = [2]
-     *  ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may not be
-     *            <code>null</code>
-     * @param index
-     *            the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException
-     *             if the index is out of range (index < 0 || index >=
-     *             array.length), or if the array is <code>null</code>.
-     * @since 2.1
-     */
-    public static long[] remove( long[] array, int index )
-    {
-        return ( long[] ) remove( ( Object ) array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the first occurrence of the specified element from the specified
-     * array. All subsequent elements are shifted to the left (substracts one
-     * from their indices). If the array doesn't contains such an element, no
-     * elements are removed from the array.
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the first occurrence of the specified element. The component type
-     * of the returned array is always the same as that of the input array.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.removeElement(null, 1)      = null
-     *  ArrayUtils.removeElement([], 1)        = []
-     *  ArrayUtils.removeElement([1], 2)       = [1]
-     *  ArrayUtils.removeElement([1, 3], 1)    = [3]
-     *  ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may be <code>null</code>
-     * @param element
-     *            the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static long[] removeElement( long[] array, long element )
-    {
-        int index = indexOf( array, element );
-        if ( index == -1 )
-        {
-            return clone( array );
-        }
-        return remove( array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (substracts one from
-     * their indices).
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the element on the specified position. The component type of the
-     * returned array is always the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.remove([1], 0)         = []
-     *  ArrayUtils.remove([2, 6], 0)      = [6]
-     *  ArrayUtils.remove([2, 6], 1)      = [2]
-     *  ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may not be
-     *            <code>null</code>
-     * @param index
-     *            the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException
-     *             if the index is out of range (index < 0 || index >=
-     *             array.length), or if the array is <code>null</code>.
-     * @since 2.1
-     */
-    public static short[] remove( short[] array, int index )
-    {
-        return ( short[] ) remove( ( Object ) array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the first occurrence of the specified element from the specified
-     * array. All subsequent elements are shifted to the left (substracts one
-     * from their indices). If the array doesn't contains such an element, no
-     * elements are removed from the array.
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the first occurrence of the specified element. The component type
-     * of the returned array is always the same as that of the input array.
-     * </p>
-     * 
-     * <pre>
-     *  ArrayUtils.removeElement(null, 1)      = null
-     *  ArrayUtils.removeElement([], 1)        = []
-     *  ArrayUtils.removeElement([1], 2)       = [1]
-     *  ArrayUtils.removeElement([1, 3], 1)    = [3]
-     *  ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
-     * </pre>
-     * 
-     * @param array
-     *            the array to remove the element from, may be <code>null</code>
-     * @param element
-     *            the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static short[] removeElement( short[] array, short element )
-    {
-        int index = indexOf( array, element );
-        if ( index == -1 )
-        {
-            return clone( array );
-        }
-        return remove( array, index );
-    }
-
-
-    /**
-     * <p>
-     * Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (substracts one from
-     * their indices).
-     * </p>
-     * <p>
-     * This method returns a new array with the same elements of the input array
-     * except the element on the specified position. The component type of the
-     * returned array is always the same as that of the input array.
-     * </p>
-     * <p>
-     * If the input array is <code>null</code>, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.
-     * </p>
-     * 
-     * @param array
-     *            the array to remove the element from, may not be
-     *            <code>null</code>
-     * @param index
-     *            the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException
-     *             if the index is out of range (index < 0 || index >=
-     *             array.length), or if the array is <code>null</code>.
-     * @since 2.1
-     */
-    private static Object remove( Object array, int index )
-    {
-        int length = getLength( array );
-        if ( index < 0 || index >= length )
-        {
-            throw new IndexOutOfBoundsException( I18n.err( I18n.ERR_04338, index, length ) );
-        }
-
-        Object result = Array.newInstance( array.getClass().getComponentType(), length - 1 );
-        System.arraycopy( array, 0, result, 0, index );
-        if ( index < length - 1 )
-        {
-            System.arraycopy( array, index + 1, result, index, length - index - 1 );
-        }
-
-        return result;
-    }
-
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java
index 046836c..a43585f 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java
@@ -31,8 +31,8 @@
 import javax.naming.directory.Attributes;
 import javax.naming.directory.BasicAttribute;
 import javax.naming.directory.BasicAttributes;
-import javax.naming.directory.InvalidAttributeIdentifierException;
 
+import org.apache.commons.lang.ArrayUtils;
 import org.apache.directory.shared.i18n.I18n;
 import org.apache.directory.shared.ldap.entry.DefaultEntry;
 import org.apache.directory.shared.ldap.entry.DefaultEntryAttribute;
@@ -357,12 +357,9 @@
                 {
                     Object value = values.nextElement();
     
-                    if ( value instanceof byte[] )
+                    if ( value instanceof byte[] && ArrayUtils.isEquals( comparedBytes, value ) )
                     {
-                        if ( ArrayUtils.isEquals( comparedBytes, value ) )
-                        {
-                            return true;
-                        }
+                        return true;
                     }
                 }
             }
@@ -405,12 +402,9 @@
                 {
                     Object attrVal = attrVals.nextElement();
 
-                    if ( attrVal instanceof String )
+                    if ( attrVal instanceof String &&  strVal.equalsIgnoreCase( ( String ) attrVal ) )
                     {
-                        if ( strVal.equalsIgnoreCase( ( String ) attrVal ) )
-                        {
-                            return true;
-                        }
+                        return true;
                     }
                 }
             }
@@ -424,13 +418,9 @@
                 {
                     Object attrVal = attrVals.nextElement();
 
-                    if ( attrVal instanceof byte[] )
+                    if ( attrVal instanceof byte[]  &&  Arrays.equals( ( byte[] ) attrVal, valueBytes ) )
                     {
-                        if ( Arrays.equals( ( byte[] ) attrVal, valueBytes ) )
-                        {
-                            return true;
-                        }
-
+                        return true;
                     }
                 }
             }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/BooleanUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/BooleanUtils.java
deleted file mode 100644
index df5e9e7..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/BooleanUtils.java
+++ /dev/null
@@ -1,1179 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-import org.apache.directory.shared.i18n.I18n;
-
-
-/**
- * <p>
- * Operations on boolean primitives and Boolean objects.
- * </p>
- * <p>
- * This class tries to handle <code>null</code> input gracefully. An exception
- * will not be thrown for a <code>null</code> input. Each method documents its
- * behaviour in more detail.
- * </p>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @since 2.0
- * @version $Id$
- */
-public class BooleanUtils
-{
-    private static final Integer INTEGER_ZERO = Integer.valueOf( 0 );
-
-    private static final Integer INTEGER_ONE = Integer.valueOf( 1 );
-
-
-    /**
-     * <p>
-     * <code>BooleanUtils</code> instances should NOT be constructed in
-     * standard programming. Instead, the class should be used as
-     * <code>BooleanUtils.toBooleanObject(true);</code>.
-     * </p>
-     * <p>
-     * This constructor is public to permit tools that require a JavaBean
-     * instance to operate.
-     * </p>
-     */
-    public BooleanUtils()
-    {
-    }
-
-
-    // Boolean utilities
-    // --------------------------------------------------------------------------
-    /**
-     * <p>
-     * Negates the specified boolean.
-     * </p>
-     * <p>
-     * If <code>null</code> is passed in, <code>null</code> will be
-     * returned.
-     * </p>
-     * 
-     * <pre>
-     * BooleanUtils.negate( Boolean.TRUE ) = Boolean.FALSE;
-     * BooleanUtils.negate( Boolean.FALSE ) = Boolean.TRUE;
-     * BooleanUtils.negate( null ) = null;
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to negate, may be null
-     * @return the negated Boolean, or <code>null</code> if <code>null</code>
-     *         input
-     */
-    public static Boolean negate( Boolean bool )
-    {
-        if ( bool == null )
-        {
-            return null;
-        }
-        return ( bool.booleanValue() ? Boolean.FALSE : Boolean.TRUE );
-    }
-
-
-    // boolean Boolean methods
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Boolean factory that avoids creating new Boolean objecs all the time.
-     * </p>
-     * <p>
-     * This method was added to JDK1.4 but is available here for earlier JDKs.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBooleanObject(false) = Boolean.FALSE
-     *    BooleanUtils.toBooleanObject(true)  = Boolean.TRUE
-     * </pre>
-     * 
-     * @param bool
-     *            the boolean to convert
-     * @return Boolean.TRUE or Boolean.FALSE as appropriate
-     */
-    public static Boolean toBooleanObject( boolean bool )
-    {
-        return ( bool ? Boolean.TRUE : Boolean.FALSE );
-    }
-
-
-    /**
-     * <p>
-     * Converts a Boolean to a boolean handling <code>null</code> by returning
-     * <code>false</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBoolean(Boolean.TRUE)  = true
-     *    BooleanUtils.toBoolean(Boolean.FALSE) = false
-     *    BooleanUtils.toBoolean(null)          = false
-     * </pre>
-     * 
-     * @param bool
-     *            the boolean to convert
-     * @return <code>true</code> or <code>false</code>, <code>null</code>
-     *         returns <code>false</code>
-     */
-    public static boolean toBoolean( Boolean bool )
-    {
-        if ( bool == null )
-        {
-            return false;
-        }
-        return ( bool.booleanValue() ? true : false );
-    }
-
-
-    /**
-     * <p>
-     * Converts a Boolean to a boolean handling <code>null</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, false) = true
-     *    BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, true) = false
-     *    BooleanUtils.toBooleanDefaultIfNull(null, true)          = true
-     * </pre>
-     * 
-     * @param bool
-     *            the boolean to convert
-     * @param valueIfNull
-     *            the boolean value to return if <code>null</code>
-     * @return <code>true</code> or <code>false</code>
-     */
-    public static boolean toBooleanDefaultIfNull( Boolean bool, boolean valueIfNull )
-    {
-        if ( bool == null )
-        {
-            return valueIfNull;
-        }
-        return ( bool.booleanValue() ? true : false );
-    }
-
-
-    // Integer to Boolean methods
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts an int to a boolean using the convention that <code>zero</code>
-     * is <code>false</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBoolean(0) = false
-     *    BooleanUtils.toBoolean(1) = true
-     *    BooleanUtils.toBoolean(2) = true
-     * </pre>
-     * 
-     * @param value
-     *            the int to convert
-     * @return <code>true</code> if non-zero, <code>false</code> if zero
-     */
-    public static boolean toBoolean( int value )
-    {
-        return ( value == 0 ? false : true );
-    }
-
-
-    /**
-     * <p>
-     * Converts an int to a Boolean using the convention that <code>zero</code>
-     * is <code>false</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBoolean(0) = Boolean.FALSE
-     *    BooleanUtils.toBoolean(1) = Boolean.TRUE
-     *    BooleanUtils.toBoolean(2) = Boolean.TRUE
-     * </pre>
-     * 
-     * @param value
-     *            the int to convert
-     * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
-     *         <code>null</code> if <code>null</code>
-     */
-    public static Boolean toBooleanObject( int value )
-    {
-        return ( value == 0 ? Boolean.FALSE : Boolean.TRUE );
-    }
-
-
-    /**
-     * <p>
-     * Converts an Integer to a Boolean using the convention that
-     * <code>zero</code> is <code>false</code>.
-     * </p>
-     * <p>
-     * <code>null</code> will be converted to <code>null</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBoolean(new Integer(0))    = Boolean.FALSE
-     *    BooleanUtils.toBoolean(new Integer(1))    = Boolean.TRUE
-     *    BooleanUtils.toBoolean(new Integer(null)) = null
-     * </pre>
-     * 
-     * @param value
-     *            the Integer to convert
-     * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
-     *         <code>null</code> if <code>null</code> input
-     */
-    public static Boolean toBooleanObject( Integer value )
-    {
-        if ( value == null )
-        {
-            return null;
-        }
-        return ( value.intValue() == 0 ? Boolean.FALSE : Boolean.TRUE );
-    }
-
-
-    /**
-     * <p>
-     * Converts an int to a boolean specifying the conversion values.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBoolean(0, 1, 0) = false
-     *    BooleanUtils.toBoolean(1, 1, 0) = true
-     *    BooleanUtils.toBoolean(2, 1, 2) = false
-     *    BooleanUtils.toBoolean(2, 2, 0) = true
-     * </pre>
-     * 
-     * @param value
-     *            the Integer to convert
-     * @param trueValue
-     *            the value to match for <code>true</code>
-     * @param falseValue
-     *            the value to match for <code>false</code>
-     * @return <code>true</code> or <code>false</code>
-     * @throws IllegalArgumentException
-     *             if no match
-     */
-    public static boolean toBoolean( int value, int trueValue, int falseValue )
-    {
-        if ( value == trueValue )
-        {
-            return true;
-        }
-        else if ( value == falseValue )
-        {
-            return false;
-        }
-        // no match
-        throw new IllegalArgumentException( I18n.err( I18n.ERR_04349 ) );
-    }
-
-
-    /**
-     * <p>
-     * Converts an Integer to a boolean specifying the conversion values.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBoolean(new Integer(0), new Integer(1), new Integer(0)) = false
-     *    BooleanUtils.toBoolean(new Integer(1), new Integer(1), new Integer(0)) = true
-     *    BooleanUtils.toBoolean(new Integer(2), new Integer(1), new Integer(2)) = false
-     *    BooleanUtils.toBoolean(new Integer(2), new Integer(2), new Integer(0)) = true
-     *    BooleanUtils.toBoolean(null, null, new Integer(0))                     = true
-     * </pre>
-     * 
-     * @param value
-     *            the Integer to convert
-     * @param trueValue
-     *            the value to match for <code>true</code>, may be
-     *            <code>null</code>
-     * @param falseValue
-     *            the value to match for <code>false</code>, may be
-     *            <code>null</code>
-     * @return <code>true</code> or <code>false</code>
-     * @throws IllegalArgumentException
-     *             if no match
-     */
-    public static boolean toBoolean( Integer value, Integer trueValue, Integer falseValue )
-    {
-        if ( value == null )
-        {
-            if ( trueValue == null )
-            {
-                return true;
-            }
-            else if ( falseValue == null )
-            {
-                return false;
-            }
-        }
-        else if ( value.equals( trueValue ) )
-        {
-            return true;
-        }
-        else if ( value.equals( falseValue ) )
-        {
-            return false;
-        }
-        // no match
-        throw new IllegalArgumentException( I18n.err( I18n.ERR_04349 ) );
-    }
-
-
-    /**
-     * <p>
-     * Converts an int to a Boolean specifying the conversion values.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBooleanObject(0, 0, 2, 3) = Boolean.TRUE
-     *    BooleanUtils.toBooleanObject(2, 1, 2, 3) = Boolean.FALSE
-     *    BooleanUtils.toBooleanObject(3, 1, 2, 3) = null
-     * </pre>
-     * 
-     * @param value
-     *            the Integer to convert
-     * @param trueValue
-     *            the value to match for <code>true</code>
-     * @param falseValue
-     *            the value to match for <code>false</code>
-     * @param nullValue
-     *            the value to to match for <code>null</code>
-     * @return Boolean.TRUE, Boolean.FALSE, or <code>null</code>
-     * @throws IllegalArgumentException
-     *             if no match
-     */
-    public static Boolean toBooleanObject( int value, int trueValue, int falseValue, int nullValue )
-    {
-        if ( value == trueValue )
-        {
-            return Boolean.TRUE;
-        }
-        else if ( value == falseValue )
-        {
-            return Boolean.FALSE;
-        }
-        else if ( value == nullValue )
-        {
-            return null;
-        }
-        // no match
-        throw new IllegalArgumentException( I18n.err( I18n.ERR_04349 ) );
-    }
-
-
-    /**
-     * <p>
-     * Converts an Integer to a Boolean specifying the conversion values.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBooleanObject(new Integer(0), new Integer(0), new Integer(2), new Integer(3)) = Boolean.TRUE
-     *    BooleanUtils.toBooleanObject(new Integer(2), new Integer(1), new Integer(2), new Integer(3)) = Boolean.FALSE
-     *    BooleanUtils.toBooleanObject(new Integer(3), new Integer(1), new Integer(2), new Integer(3)) = null
-     * </pre>
-     * 
-     * @param value
-     *            the Integer to convert
-     * @param trueValue
-     *            the value to match for <code>true</code>, may be
-     *            <code>null</code>
-     * @param falseValue
-     *            the value to match for <code>false</code>, may be
-     *            <code>null</code>
-     * @param nullValue
-     *            the value to to match for <code>null</code>, may be
-     *            <code>null</code>
-     * @return Boolean.TRUE, Boolean.FALSE, or <code>null</code>
-     * @throws IllegalArgumentException
-     *             if no match
-     */
-    public static Boolean toBooleanObject( Integer value, Integer trueValue, Integer falseValue, Integer nullValue )
-    {
-        if ( value == null )
-        {
-            if ( trueValue == null )
-            {
-                return Boolean.TRUE;
-            }
-            else if ( falseValue == null )
-            {
-                return Boolean.FALSE;
-            }
-            else if ( nullValue == null )
-            {
-                return null;
-            }
-        }
-        else if ( value.equals( trueValue ) )
-        {
-            return Boolean.TRUE;
-        }
-        else if ( value.equals( falseValue ) )
-        {
-            return Boolean.FALSE;
-        }
-        else if ( value.equals( nullValue ) )
-        {
-            return null;
-        }
-        // no match
-        throw new IllegalArgumentException( I18n.err( I18n.ERR_04349 ) );
-    }
-
-
-    // Boolean to Integer methods
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts a boolean to an int using the convention that <code>zero</code>
-     * is <code>false</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toInteger(true)  = 1
-     *    BooleanUtils.toInteger(false) = 0
-     * </pre>
-     * 
-     * @param bool
-     *            the boolean to convert
-     * @return one if <code>true</code>, zero if <code>false</code>
-     */
-    public static int toInteger( boolean bool )
-    {
-        return ( bool ? 1 : 0 );
-    }
-
-
-    /**
-     * <p>
-     * Converts a boolean to an Integer using the convention that
-     * <code>zero</code> is <code>false</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toIntegerObject(true)  = new Integer(1)
-     *    BooleanUtils.toIntegerObject(false) = new Integer(0)
-     * </pre>
-     * 
-     * @param bool
-     *            the boolean to convert
-     * @return one if <code>true</code>, zero if <code>false</code>
-     */
-    public static Integer toIntegerObject( boolean bool )
-    {
-        return ( bool ? INTEGER_ONE : INTEGER_ZERO );
-    }
-
-
-    /**
-     * <p>
-     * Converts a Boolean to a Integer using the convention that
-     * <code>zero</code> is <code>false</code>.
-     * </p>
-     * <p>
-     * <code>null</code> will be converted to <code>null</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toIntegerObject(Boolean.TRUE)  = new Integer(1)
-     *    BooleanUtils.toIntegerObject(Boolean.FALSE) = new Integer(0)
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to convert
-     * @return one if Boolean.TRUE, zero if Boolean.FALSE, <code>null</code>
-     *         if <code>null</code>
-     */
-    public static Integer toIntegerObject( Boolean bool )
-    {
-        if ( bool == null )
-        {
-            return null;
-        }
-        return ( bool.booleanValue() ? INTEGER_ONE : INTEGER_ZERO );
-    }
-
-
-    /**
-     * <p>
-     * Converts a boolean to an int specifying the conversion values.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toInteger(true, 1, 0)  = 1
-     *    BooleanUtils.toInteger(false, 1, 0) = 0
-     * </pre>
-     * 
-     * @param bool
-     *            the to convert
-     * @param trueValue
-     *            the value to return if <code>true</code>
-     * @param falseValue
-     *            the value to return if <code>false</code>
-     * @return the appropriate value
-     */
-    public static int toInteger( boolean bool, int trueValue, int falseValue )
-    {
-        return ( bool ? trueValue : falseValue );
-    }
-
-
-    /**
-     * <p>
-     * Converts a Boolean to an int specifying the conversion values.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toInteger(Boolean.TRUE, 1, 0, 2)  = 1
-     *    BooleanUtils.toInteger(Boolean.FALSE, 1, 0, 2) = 0
-     *    BooleanUtils.toInteger(null, 1, 0, 2)          = 2
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to convert
-     * @param trueValue
-     *            the value to return if <code>true</code>
-     * @param falseValue
-     *            the value to return if <code>false</code>
-     * @param nullValue
-     *            the value to return if <code>null</code>
-     * @return the appropriate value
-     */
-    public static int toInteger( Boolean bool, int trueValue, int falseValue, int nullValue )
-    {
-        if ( bool == null )
-        {
-            return nullValue;
-        }
-        return ( bool.booleanValue() ? trueValue : falseValue );
-    }
-
-
-    /**
-     * <p>
-     * Converts a boolean to an Integer specifying the conversion values.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toIntegerObject(true, new Integer(1), new Integer(0))  = new Integer(1)
-     *    BooleanUtils.toIntegerObject(false, new Integer(1), new Integer(0)) = new Integer(0)
-     * </pre>
-     * 
-     * @param bool
-     *            the to convert
-     * @param trueValue
-     *            the value to return if <code>true</code>, may be
-     *            <code>null</code>
-     * @param falseValue
-     *            the value to return if <code>false</code>, may be
-     *            <code>null</code>
-     * @return the appropriate value
-     */
-    public static Integer toIntegerObject( boolean bool, Integer trueValue, Integer falseValue )
-    {
-        return ( bool ? trueValue : falseValue );
-    }
-
-
-    /**
-     * <p>
-     * Converts a Boolean to an Integer specifying the conversion values.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toIntegerObject(Boolean.TRUE, new Integer(1), new Integer(0), new Integer(2))  = new Integer(1)
-     *    BooleanUtils.toIntegerObject(Boolean.FALSE, new Integer(1), new Integer(0), new Integer(2)) = new Integer(0)
-     *    BooleanUtils.toIntegerObject(null, new Integer(1), new Integer(0), new Integer(2))          = new Integer(2)
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to convert
-     * @param trueValue
-     *            the value to return if <code>true</code>, may be
-     *            <code>null</code>
-     * @param falseValue
-     *            the value to return if <code>false</code>, may be
-     *            <code>null</code>
-     * @param nullValue
-     *            the value to return if <code>null</code>, may be
-     *            <code>null</code>
-     * @return the appropriate value
-     */
-    public static Integer toIntegerObject( Boolean bool, Integer trueValue, Integer falseValue, Integer nullValue )
-    {
-        if ( bool == null )
-        {
-            return nullValue;
-        }
-        return ( bool.booleanValue() ? trueValue : falseValue );
-    }
-
-
-    // String to Boolean methods
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts a String to a Boolean.
-     * </p>
-     * <p>
-     * <code>'true'</code>, <code>'on'</code> or <code>'yes'</code> (case
-     * insensitive) will return <code>true</code>. <code>'false'</code>,
-     * <code>'off'</code> or <code>'no'</code> (case insensitive) will
-     * return <code>false</code>. Otherwise, <code>null</code> is returned.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBooleanObject(null)    = null
-     *    BooleanUtils.toBooleanObject(&quot;true&quot;)  = Boolean.TRUE
-     *    BooleanUtils.toBooleanObject(&quot;false&quot;) = Boolean.FALSE
-     *    BooleanUtils.toBooleanObject(&quot;on&quot;)    = Boolean.TRUE
-     *    BooleanUtils.toBooleanObject(&quot;ON&quot;)    = Boolean.TRUE
-     *    BooleanUtils.toBooleanObject(&quot;off&quot;)   = Boolean.FALSE
-     *    BooleanUtils.toBooleanObject(&quot;oFf&quot;)   = Boolean.FALSE
-     *    BooleanUtils.toBooleanObject(&quot;blue&quot;)  = null
-     * </pre>
-     * 
-     * @param str
-     *            the String to check
-     * @return the Boolean value of the string, <code>null</code> if no match
-     *         or <code>null</code> input
-     */
-    public static Boolean toBooleanObject( String str )
-    {
-        if ( "true".equalsIgnoreCase( str ) )
-        {
-            return Boolean.TRUE;
-        }
-        else if ( "false".equalsIgnoreCase( str ) )
-        {
-            return Boolean.FALSE;
-        }
-        else if ( "on".equalsIgnoreCase( str ) )
-        {
-            return Boolean.TRUE;
-        }
-        else if ( "off".equalsIgnoreCase( str ) )
-        {
-            return Boolean.FALSE;
-        }
-        else if ( "yes".equalsIgnoreCase( str ) )
-        {
-            return Boolean.TRUE;
-        }
-        else if ( "no".equalsIgnoreCase( str ) )
-        {
-            return Boolean.FALSE;
-        }
-        // no match
-        return null;
-    }
-
-
-    /**
-     * <p>
-     * Converts a String to a Boolean throwing an exception if no match.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBooleanObject(&quot;true&quot;, &quot;true&quot;, &quot;false&quot;, &quot;null&quot;)  = Boolean.TRUE
-     *    BooleanUtils.toBooleanObject(&quot;false&quot;, &quot;true&quot;, &quot;false&quot;, &quot;null&quot;) = Boolean.FALSE
-     *    BooleanUtils.toBooleanObject(&quot;null&quot;, &quot;true&quot;, &quot;false&quot;, &quot;null&quot;)  = null
-     * </pre>
-     * 
-     * @param str
-     *            the String to check
-     * @param trueString
-     *            the String to match for <code>true</code> (case sensitive),
-     *            may be <code>null</code>
-     * @param falseString
-     *            the String to match for <code>false</code> (case sensitive),
-     *            may be <code>null</code>
-     * @param nullString
-     *            the String to match for <code>null</code> (case sensitive),
-     *            may be <code>null</code>
-     * @return the Boolean value of the string, <code>null</code> if no match
-     *         or <code>null</code> input
-     */
-    public static Boolean toBooleanObject( String str, String trueString, String falseString, String nullString )
-    {
-        if ( str == null )
-        {
-            if ( trueString == null )
-            {
-                return Boolean.TRUE;
-            }
-            else if ( falseString == null )
-            {
-                return Boolean.FALSE;
-            }
-            else if ( nullString == null )
-            {
-                return null;
-            }
-        }
-        else if ( str.equals( trueString ) )
-        {
-            return Boolean.TRUE;
-        }
-        else if ( str.equals( falseString ) )
-        {
-            return Boolean.FALSE;
-        }
-        else if ( str.equals( nullString ) )
-        {
-            return null;
-        }
-        // no match
-        throw new IllegalArgumentException( I18n.err( I18n.ERR_04350 ) );
-    }
-
-
-    // String to boolean methods
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts a String to a boolean (optimised for performance).
-     * </p>
-     * <p>
-     * <code>'true'</code>, <code>'on'</code> or <code>'yes'</code> (case
-     * insensitive) will return <code>true</code>. Otherwise,
-     * <code>false</code> is returned.
-     * </p>
-     * <p>
-     * This method performs 4 times faster (JDK1.4) than
-     * <code>Boolean.valueOf(String)</code>. However, this method accepts
-     * 'on' and 'yes' as true values.
-     * 
-     * <pre>
-     *    BooleanUtils.toBoolean(null)    = false
-     *    BooleanUtils.toBoolean(&quot;true&quot;)  = true
-     *    BooleanUtils.toBoolean(&quot;TRUE&quot;)  = true
-     *    BooleanUtils.toBoolean(&quot;tRUe&quot;)  = true
-     *    BooleanUtils.toBoolean(&quot;on&quot;)    = true
-     *    BooleanUtils.toBoolean(&quot;yes&quot;)   = true
-     *    BooleanUtils.toBoolean(&quot;false&quot;) = false
-     *    BooleanUtils.toBoolean(&quot;x gti&quot;) = false
-     * </pre>
-     * 
-     * @param str
-     *            the String to check
-     * @return the boolean value of the string, <code>false</code> if no match
-     */
-    public static boolean toBoolean( String str )
-    {
-        // Previously used equalsIgnoreCase, which was fast for interned 'true'.
-        // Non interned 'true' matched 15 times slower.
-        // 
-        // Optimisation provides same performance as before for interned 'true'.
-        // Similar performance for null, 'false', and other strings not length
-        // 2/3/4.
-        // 'true'/'TRUE' match 4 times slower, 'tRUE'/'True' 7 times slower.
-        if ( "true".equals( str ) )
-        {
-            return true;
-        }
-        if ( str == null )
-        {
-            return false;
-        }
-        switch ( str.length() )
-        {
-            case 2:
-            {
-                char ch0 = str.charAt( 0 );
-                char ch1 = str.charAt( 1 );
-                return ( ch0 == 'o' || ch0 == 'O' ) && ( ch1 == 'n' || ch1 == 'N' );
-            }
-            case 3:
-            {
-                char ch = str.charAt( 0 );
-                if ( ch == 'y' )
-                {
-                    return ( str.charAt( 1 ) == 'e' || str.charAt( 1 ) == 'E' )
-                        && ( str.charAt( 2 ) == 's' || str.charAt( 2 ) == 'S' );
-                }
-                if ( ch == 'Y' )
-                {
-                    return ( str.charAt( 1 ) == 'E' || str.charAt( 1 ) == 'e' )
-                        && ( str.charAt( 2 ) == 'S' || str.charAt( 2 ) == 's' );
-                }
-            }
-            case 4:
-            {
-                char ch = str.charAt( 0 );
-                if ( ch == 't' )
-                {
-                    return ( str.charAt( 1 ) == 'r' || str.charAt( 1 ) == 'R' )
-                        && ( str.charAt( 2 ) == 'u' || str.charAt( 2 ) == 'U' )
-                        && ( str.charAt( 3 ) == 'e' || str.charAt( 3 ) == 'E' );
-                }
-                if ( ch == 'T' )
-                {
-                    return ( str.charAt( 1 ) == 'R' || str.charAt( 1 ) == 'r' )
-                        && ( str.charAt( 2 ) == 'U' || str.charAt( 2 ) == 'u' )
-                        && ( str.charAt( 3 ) == 'E' || str.charAt( 3 ) == 'e' );
-                }
-            }
-        }
-        return false;
-    }
-
-
-    /**
-     * <p>
-     * Converts a String to a Boolean throwing an exception if no match found.
-     * </p>
-     * <p>
-     * null is returned if there is no match.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toBoolean(&quot;true&quot;, &quot;true&quot;, &quot;false&quot;)  = true
-     *    BooleanUtils.toBoolean(&quot;false&quot;, &quot;true&quot;, &quot;false&quot;) = false
-     * </pre>
-     * 
-     * @param str
-     *            the String to check
-     * @param trueString
-     *            the String to match for <code>true</code> (case sensitive),
-     *            may be <code>null</code>
-     * @param falseString
-     *            the String to match for <code>false</code> (case sensitive),
-     *            may be <code>null</code>
-     * @return the boolean value of the string
-     * @throws IllegalArgumentException
-     *             if the String doesn't match
-     */
-    public static boolean toBoolean( String str, String trueString, String falseString )
-    {
-        if ( str == null )
-        {
-            if ( trueString == null )
-            {
-                return true;
-            }
-            else if ( falseString == null )
-            {
-                return false;
-            }
-        }
-        else if ( str.equals( trueString ) )
-        {
-            return true;
-        }
-        else if ( str.equals( falseString ) )
-        {
-            return false;
-        }
-        // no match
-        throw new IllegalArgumentException( I18n.err( I18n.ERR_04350 ) );
-    }
-
-
-    // Boolean to String methods
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts a Boolean to a String returning <code>'true'</code>,
-     * <code>'false'</code>, or <code>null</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toStringTrueFalse(Boolean.TRUE)  = &quot;true&quot;
-     *    BooleanUtils.toStringTrueFalse(Boolean.FALSE) = &quot;false&quot;
-     *    BooleanUtils.toStringTrueFalse(null)          = null;
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to check
-     * @return <code>'true'</code>, <code>'false'</code>, or
-     *         <code>null</code>
-     */
-    public static String toStringTrueFalse( Boolean bool )
-    {
-        return toString( bool, "true", "false", null );
-    }
-
-
-    /**
-     * <p>
-     * Converts a Boolean to a String returning <code>'on'</code>,
-     * <code>'off'</code>, or <code>null</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toStringOnOff(Boolean.TRUE)  = &quot;on&quot;
-     *    BooleanUtils.toStringOnOff(Boolean.FALSE) = &quot;off&quot;
-     *    BooleanUtils.toStringOnOff(null)          = null;
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to check
-     * @return <code>'on'</code>, <code>'off'</code>, or <code>null</code>
-     */
-    public static String toStringOnOff( Boolean bool )
-    {
-        return toString( bool, "on", "off", null );
-    }
-
-
-    /**
-     * <p>
-     * Converts a Boolean to a String returning <code>'yes'</code>,
-     * <code>'no'</code>, or <code>null</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toStringYesNo(Boolean.TRUE)  = &quot;yes&quot;
-     *    BooleanUtils.toStringYesNo(Boolean.FALSE) = &quot;no&quot;
-     *    BooleanUtils.toStringYesNo(null)          = null;
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to check
-     * @return <code>'yes'</code>, <code>'no'</code>, or <code>null</code>
-     */
-    public static String toStringYesNo( Boolean bool )
-    {
-        return toString( bool, "yes", "no", null );
-    }
-
-
-    /**
-     * <p>
-     * Converts a Boolean to a String returning one of the input Strings.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toString(Boolean.TRUE, &quot;true&quot;, &quot;false&quot;, null)   = &quot;true&quot;
-     *    BooleanUtils.toString(Boolean.FALSE, &quot;true&quot;, &quot;false&quot;, null)  = &quot;false&quot;
-     *    BooleanUtils.toString(null, &quot;true&quot;, &quot;false&quot;, null)           = null;
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to check
-     * @param trueString
-     *            the String to return if <code>true</code>, may be
-     *            <code>null</code>
-     * @param falseString
-     *            the String to return if <code>false</code>, may be
-     *            <code>null</code>
-     * @param nullString
-     *            the String to return if <code>null</code>, may be
-     *            <code>null</code>
-     * @return one of the three input Strings
-     */
-    public static String toString( Boolean bool, String trueString, String falseString, String nullString )
-    {
-        if ( bool == null )
-        {
-            return nullString;
-        }
-        return ( bool.booleanValue() ? trueString : falseString );
-    }
-
-
-    // boolean to String methods
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Converts a boolean to a String returning <code>'true'</code> or
-     * <code>'false'</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toStringTrueFalse(true)   = &quot;true&quot;
-     *    BooleanUtils.toStringTrueFalse(false)  = &quot;false&quot;
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to check
-     * @return <code>'true'</code>, <code>'false'</code>, or
-     *         <code>null</code>
-     */
-    public static String toStringTrueFalse( boolean bool )
-    {
-        return toString( bool, "true", "false" );
-    }
-
-
-    /**
-     * <p>
-     * Converts a boolean to a String returning <code>'on'</code> or
-     * <code>'off'</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toStringOnOff(true)   = &quot;on&quot;
-     *    BooleanUtils.toStringOnOff(false)  = &quot;off&quot;
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to check
-     * @return <code>'on'</code>, <code>'off'</code>, or <code>null</code>
-     */
-    public static String toStringOnOff( boolean bool )
-    {
-        return toString( bool, "on", "off" );
-    }
-
-
-    /**
-     * <p>
-     * Converts a boolean to a String returning <code>'yes'</code> or
-     * <code>'no'</code>.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toStringYesNo(true)   = &quot;yes&quot;
-     *    BooleanUtils.toStringYesNo(false)  = &quot;no&quot;
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to check
-     * @return <code>'yes'</code>, <code>'no'</code>, or <code>null</code>
-     */
-    public static String toStringYesNo( boolean bool )
-    {
-        return toString( bool, "yes", "no" );
-    }
-
-
-    /**
-     * <p>
-     * Converts a boolean to a String returning one of the input Strings.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.toString(true, &quot;true&quot;, &quot;false&quot;)   = &quot;true&quot;
-     *    BooleanUtils.toString(false, &quot;true&quot;, &quot;false&quot;)  = &quot;false&quot;
-     * </pre>
-     * 
-     * @param bool
-     *            the Boolean to check
-     * @param trueString
-     *            the String to return if <code>true</code>, may be
-     *            <code>null</code>
-     * @param falseString
-     *            the String to return if <code>false</code>, may be
-     *            <code>null</code>
-     * @return one of the two input Strings
-     */
-    public static String toString( boolean bool, String trueString, String falseString )
-    {
-        return ( bool ? trueString : falseString );
-    }
-
-
-    // xor methods
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Performs an xor on a set of booleans.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.xor(new boolean[] { true, true })   = false
-     *    BooleanUtils.xor(new boolean[] { false, false }) = false
-     *    BooleanUtils.xor(new boolean[] { true, false })  = true
-     * </pre>
-     * 
-     * @param array
-     *            an array of <code>boolean<code>s
-     * @return <code>true</code> if the xor is successful.
-     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
-     * @throws IllegalArgumentException if <code>array</code> is empty.
-     */
-    public static boolean xor( boolean[] array )
-    {
-        // Validates input
-        if ( array == null )
-        {
-            throw new IllegalArgumentException( I18n.err( I18n.ERR_04352 ) );
-        }
-        else if ( array.length == 0 )
-        {
-            throw new IllegalArgumentException( I18n.err( I18n.ERR_04352 ) );
-        }
-
-        // Loops through array, comparing each item
-        int trueCount = 0;
-        for ( int i = 0; i < array.length; i++ )
-        {
-            // If item is true, and trueCount is < 1, increments count
-            // Else, xor fails
-            if ( array[i] )
-            {
-                if ( trueCount < 1 )
-                {
-                    trueCount++;
-                }
-                else
-                {
-                    return false;
-                }
-            }
-        }
-
-        // Returns true if there was exactly 1 true item
-        return trueCount == 1;
-    }
-
-
-    /**
-     * <p>
-     * Performs an xor on an array of Booleans.
-     * </p>
-     * 
-     * <pre>
-     *    BooleanUtils.xor(new Boolean[] { Boolean.TRUE, Boolean.TRUE })   = Boolean.FALSE
-     *    BooleanUtils.xor(new Boolean[] { Boolean.FALSE, Boolean.FALSE }) = Boolean.FALSE
-     *    BooleanUtils.xor(new Boolean[] { Boolean.TRUE, Boolean.FALSE })  = Boolean.TRUE
-     * </pre>
-     * 
-     * @param array
-     *            an array of <code>Boolean<code>s
-     * @return <code>true</code> if the xor is successful.
-     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
-     * @throws IllegalArgumentException if <code>array</code> is empty.
-     * @throws IllegalArgumentException if <code>array</code> contains a <code>null</code>
-     */
-    public static Boolean xor( Boolean[] array )
-    {
-        if ( array == null )
-        {
-            throw new IllegalArgumentException( I18n.err( I18n.ERR_04351 ) );
-        }
-        else if ( array.length == 0 )
-        {
-            throw new IllegalArgumentException( I18n.err( I18n.ERR_04352 ) );
-        }
-        boolean[] primitive = null;
-        try
-        {
-            primitive = ArrayUtils.toPrimitive( array );
-        }
-        catch ( NullPointerException ex )
-        {
-            throw new IllegalArgumentException( I18n.err( I18n.ERR_04353 ) );
-        }
-        return ( xor( primitive ) ? Boolean.TRUE : Boolean.FALSE );
-    }
-
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ClassUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/ClassUtils.java
deleted file mode 100644
index 85fc206..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ClassUtils.java
+++ /dev/null
@@ -1,784 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * <p>
- * Operates on classes without using reflection.
- * </p>
- * <p>
- * This class handles invalid <code>null</code> inputs as best it can. Each
- * method documents its behaviour in more detail.
- * </p>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class ClassUtils
-{
-    private static final String EMPTY = "";
-
-    /**
-     * <p>
-     * The package separator character: <code>'&#x2e;' == .</code>.
-     * </p>
-     */
-    public static final char PACKAGE_SEPARATOR_CHAR = '.';
-
-    /**
-     * <p>
-     * The package separator String: <code>"&#x2e;"</code>.
-     * </p>
-     */
-    public static final String PACKAGE_SEPARATOR = String.valueOf( PACKAGE_SEPARATOR_CHAR );
-
-    /**
-     * <p>
-     * The inner class separator character: <code>'$' == $</code>.
-     * </p>
-     */
-    public static final char INNER_CLASS_SEPARATOR_CHAR = '$';
-
-    /**
-     * <p>
-     * The inner class separator String: <code>"$"</code>.
-     * </p>
-     */
-    public static final String INNER_CLASS_SEPARATOR = String.valueOf( INNER_CLASS_SEPARATOR_CHAR );
-
-    /**
-     * Maps primitive <code>Class</code>es to their corresponding wrapper
-     * <code>Class</code>.
-     */
-    private static Map<Class<?>,Class<?>> primitiveWrapperMap = new HashMap<Class<?>,Class<?>>();
-    
-    static
-    {
-        primitiveWrapperMap.put( Boolean.TYPE, Boolean.class );
-        primitiveWrapperMap.put( Byte.TYPE, Byte.class );
-        primitiveWrapperMap.put( Character.TYPE, Character.class );
-        primitiveWrapperMap.put( Short.TYPE, Short.class );
-        primitiveWrapperMap.put( Integer.TYPE, Integer.class );
-        primitiveWrapperMap.put( Long.TYPE, Long.class );
-        primitiveWrapperMap.put( Double.TYPE, Double.class );
-        primitiveWrapperMap.put( Float.TYPE, Float.class );
-    }
-
-
-    /**
-     * <p>
-     * ClassUtils instances should NOT be constructed in standard programming.
-     * Instead, the class should be used as
-     * <code>ClassUtils.getShortClassName(cls)</code>.
-     * </p>
-     * <p>
-     * This constructor is public to permit tools that require a JavaBean
-     * instance to operate.
-     * </p>
-     */
-    public ClassUtils()
-    {
-    }
-
-
-    // Short class name
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Gets the class name minus the package name for an <code>Object</code>.
-     * </p>
-     * 
-     * @param object
-     *            the class to get the short name for, may be null
-     * @param valueIfNull
-     *            the value to return if null
-     * @return the class name of the object without the package name, or the
-     *         null value
-     */
-    public static String getShortClassName( Object object, String valueIfNull )
-    {
-        if ( object == null )
-        {
-            return valueIfNull;
-        }
-        return getShortClassName( object.getClass().getName() );
-    }
-
-
-    /**
-     * <p>
-     * Gets the class name minus the package name from a <code>Class</code>.
-     * </p>
-     * 
-     * @param cls
-     *            the class to get the short name for.
-     * @return the class name without the package name or an empty string
-     */
-    public static String getShortClassName( Class<?> cls )
-    {
-        if ( cls == null )
-        {
-            return EMPTY;
-        }
-        
-        return getShortClassName( cls.getName() );
-    }
-
-
-    /**
-     * <p>
-     * Gets the class name minus the package name from a String.
-     * </p>
-     * <p>
-     * The string passed in is assumed to be a class name - it is not checked.
-     * </p>
-     * 
-     * @param className
-     *            the className to get the short name for
-     * @return the class name of the class without the package name or an empty
-     *         string
-     */
-    public static String getShortClassName( String className )
-    {
-        if ( className == null )
-        {
-            return EMPTY;
-        }
-        
-        if ( className.length() == 0 )
-        {
-            return EMPTY;
-        }
-        
-        char[] chars = className.toCharArray();
-        int lastDot = 0;
-        
-        for ( int i = 0; i < chars.length; i++ )
-        {
-            if ( chars[i] == PACKAGE_SEPARATOR_CHAR )
-            {
-                lastDot = i + 1;
-            }
-            else if ( chars[i] == INNER_CLASS_SEPARATOR_CHAR )
-            { // handle inner classes
-                chars[i] = PACKAGE_SEPARATOR_CHAR;
-            }
-        }
-        
-        return new String( chars, lastDot, chars.length - lastDot );
-    }
-
-
-    // Package name
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Gets the package name of an <code>Object</code>.
-     * </p>
-     * 
-     * @param object
-     *            the class to get the package name for, may be null
-     * @param valueIfNull
-     *            the value to return if null
-     * @return the package name of the object, or the null value
-     */
-    public static String getPackageName( Object object, String valueIfNull )
-    {
-        if ( object == null )
-        {
-            return valueIfNull;
-        }
-        
-        return getPackageName( object.getClass().getName() );
-    }
-
-
-    /**
-     * <p>
-     * Gets the package name of a <code>Class</code>.
-     * </p>
-     * 
-     * @param cls
-     *            the class to get the package name for, may be
-     *            <code>null</code>.
-     * @return the package name or an empty string
-     */
-    public static String getPackageName( Class<?> cls )
-    {
-        if ( cls == null )
-        {
-            return EMPTY;
-        }
-        
-        return getPackageName( cls.getName() );
-    }
-
-
-    /**
-     * <p>
-     * Gets the package name from a <code>String</code>.
-     * </p>
-     * <p>
-     * The string passed in is assumed to be a class name - it is not checked.
-     * </p>
-     * <p>
-     * If the class is unpackaged, return an empty string.
-     * </p>
-     * 
-     * @param className
-     *            the className to get the package name for, may be
-     *            <code>null</code>
-     * @return the package name or an empty string
-     */
-    public static String getPackageName( String className )
-    {
-        if ( className == null )
-        {
-            return EMPTY;
-        }
-        
-        int i = className.lastIndexOf( PACKAGE_SEPARATOR_CHAR );
-        
-        if ( i == -1 )
-        {
-            return EMPTY;
-        }
-        
-        return className.substring( 0, i );
-    }
-
-
-    // Superclasses/Superinterfaces
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Gets a <code>List</code> of superclasses for the given class.
-     * </p>
-     * 
-     * @param cls
-     *            the class to look up, may be <code>null</code>
-     * @return the <code>List</code> of superclasses in order going up from
-     *         this one <code>null</code> if null input
-     */
-    public static List<Class<?>> getAllSuperclasses( Class<?> cls )
-    {
-        if ( cls == null )
-        {
-            return null;
-        }
-        
-        List<Class<?>> classes = new ArrayList<Class<?>>();
-        
-        Class<?> superclass = cls.getSuperclass();
-        
-        while ( superclass != null )
-        {
-            classes.add( superclass );
-            superclass = superclass.getSuperclass();
-        }
-        
-        return classes;
-    }
-
-
-    /**
-     * <p>
-     * Gets a <code>List</code> of all interfaces implemented by the given
-     * class and its superclasses.
-     * </p>
-     * <p>
-     * The order is determined by looking through each interface in turn as
-     * declared in the source file and following its hierarchy up. Then each
-     * superclass is considered in the same way. Later duplicates are ignored,
-     * so the order is maintained.
-     * </p>
-     * 
-     * @param cls
-     *            the class to look up, may be <code>null</code>
-     * @return the <code>List</code> of interfaces in order, <code>null</code>
-     *         if null input
-     */
-    public static List<Class<?>> getAllInterfaces( Class<?> cls )
-    {
-        if ( cls == null )
-        {
-            return null;
-        }
-        
-        List<Class<?>> list = new ArrayList<Class<?>>();
-        
-        while ( cls != null )
-        {
-            Class<?>[] interfaces = cls.getInterfaces();
-            
-            for ( Class<?> interf:interfaces )
-            {
-                if ( list.contains( interf ) == false )
-                {
-                    list.add( interf );
-                }
-                
-                for ( Class<?> superIntf:getAllInterfaces( interf ) )
-                {
-                    if ( list.contains( superIntf ) == false )
-                    {
-                        list.add( superIntf );
-                    }
-                }
-            }
-            
-            cls = cls.getSuperclass();
-        }
-        
-        return list;
-    }
-
-
-    // Convert list
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Given a <code>List</code> of class names, this method converts them
-     * into classes.
-     * </p>
-     * <p>
-     * A new <code>List</code> is returned. If the class name cannot be found,
-     * <code>null</code> is stored in the <code>List</code>. If the class
-     * name in the <code>List</code> is <code>null</code>,
-     * <code>null</code> is stored in the output <code>List</code>.
-     * </p>
-     * 
-     * @param classNames
-     *            the classNames to change
-     * @return a <code>List</code> of Class objects corresponding to the class
-     *         names, <code>null</code> if null input
-     * @throws ClassCastException
-     *             if classNames contains a non String entry
-     */
-    public static List<Class<?>> convertClassNamesToClasses( List<String> classNames )
-    {
-        if ( classNames == null )
-        {
-            return null;
-        }
-        
-        List<Class<?>> classes = new ArrayList<Class<?>>( classNames.size() );
-        
-        for ( String className:classNames )
-        {
-            try
-            {
-                classes.add( Class.forName( className ) );
-            }
-            catch ( Exception ex )
-            {
-                classes.add( null );
-            }
-        }
-        
-        return classes;
-    }
-
-
-    /**
-     * <p>
-     * Given a <code>List</code> of <code>Class</code> objects, this method
-     * converts them into class names.
-     * </p>
-     * <p>
-     * A new <code>List</code> is returned. <code>null</code> objects will
-     * be copied into the returned list as <code>null</code>.
-     * </p>
-     * 
-     * @param classes
-     *            the classes to change
-     * @return a <code>List</code> of class names corresponding to the Class
-     *         objects, <code>null</code> if null input
-     * @throws ClassCastException
-     *             if <code>classes</code> contains a non-<code>Class</code>
-     *             entry
-     */
-    public static List<String> convertClassesToClassNames( List<Class<?>> classes )
-    {
-        if ( classes == null )
-        {
-            return null;
-        }
-        
-        List<String> classNames = new ArrayList<String>( classes.size() );
-        
-        for ( Class<?> clazz:classes )
-        {
-            if ( clazz == null )
-            {
-                classNames.add( null );
-            }
-            else
-            {
-                classNames.add( clazz.getName() );
-            }
-        }
-        
-        return classNames;
-    }
-
-
-    // Is assignable
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Checks if an array of Classes can be assigned to another array of
-     * Classes.
-     * </p>
-     * <p>
-     * This method calls {@link #isAssignable(Class, Class) isAssignable} for
-     * each Class pair in the input arrays. It can be used to check if a set of
-     * arguments (the first parameter) are suitably compatible with a set of
-     * method parameter types (the second parameter).
-     * </p>
-     * <p>
-     * Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, this
-     * method takes into account widenings of primitive classes and
-     * <code>null</code>s.
-     * </p>
-     * <p>
-     * Primitive widenings allow an int to be assigned to a <code>long</code>,
-     * <code>float</code> or <code>double</code>. This method returns the
-     * correct result for these cases.
-     * </p>
-     * <p>
-     * <code>Null</code> may be assigned to any reference type. This method
-     * will return <code>true</code> if <code>null</code> is passed in and
-     * the toClass is non-primitive.
-     * </p>
-     * <p>
-     * Specifically, this method tests whether the type represented by the
-     * specified <code>Class</code> parameter can be converted to the type
-     * represented by this <code>Class</code> object via an identity
-     * conversion widening primitive or widening reference conversion. See
-     * <em><a href="http://java.sun.com/docs/books/jls/">The Java Language Specification</a></em>,
-     * sections 5.1.1, 5.1.2 and 5.1.4 for details.
-     * </p>
-     * 
-     * @param classArray
-     *            the array of Classes to check, may be <code>null</code>
-     * @param toClassArray
-     *            the array of Classes to try to assign into, may be
-     *            <code>null</code>
-     * @return <code>true</code> if assignment possible
-     */
-    public static boolean isAssignable( Class<?>[] classArray, Class<?>[] toClassArray )
-    {
-        if ( ArrayUtils.isSameLength( classArray, toClassArray ) == false )
-        {
-            return false;
-        }
-        
-        if ( classArray == null )
-        {
-            classArray = ArrayUtils.EMPTY_CLASS_ARRAY;
-        }
-        
-        if ( toClassArray == null )
-        {
-            toClassArray = ArrayUtils.EMPTY_CLASS_ARRAY;
-        }
-        
-        for ( int i = 0; i < classArray.length; i++ )
-        {
-            if ( isAssignable( classArray[i], toClassArray[i] ) == false )
-            {
-                return false;
-            }
-        }
-        
-        return true;
-    }
-
-
-    /**
-     * <p>
-     * Checks if one <code>Class</code> can be assigned to a variable of
-     * another <code>Class</code>.
-     * </p>
-     * <p>
-     * Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, this
-     * method takes into account widenings of primitive classes and
-     * <code>null</code>s.
-     * </p>
-     * <p>
-     * Primitive widenings allow an int to be assigned to a long, float or
-     * double. This method returns the correct result for these cases.
-     * </p>
-     * <p>
-     * <code>Null</code> may be assigned to any reference type. This method
-     * will return <code>true</code> if <code>null</code> is passed in and
-     * the toClass is non-primitive.
-     * </p>
-     * <p>
-     * Specifically, this method tests whether the type represented by the
-     * specified <code>Class</code> parameter can be converted to the type
-     * represented by this <code>Class</code> object via an identity
-     * conversion widening primitive or widening reference conversion. See
-     * <em><a href="http://java.sun.com/docs/books/jls/">The Java Language Specification</a></em>,
-     * sections 5.1.1, 5.1.2 and 5.1.4 for details.
-     * </p>
-     * 
-     * @param cls
-     *            the Class to check, may be null
-     * @param toClass
-     *            the Class to try to assign into, returns false if null
-     * @return <code>true</code> if assignment possible
-     */
-    public static boolean isAssignable( Class<?> cls, Class<?> toClass )
-    {
-        if ( toClass == null )
-        {
-            return false;
-        }
-        
-        // have to check for null, as isAssignableFrom doesn't
-        if ( cls == null )
-        {
-            return !( toClass.isPrimitive() );
-        }
-        
-        if ( cls.equals( toClass ) )
-        {
-            return true;
-        }
-        
-        if ( cls.isPrimitive() )
-        {
-            if ( toClass.isPrimitive() == false )
-            {
-                return false;
-            }
-            
-            if ( Integer.TYPE.equals( cls ) )
-            {
-                return Long.TYPE.equals( toClass ) || Float.TYPE.equals( toClass ) || Double.TYPE.equals( toClass );
-            }
-            
-            if ( Long.TYPE.equals( cls ) )
-            {
-                return Float.TYPE.equals( toClass ) || Double.TYPE.equals( toClass );
-            }
-            
-            if ( Boolean.TYPE.equals( cls ) )
-            {
-                return false;
-            }
-            
-            if ( Double.TYPE.equals( cls ) )
-            {
-                return false;
-            }
-            
-            if ( Float.TYPE.equals( cls ) )
-            {
-                return Double.TYPE.equals( toClass );
-            }
-            
-            if ( Character.TYPE.equals( cls ) )
-            {
-                return Integer.TYPE.equals( toClass ) || Long.TYPE.equals( toClass ) || Float.TYPE.equals( toClass )
-                    || Double.TYPE.equals( toClass );
-            }
-            
-            if ( Short.TYPE.equals( cls ) )
-            {
-                return Integer.TYPE.equals( toClass ) || Long.TYPE.equals( toClass ) || Float.TYPE.equals( toClass )
-                    || Double.TYPE.equals( toClass );
-            }
-            
-            if ( Byte.TYPE.equals( cls ) )
-            {
-                return Short.TYPE.equals( toClass ) || Integer.TYPE.equals( toClass ) || Long.TYPE.equals( toClass )
-                    || Float.TYPE.equals( toClass ) || Double.TYPE.equals( toClass );
-            }
-            
-            // should never get here
-            return false;
-        }
-        
-        return toClass.isAssignableFrom( cls );
-    }
-
-
-    /**
-     * <p>
-     * Converts the specified primitive Class object to its corresponding
-     * wrapper Class object.
-     * </p>
-     * 
-     * @param cls
-     *            the class to convert, may be null
-     * @return the wrapper class for <code>cls</code> or <code>cls</code> if
-     *         <code>cls</code> is not a primitive. <code>null</code> if
-     *         null input.
-     */
-    public static Class<?> primitiveToWrapper( Class<?> cls )
-    {
-        Class<?> convertedClass = cls;
-        
-        if ( cls != null && cls.isPrimitive() )
-        {
-            convertedClass = primitiveWrapperMap.get( cls );
-        }
-        
-        return convertedClass;
-    }
-
-
-    /**
-     * <p>
-     * Converts the specified array of primitive Class objects to an array of
-     * its corresponding wrapper Class objects.
-     * </p>
-     * 
-     * @param classes
-     *            the class array to convert, may be null or empty
-     * @return an array which contains for each given class, the wrapper class
-     *         or the original class if class is not a primitive.
-     *         <code>null</code> if null input. Empty array if an empty array
-     *         passed in.
-     */
-    public static Class<?>[] primitivesToWrappers( Class<?>[] classes )
-    {
-        if ( classes == null )
-        {
-            return null;
-        }
-
-        if ( classes.length == 0 )
-        {
-            return ArrayUtils.EMPTY_CLASS_ARRAY;
-        }
-
-        Class<?>[] convertedClasses = new Class[classes.length];
-        
-        for ( int i = 0; i < classes.length; i++ )
-        {
-            convertedClasses[i] = primitiveToWrapper( classes[i] );
-        }
-        
-        return convertedClasses;
-    }
-
-
-    // Inner class
-    // ----------------------------------------------------------------------
-    /**
-     * <p>
-     * Is the specified class an inner class or static nested class.
-     * </p>
-     * 
-     * @param cls
-     *            the class to check, may be null
-     * @return <code>true</code> if the class is an inner or static nested
-     *         class, false if not or <code>null</code>
-     */
-    public static boolean isInnerClass( Class<?> cls )
-    {
-        if ( cls == null )
-        {
-            return false;
-        }
-        
-        return ( cls.getName().indexOf( INNER_CLASS_SEPARATOR_CHAR ) >= 0 );
-    }
-
-    // -----------------------------------------------------------------------
-    /**
-     * Compares two <code>Class</code>s by name.
-     */
-    private static class ClassNameComparator implements Comparator<Class<?>>
-    {
-        /**
-         * Compares two <code>Class</code>s by name.
-         * 
-         * @throws ClassCastException
-         *             If <code>o1</code> or <code>o2</code> are not
-         *             <code>Class</code> instances.
-         */
-        public int compare( Class<?> class1, Class<?> class2 )
-        {
-            if ( class1 == null )
-            {
-                return class2 == null ? 0 : -1;
-            }
-            
-            if ( class2 == null )
-            {
-                return 1;
-            }
-            
-            return class1.getName().compareTo( class2.getName() );
-        }
-    }
-
-    /**
-     * Compares two <code>Class</code>s by name.
-     */
-    public static final Comparator<Class<?>> CLASS_NAME_COMPARATOR = new ClassNameComparator();
-
-    /**
-     * Compares two <code>Package</code>s by name.
-     */
-    private static class PackageNameComparator implements Comparator<Package>
-    {
-
-        /**
-         * Compares two <code>Package</code>s by name.
-         * 
-         * @throws ClassCastException
-         *             If <code>o1</code> or <code>o2</code> are not
-         *             <code>Package</code> instances.
-         */
-        public int compare( Package package1, Package package2 )
-        {
-            if ( package1 == null )
-            {
-                return package2 == null ? 0 : -1;
-            }
-
-            if ( package2 == null )
-            {
-                return 1;
-            }
-            
-            return package1.getName().compareTo( package2.getName() );
-        }
-    }
-
-    /**
-     * Compares two <code>Package</code>s by name.
-     */
-    public static final Comparator<Package> PACKAGE_NAME_COMPARATOR = new PackageNameComparator();
-
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/EqualsBuilder.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/EqualsBuilder.java
deleted file mode 100644
index d08a221..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/EqualsBuilder.java
+++ /dev/null
@@ -1,1031 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-
-import org.apache.directory.shared.i18n.I18n;
-
-
-/**
- * <p>
- * Assists in implementing {@link Object#equals(Object)} methods.
- * </p>
- * <p>
- * This class provides methods to build a good equals method for any class. It
- * follows rules laid out in <a
- * href="http://java.sun.com/docs/books/effective/index.html">Effective Java</a> ,
- * by Joshua Bloch. In particular the rule for comparing <code>doubles</code>,
- * <code>floats</code>, and arrays can be tricky. Also, making sure that
- * <code>equals()</code> and <code>hashCode()</code> are consistent can be
- * difficult.
- * </p>
- * <p>
- * Two Objects that compare as equals must generate the same hash code, but two
- * Objects with the same hash code do not have to be equal.
- * </p>
- * <p>
- * All relevant fields should be included in the calculation of equals. Derived
- * fields may be ignored. In particular, any field used in generating a hash
- * code must be used in the equals method, and vice versa.
- * </p>
- * <p>
- * Typical use for the code is as follows:
- * </p>
- * 
- * <pre>
- * public boolean equals( Object o )
- * {
- *     if ( !( o instanceof MyClass ) )
- *     {
- *         return false;
- *     }
- *     MyClass rhs = ( MyClass ) o;
- *     return new EqualsBuilder().appendSuper( super.equals( o ) ).append( field1, rhs.field1 )
- *         .append( field2, rhs.field2 ).append( field3, rhs.field3 ).isEquals();
- * }
- * </pre>
- * 
- * <p>
- * Alternatively, there is a method that uses reflection to determine the fields
- * to test. Because these fields are usually private, the method,
- * <code>reflectionEquals</code>, uses
- * <code>AccessibleObject.setAccessible</code> to change the visibility of the
- * fields. This will fail under a security manager, unless the appropriate
- * permissions are set up correctly. It is also slower than testing explicitly.
- * </p>
- * <p>
- * A typical invocation for this method would look like:
- * </p>
- * 
- * <pre>
- * public boolean equals( Object o )
- * {
- *     return EqualsBuilder.reflectionEquals( this, o );
- * }
- * </pre>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class EqualsBuilder
-{
-
-    /**
-     * If the fields tested are equals. The default value is <code>true</code>.
-     */
-    private boolean isEquals = true;
-
-
-    /**
-     * <p>
-     * Constructor for EqualsBuilder.
-     * </p>
-     * <p>
-     * Starts off assuming that equals is <code>true</code>.
-     * </p>
-     * 
-     * @see Object#equals(Object)
-     */
-    public EqualsBuilder()
-    {
-        // do nothing for now.
-    }
-
-
-    // -------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * This method uses reflection to determine if the two <code>Object</code>s
-     * are equal.
-     * </p>
-     * <p>
-     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
-     * private fields. This means that it will throw a security exception if run
-     * under a security manager, if the permissions are not set up correctly. It
-     * is also not as efficient as testing explicitly.
-     * </p>
-     * <p>
-     * Transient members will be not be tested, as they are likely derived
-     * fields, and not part of the value of the Object.
-     * </p>
-     * <p>
-     * Static fields will not be tested. Superclass fields will be included.
-     * </p>
-     * 
-     * @param lhs
-     *            <code>this</code> object
-     * @param rhs
-     *            the other object
-     * @return <code>true</code> if the two Objects have tested equals.
-     */
-    public static boolean reflectionEquals( Object lhs, Object rhs )
-    {
-        return reflectionEquals( lhs, rhs, false, null );
-    }
-
-
-    /**
-     * <p>
-     * This method uses reflection to determine if the two <code>Object</code>s
-     * are equal.
-     * </p>
-     * <p>
-     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
-     * private fields. This means that it will throw a security exception if run
-     * under a security manager, if the permissions are not set up correctly. It
-     * is also not as efficient as testing explicitly.
-     * </p>
-     * <p>
-     * If the TestTransients parameter is set to <code>true</code>, transient
-     * members will be tested, otherwise they are ignored, as they are likely
-     * derived fields, and not part of the value of the <code>Object</code>.
-     * </p>
-     * <p>
-     * Static fields will not be tested. Superclass fields will be included.
-     * </p>
-     * 
-     * @param lhs
-     *            <code>this</code> object
-     * @param rhs
-     *            the other object
-     * @param testTransients
-     *            whether to include transient fields
-     * @return <code>true</code> if the two Objects have tested equals.
-     */
-    public static boolean reflectionEquals( Object lhs, Object rhs, boolean testTransients )
-    {
-        return reflectionEquals( lhs, rhs, testTransients, null );
-    }
-
-
-    /**
-     * <p>
-     * This method uses reflection to determine if the two <code>Object</code>s
-     * are equal.
-     * </p>
-     * <p>
-     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
-     * private fields. This means that it will throw a security exception if run
-     * under a security manager, if the permissions are not set up correctly. It
-     * is also not as efficient as testing explicitly.
-     * </p>
-     * <p>
-     * If the testTransients parameter is set to <code>true</code>, transient
-     * members will be tested, otherwise they are ignored, as they are likely
-     * derived fields, and not part of the value of the <code>Object</code>.
-     * </p>
-     * <p>
-     * Static fields will not be included. Superclass fields will be appended up
-     * to and including the specified superclass. A null superclass is treated
-     * as java.lang.Object.
-     * </p>
-     * 
-     * @param lhs
-     *            <code>this</code> object
-     * @param rhs
-     *            the other object
-     * @param testTransients
-     *            whether to include transient fields
-     * @param reflectUpToClass
-     *            the superclass to reflect up to (inclusive), may be
-     *            <code>null</code>
-     * @return <code>true</code> if the two Objects have tested equals.
-     * @since 2.0
-     */
-    public static boolean reflectionEquals( Object lhs, Object rhs, boolean testTransients, Class reflectUpToClass )
-    {
-        if ( lhs == rhs )
-        {
-            return true;
-        }
-        if ( lhs == null || rhs == null )
-        {
-            return false;
-        }
-        // Find the leaf class since there may be transients in the leaf
-        // class or in classes between the leaf and root.
-        // If we are not testing transients or a subclass has no ivars,
-        // then a subclass can test equals to a superclass.
-        Class lhsClass = lhs.getClass();
-        Class rhsClass = rhs.getClass();
-        Class testClass;
-        if ( lhsClass.isInstance( rhs ) )
-        {
-            testClass = lhsClass;
-            if ( !rhsClass.isInstance( lhs ) )
-            {
-                // rhsClass is a subclass of lhsClass
-                testClass = rhsClass;
-            }
-        }
-        else if ( rhsClass.isInstance( lhs ) )
-        {
-            testClass = rhsClass;
-            if ( !lhsClass.isInstance( rhs ) )
-            {
-                // lhsClass is a subclass of rhsClass
-                testClass = lhsClass;
-            }
-        }
-        else
-        {
-            // The two classes are not related.
-            return false;
-        }
-        EqualsBuilder equalsBuilder = new EqualsBuilder();
-        try
-        {
-            reflectionAppend( lhs, rhs, testClass, equalsBuilder, testTransients );
-            while ( testClass.getSuperclass() != null && testClass != reflectUpToClass )
-            {
-                testClass = testClass.getSuperclass();
-                reflectionAppend( lhs, rhs, testClass, equalsBuilder, testTransients );
-            }
-        }
-        catch ( IllegalArgumentException e )
-        {
-            // In this case, we tried to test a subclass vs. a superclass and
-            // the subclass has ivars or the ivars are transient and
-            // we are testing transients.
-            // If a subclass has ivars that we are trying to test them, we get
-            // an
-            // exception and we know that the objects are not equal.
-            return false;
-        }
-        return equalsBuilder.isEquals();
-    }
-
-
-    /**
-     * <p>
-     * Appends the fields and values defined by the given object of the given
-     * Class.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand object
-     * @param rhs
-     *            the right hand object
-     * @param clazz
-     *            the class to append details of
-     * @param builder
-     *            the builder to append to
-     * @param useTransients
-     *            whether to test transient fields
-     */
-    private static void reflectionAppend( Object lhs, Object rhs, Class clazz, EqualsBuilder builder,
-        boolean useTransients )
-    {
-        Field[] fields = clazz.getDeclaredFields();
-        AccessibleObject.setAccessible( fields, true );
-        for ( int i = 0; i < fields.length && builder.isEquals; i++ )
-        {
-            Field f = fields[i];
-            if ( ( f.getName().indexOf( '$' ) == -1 ) && ( useTransients || !Modifier.isTransient( f.getModifiers() ) )
-                && ( !Modifier.isStatic( f.getModifiers() ) ) )
-            {
-                try
-                {
-                    builder.append( f.get( lhs ), f.get( rhs ) );
-                }
-                catch ( IllegalAccessException e )
-                {
-                    // this can't happen. Would get a Security exception instead
-                    // throw a runtime exception in case the impossible happens.
-                    throw new InternalError( I18n.err( I18n.ERR_04355 ) );
-                }
-            }
-        }
-    }
-
-
-    // -------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Adds the result of <code>super.equals()</code> to this builder.
-     * </p>
-     * 
-     * @param superEquals
-     *            the result of calling <code>super.equals()</code>
-     * @return EqualsBuilder - used to chain calls.
-     * @since 2.0
-     */
-    public EqualsBuilder appendSuper( boolean superEquals )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        isEquals = superEquals;
-        return this;
-    }
-
-
-    // -------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Test if two <code>Object</code>s are equal using their
-     * <code>equals</code> method.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand object
-     * @param rhs
-     *            the right hand object
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( Object lhs, Object rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        if ( lhs == rhs )
-        {
-            return this;
-        }
-        if ( lhs == null || rhs == null )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        Class lhsClass = lhs.getClass();
-        if ( !lhsClass.isArray() )
-        {
-            // The simple case, not an array, just test the element
-            isEquals = lhs.equals( rhs );
-        }
-        else if ( lhs.getClass() != rhs.getClass() )
-        {
-            // Here when we compare different dimensions, for example: a
-            // boolean[][] to a boolean[]
-            this.setEquals( false );
-        }
-        // 'Switch' on type of array, to dispatch to the correct handler
-        // This handles multi dimensional arrays of the same depth
-        else if ( lhs instanceof long[] )
-        {
-            append( ( long[] ) lhs, ( long[] ) rhs );
-        }
-        else if ( lhs instanceof int[] )
-        {
-            append( ( int[] ) lhs, ( int[] ) rhs );
-        }
-        else if ( lhs instanceof short[] )
-        {
-            append( ( short[] ) lhs, ( short[] ) rhs );
-        }
-        else if ( lhs instanceof char[] )
-        {
-            append( ( char[] ) lhs, ( char[] ) rhs );
-        }
-        else if ( lhs instanceof byte[] )
-        {
-            append( ( byte[] ) lhs, ( byte[] ) rhs );
-        }
-        else if ( lhs instanceof double[] )
-        {
-            append( ( double[] ) lhs, ( double[] ) rhs );
-        }
-        else if ( lhs instanceof float[] )
-        {
-            append( ( float[] ) lhs, ( float[] ) rhs );
-        }
-        else if ( lhs instanceof boolean[] )
-        {
-            append( ( boolean[] ) lhs, ( boolean[] ) rhs );
-        }
-        else
-        {
-            // Not an array of primitives
-            append( ( Object[] ) lhs, ( Object[] ) rhs );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Test if two <code>long</code> s are equal.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>long</code>
-     * @param rhs
-     *            the right hand <code>long</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( long lhs, long rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        isEquals = ( lhs == rhs );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Test if two <code>int</code>s are equal.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>int</code>
-     * @param rhs
-     *            the right hand <code>int</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( int lhs, int rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        isEquals = ( lhs == rhs );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Test if two <code>short</code>s are equal.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>short</code>
-     * @param rhs
-     *            the right hand <code>short</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( short lhs, short rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        isEquals = ( lhs == rhs );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Test if two <code>char</code>s are equal.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>char</code>
-     * @param rhs
-     *            the right hand <code>char</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( char lhs, char rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        isEquals = ( lhs == rhs );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Test if two <code>byte</code>s are equal.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>byte</code>
-     * @param rhs
-     *            the right hand <code>byte</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( byte lhs, byte rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        isEquals = ( lhs == rhs );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Test if two <code>double</code>s are equal by testing that the pattern
-     * of bits returned by <code>doubleToLong</code> are equal.
-     * </p>
-     * <p>
-     * This handles NaNs, Infinities, and <code>-0.0</code>.
-     * </p>
-     * <p>
-     * It is compatible with the hash code generated by
-     * <code>HashCodeBuilder</code>.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>double</code>
-     * @param rhs
-     *            the right hand <code>double</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( double lhs, double rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        return append( Double.doubleToLongBits( lhs ), Double.doubleToLongBits( rhs ) );
-    }
-
-
-    /**
-     * <p>
-     * Test if two <code>float</code>s are equal byt testing that the pattern
-     * of bits returned by doubleToLong are equal.
-     * </p>
-     * <p>
-     * This handles NaNs, Infinities, and <code>-0.0</code>.
-     * </p>
-     * <p>
-     * It is compatible with the hash code generated by
-     * <code>HashCodeBuilder</code>.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>float</code>
-     * @param rhs
-     *            the right hand <code>float</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( float lhs, float rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        return append( Float.floatToIntBits( lhs ), Float.floatToIntBits( rhs ) );
-    }
-
-
-    /**
-     * <p>
-     * Test if two <code>booleans</code>s are equal.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>boolean</code>
-     * @param rhs
-     *            the right hand <code>boolean</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( boolean lhs, boolean rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        isEquals = ( lhs == rhs );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Performs a deep comparison of two <code>Object</code> arrays.
-     * </p>
-     * <p>
-     * This also will be called for the top level of multi-dimensional, ragged,
-     * and multi-typed arrays.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>Object[]</code>
-     * @param rhs
-     *            the right hand <code>Object[]</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( Object[] lhs, Object[] rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        if ( lhs == rhs )
-        {
-            return this;
-        }
-        if ( lhs == null || rhs == null )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        if ( lhs.length != rhs.length )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        for ( int i = 0; i < lhs.length && isEquals; ++i )
-        {
-            append( lhs[i], rhs[i] );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Deep comparison of array of <code>long</code>. Length and all values
-     * are compared.
-     * </p>
-     * <p>
-     * The method {@link #append(long, long)} is used.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>long[]</code>
-     * @param rhs
-     *            the right hand <code>long[]</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( long[] lhs, long[] rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        if ( lhs == rhs )
-        {
-            return this;
-        }
-        if ( lhs == null || rhs == null )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        if ( lhs.length != rhs.length )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        for ( int i = 0; i < lhs.length && isEquals; ++i )
-        {
-            append( lhs[i], rhs[i] );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Deep comparison of array of <code>int</code>. Length and all values
-     * are compared.
-     * </p>
-     * <p>
-     * The method {@link #append(int, int)} is used.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>int[]</code>
-     * @param rhs
-     *            the right hand <code>int[]</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( int[] lhs, int[] rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        if ( lhs == rhs )
-        {
-            return this;
-        }
-        if ( lhs == null || rhs == null )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        if ( lhs.length != rhs.length )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        for ( int i = 0; i < lhs.length && isEquals; ++i )
-        {
-            append( lhs[i], rhs[i] );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Deep comparison of array of <code>short</code>. Length and all values
-     * are compared.
-     * </p>
-     * <p>
-     * The method {@link #append(short, short)} is used.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>short[]</code>
-     * @param rhs
-     *            the right hand <code>short[]</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( short[] lhs, short[] rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        if ( lhs == rhs )
-        {
-            return this;
-        }
-        if ( lhs == null || rhs == null )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        if ( lhs.length != rhs.length )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        for ( int i = 0; i < lhs.length && isEquals; ++i )
-        {
-            append( lhs[i], rhs[i] );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Deep comparison of array of <code>char</code>. Length and all values
-     * are compared.
-     * </p>
-     * <p>
-     * The method {@link #append(char, char)} is used.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>char[]</code>
-     * @param rhs
-     *            the right hand <code>char[]</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( char[] lhs, char[] rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        if ( lhs == rhs )
-        {
-            return this;
-        }
-        if ( lhs == null || rhs == null )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        if ( lhs.length != rhs.length )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        for ( int i = 0; i < lhs.length && isEquals; ++i )
-        {
-            append( lhs[i], rhs[i] );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Deep comparison of array of <code>byte</code>. Length and all values
-     * are compared.
-     * </p>
-     * <p>
-     * The method {@link #append(byte, byte)} is used.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>byte[]</code>
-     * @param rhs
-     *            the right hand <code>byte[]</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( byte[] lhs, byte[] rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        if ( lhs == rhs )
-        {
-            return this;
-        }
-        if ( lhs == null || rhs == null )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        if ( lhs.length != rhs.length )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        for ( int i = 0; i < lhs.length && isEquals; ++i )
-        {
-            append( lhs[i], rhs[i] );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Deep comparison of array of <code>double</code>. Length and all values
-     * are compared.
-     * </p>
-     * <p>
-     * The method {@link #append(double, double)} is used.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>double[]</code>
-     * @param rhs
-     *            the right hand <code>double[]</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( double[] lhs, double[] rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        if ( lhs == rhs )
-        {
-            return this;
-        }
-        if ( lhs == null || rhs == null )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        if ( lhs.length != rhs.length )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        for ( int i = 0; i < lhs.length && isEquals; ++i )
-        {
-            append( lhs[i], rhs[i] );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Deep comparison of array of <code>float</code>. Length and all values
-     * are compared.
-     * </p>
-     * <p>
-     * The method {@link #append(float, float)} is used.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>float[]</code>
-     * @param rhs
-     *            the right hand <code>float[]</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( float[] lhs, float[] rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        if ( lhs == rhs )
-        {
-            return this;
-        }
-        if ( lhs == null || rhs == null )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        if ( lhs.length != rhs.length )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        for ( int i = 0; i < lhs.length && isEquals; ++i )
-        {
-            append( lhs[i], rhs[i] );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Deep comparison of array of <code>boolean</code>. Length and all
-     * values are compared.
-     * </p>
-     * <p>
-     * The method {@link #append(boolean, boolean)} is used.
-     * </p>
-     * 
-     * @param lhs
-     *            the left hand <code>boolean[]</code>
-     * @param rhs
-     *            the right hand <code>boolean[]</code>
-     * @return EqualsBuilder - used to chain calls.
-     */
-    public EqualsBuilder append( boolean[] lhs, boolean[] rhs )
-    {
-        if ( isEquals == false )
-        {
-            return this;
-        }
-        if ( lhs == rhs )
-        {
-            return this;
-        }
-        if ( lhs == null || rhs == null )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        if ( lhs.length != rhs.length )
-        {
-            this.setEquals( false );
-            return this;
-        }
-        for ( int i = 0; i < lhs.length && isEquals; ++i )
-        {
-            append( lhs[i], rhs[i] );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Returns <code>true</code> if the fields that have been checked are all
-     * equal.
-     * </p>
-     * 
-     * @return boolean
-     */
-    public boolean isEquals()
-    {
-        return this.isEquals;
-    }
-
-
-    /**
-     * Sets the <code>isEquals</code> value.
-     * 
-     * @param isEquals
-     *            The value to set.
-     */
-    protected void setEquals( boolean isEquals )
-    {
-        this.isEquals = isEquals;
-    }
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ExceptionUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/ExceptionUtils.java
deleted file mode 100644
index 6a36cc8..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ExceptionUtils.java
+++ /dev/null
@@ -1,988 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.reflect.Field;
-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 org.apache.directory.shared.i18n.I18n;
-
-
-/**
- * <p>
- * Provides utilities for manipulating and examining <code>Throwable</code>
- * objects.
- * </p>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$
- */
-public class ExceptionUtils
-{
-
-    /**
-     * <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] ";
-
-    /**
-     * <p>
-     * The names of methods commonly used to access a wrapped exception.
-     * </p>
-     */
-    private static String[] CAUSE_METHOD_NAMES =
-        { "getCause", "getNextException", "getTargetException", "getException", "getSourceException", "getRootCause",
-            "getCausedByException", "getNested", "getLinkedException", "getNestedException", "getLinkedCause",
-            "getThrowable", };
-
-    /**
-     * <p>
-     * The Method object for JDK1.4 getCause.
-     * </p>
-     */
-    private static final Method THROWABLE_CAUSE_METHOD;
-
-    static
-    {
-        Method getCauseMethod;
-        try
-        {
-            getCauseMethod = Throwable.class.getMethod( "getCause", (Class[])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()
-    {
-    }
-
-
-    /**
-     * <p>
-     * Checks if a String is not empty ("") and not null.
-     * </p>
-     * 
-     * @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 );
-    }
-
-
-    // -----------------------------------------------------------------------
-    /**
-     * <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<String> list = new ArrayList<String>( Arrays.asList( CAUSE_METHOD_NAMES ) );
-            list.add( methodName );
-            CAUSE_METHOD_NAMES = list.toArray( new String[list.size()] );
-        }
-    }
-
-
-    /**
-     * <p>
-     * Introspects the <code>Throwable</code> to obtain the cause.
-     * </p>
-     * <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
-     * @since 1.0
-     */
-    public static Throwable getCause( Throwable throwable )
-    {
-        return getCause( throwable, CAUSE_METHOD_NAMES );
-    }
-
-
-    /**
-     * <p>
-     * Introspects the <code>Throwable</code> to obtain the cause.
-     * </p>
-     * <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 )
-        {
-            return null;
-        }
-        Throwable cause = getCauseUsingWellKnownTypes( throwable );
-        if ( cause == null )
-        {
-            if ( methodNames == null )
-            {
-                methodNames = CAUSE_METHOD_NAMES;
-            }
-            for ( int i = 0; i < methodNames.length; i++ )
-            {
-                String methodName = methodNames[i];
-                if ( methodName != null )
-                {
-                    cause = getCauseUsingMethodName( throwable, methodName );
-                    if ( cause != null )
-                    {
-                        break;
-                    }
-                }
-            }
-
-            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>
-     * 
-     * @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 )
-            {
-                cause = throwable;
-            }
-        }
-        return cause;
-    }
-
-
-    /**
-     * <p>
-     * Finds a <code>Throwable</code> for known types.
-     * </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
-     * @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
-        {
-            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
-     * @return the wrapped exception, or <code>null</code> if not found
-     */
-    // This will suppress PMD.EmptyCatchBlock warnings in this method
-    @SuppressWarnings("PMD.EmptyCatchBlock")
-    private static Throwable getCauseUsingMethodName( Throwable throwable, String methodName )
-    {
-        Method method = null;
-        try
-        {
-            method = throwable.getClass().getMethod( methodName, (Class[])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 )
-            {
-            }
-        }
-        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
-     * @return the wrapped exception, or <code>null</code> if not found
-     */
-    // This will suppress PMD.EmptyCatchBlock warnings in this method
-    @SuppressWarnings("PMD.EmptyCatchBlock")
-    private static Throwable getCauseUsingFieldName( Throwable throwable, String fieldName )
-    {
-        Field field = null;
-        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 )
-            {
-            }
-        }
-        return null;
-    }
-
-
-    // -----------------------------------------------------------------------
-    /**
-     * <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 );
-    }
-
-
-    /**
-     * <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
-     * @return boolean <code>true</code> if nested otherwise
-     *         <code>false</code>
-     * @since 2.0
-     */
-    // This will suppress PMD.EmptyCatchBlock warnings in this method
-    @SuppressWarnings("PMD.EmptyCatchBlock")
-    public static boolean isNestedThrowable( Throwable throwable )
-    {
-        if ( throwable == null )
-        {
-            return false;
-        }
-
-        if ( throwable instanceof Nestable )
-        {
-            return true;
-        }
-        else if ( throwable instanceof SQLException )
-        {
-            return true;
-        }
-        else if ( throwable instanceof InvocationTargetException )
-        {
-            return true;
-        }
-        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], (Class[])null );
-                if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) )
-                {
-                    return true;
-                }
-            }
-            catch ( NoSuchMethodException ignored )
-            {
-            }
-            catch ( SecurityException ignored )
-            {
-            }
-        }
-
-        try
-        {
-            Field field = cls.getField( "detail" );
-            if ( field != null )
-            {
-                return true;
-            }
-        }
-        catch ( NoSuchFieldException ignored )
-        {
-        }
-        catch ( SecurityException ignored )
-        {
-        }
-
-        return false;
-    }
-
-
-    // -----------------------------------------------------------------------
-    /**
-     * <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 )
-    {
-        int count = 0;
-        while ( throwable != null )
-        {
-            count++;
-            throwable = ExceptionUtils.getCause( throwable );
-        }
-        return count;
-    }
-
-
-    /**
-     * <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
-     * @return the array of throwables, never null
-     */
-    public static Throwable[] getThrowables( Throwable throwable )
-    {
-        List<Throwable> list = new ArrayList<Throwable>();
-        
-        while ( throwable != null )
-        {
-            list.add( throwable );
-            throwable = ExceptionUtils.getCause( throwable );
-        }
-        
-        return 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/>
-     * <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
-     * @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 );
-    }
-
-
-    /**
-     * <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/>
-     * <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 )
-        {
-            return -1;
-        }
-        if ( fromIndex < 0 )
-        {
-            fromIndex = 0;
-        }
-        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 ) )
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    // -----------------------------------------------------------------------
-    /**
-     * <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 );
-    }
-
-
-    /**
-     * <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>
-     * 
-     * @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 )
-        {
-            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] );
-        }
-        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>
-     * 
-     * @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 )
-        {
-            return;
-        }
-        if ( writer == null )
-        {
-            throw new IllegalArgumentException( I18n.err( I18n.ERR_04356 ) );
-        }
-        String trace[] = getRootCauseStackTrace( throwable );
-        for ( int i = 0; i < trace.length; i++ )
-        {
-            writer.println( trace[i] );
-        }
-        writer.flush();
-    }
-
-
-    // -----------------------------------------------------------------------
-    /**
-     * <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
-     * @return an array of stack trace frames, never null
-     * @since 2.0
-     */
-    public static String[] getRootCauseStackTrace( Throwable throwable )
-    {
-        if ( throwable == null )
-        {
-            return ArrayUtils.EMPTY_STRING_ARRAY;
-        }
-        
-        Throwable throwables[] = getThrowables( throwable );
-        int count = throwables.length;
-        List<String> frames = new ArrayList<String>();
-        List<String> nextTrace = getStackFrameList( throwables[count - 1] );
-        
-        for ( int i = count; --i >= 0; )
-        {
-            List<String> 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() );
-            }
-            for ( int j = 0; j < trace.size(); j++ )
-            {
-                frames.add( trace.get( j ) );
-            }
-        }
-        return 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
-     * @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( I18n.err( I18n.ERR_04357 ) );
-        }
-        int causeFrameIndex = causeFrames.size() - 1;
-        int wrapperFrameIndex = wrapperFrames.size() - 1;
-        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 );
-            }
-            causeFrameIndex--;
-            wrapperFrameIndex--;
-        }
-    }
-
-
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Gets the stack trace from a Throwable as a String.
-     * </p>
-     * 
-     * @param throwable
-     *            the <code>Throwable</code> to be examined
-     * @return the stack trace as generated by the exception's
-     *         <code>printStackTrace(PrintWriter)</code> method
-     */
-    public static String getStackTrace( Throwable throwable )
-    {
-        StringWriter sw = new StringWriter();
-        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
-     * @return the nested stack trace, with the root cause first
-     * @since 2.0
-     */
-    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] ) )
-            {
-                break;
-            }
-        }
-        return sw.getBuffer().toString();
-    }
-
-
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Captures the stack trace associated with the specified
-     * <code>Throwable</code> object, decomposing it into a list of stack
-     * frames.
-     * </p>
-     * 
-     * @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 )
-        {
-            return ArrayUtils.EMPTY_STRING_ARRAY;
-        }
-        return getStackFrames( getStackTrace( throwable ) );
-    }
-
-
-    /**
-     * <p>
-     * Functionality shared between the <code>getStackFrames(Throwable)</code>
-     * methods of this and the
-     */
-    static String[] getStackFrames( String stackTrace )
-    {
-        String linebreak = SystemUtils.LINE_SEPARATOR;
-        StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
-        List<String> list = new LinkedList<String>();
-        
-        while ( frames.hasMoreTokens() )
-        {
-            list.add( frames.nextToken() );
-        }
-        
-        return list.toArray( new String[list.size()] );
-    }
-
-
-    /**
-     * <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>
-     * 
-     * @param t
-     *            is any throwable
-     * @return List of stack frames
-     */
-    static List<String> getStackFrameList( Throwable t )
-    {
-        String stackTrace = getStackTrace( t );
-        String linebreak = SystemUtils.LINE_SEPARATOR;
-        StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
-        List<String> list = new LinkedList<String>();
-        boolean traceStarted = false;
-        
-        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 )
-            {
-                traceStarted = true;
-                list.add( token );
-            }
-            else if ( traceStarted )
-            {
-                break;
-            }
-        }
-        return list;
-    }
-    
-    
-    public static String printErrors( List<Throwable> errors )
-    {
-        StringBuilder sb = new StringBuilder();
-        
-        for ( Throwable error:errors )
-        {
-            sb.append( "Error : " ).append( error.getMessage() ).append( "\n" );
-        }
-        
-        return sb.toString();
-    }
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/KeyValue.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/LdapExceptionUtils.java
similarity index 65%
rename from ldap/src/main/java/org/apache/directory/shared/ldap/util/KeyValue.java
rename to ldap/src/main/java/org/apache/directory/shared/ldap/util/LdapExceptionUtils.java
index 6f6bbcf..8abc7ae 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/KeyValue.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/util/LdapExceptionUtils.java
@@ -20,33 +20,29 @@
 package org.apache.directory.shared.ldap.util;
 
 
+import java.util.List;
+
+
 /**
- * Defines a simple key value pair.
  * <p>
- * A Map Entry has considerable additional semantics over and above a simple
- * key-value pair. This interface defines the minimum key value, with just the
- * two get methods.
+ * Provides utilities for manipulating and examining <code>Throwable</code>
+ * objects.
+ * </p>
  * 
- * @since Commons Collections 3.0
- * @version $Revision$ $Date$
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
  */
-public interface KeyValue
+public class LdapExceptionUtils
 {
-
-    /**
-     * Gets the key from the pair.
-     * 
-     * @return the key
-     */
-    Object getKey();
-
-
-    /**
-     * Gets the value from the pair.
-     * 
-     * @return the value
-     */
-    Object getValue();
-
+    public static String printErrors( List<Throwable> errors )
+    {
+        StringBuilder sb = new StringBuilder();
+        
+        for ( Throwable error:errors )
+        {
+            sb.append( "Error : " ).append( error.getMessage() ).append( "\n" );
+        }
+        
+        return sb.toString();
+    }
 }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/LdapURL.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/LdapURL.java
index b84cf92..c291995 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/LdapURL.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/util/LdapURL.java
@@ -363,6 +363,7 @@
      *         apply to the byte buffer TODO check that the topLabel is valid
      *         (it must start with an alpha)
      */
+    @SuppressWarnings("PMD.CollapsibleIfStatements") // Used because of comments
     private int parseHost( char[] chars, int pos )
     {
 
@@ -400,17 +401,13 @@
                 }
 
                 // Let's check the string we had before the dot.
-                if ( isHostNumber )
+                if ( isHostNumber &&  nbDots < 4 )
                 {
 
-                    if ( nbDots < 4 )
+                    // We had only digits. It may be an IP adress? Check it
+                    if ( ipElem[nbDots] > 65535 )
                     {
-
-                        // We had only digits. It may be an IP adress? Check it
-                        if ( ipElem[nbDots] > 65535 )
-                        {
-                            invalidIp = true;
-                        }
+                        invalidIp = true;
                     }
                 }
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/Nestable.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/Nestable.java
deleted file mode 100644
index d30bd41..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/Nestable.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-
-/**
- * An interface to be implemented by {@link java.lang.Throwable} extensions
- * which would like to be able to nest root exceptions inside themselves.
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public interface Nestable
-{
-
-    /**
-     * Returns the reference to the exception or error that caused the exception
-     * implementing the <code>Nestable</code> to be thrown.
-     * 
-     * @return throwable that caused the original exception
-     */
-    public Throwable getCause();
-
-
-    /**
-     * Returns the error message of this and any nested <code>Throwable</code>.
-     * 
-     * @return the error message
-     */
-    public String getMessage();
-
-
-    /**
-     * Returns the error message of the <code>Throwable</code> in the chain of
-     * <code>Throwable</code>s at the specified index, numbered from 0.
-     * 
-     * @param index
-     *            the index of the <code>Throwable</code> in the chain of
-     *            <code>Throwable</code>s
-     * @return the error message, or null if the <code>Throwable</code> at the
-     *         specified index in the chain does not contain a message
-     * @throws IndexOutOfBoundsException
-     *             if the <code>index</code> argument is negative or not less
-     *             than the count of <code>Throwable</code>s in the chain
-     */
-    public String getMessage( int index );
-
-
-    /**
-     * Returns the error message of this and any nested <code>Throwable</code>s
-     * in an array of Strings, one element for each message. Any
-     * <code>Throwable</code> not containing a message is represented in the
-     * array by a null. This has the effect of cause the length of the returned
-     * array to be equal to the result of the {@link #getThrowableCount()}
-     * operation.
-     * 
-     * @return the error messages
-     */
-    public String[] getMessages();
-
-
-    /**
-     * Returns the <code>Throwable</code> in the chain of
-     * <code>Throwable</code>s at the specified index, numbered from 0.
-     * 
-     * @param index
-     *            the index, numbered from 0, of the <code>Throwable</code> in
-     *            the chain of <code>Throwable</code>s
-     * @return the <code>Throwable</code>
-     * @throws IndexOutOfBoundsException
-     *             if the <code>index</code> argument is negative or not less
-     *             than the count of <code>Throwable</code>s in the chain
-     */
-    public Throwable getThrowable( int index );
-
-
-    /**
-     * Returns the number of nested <code>Throwable</code>s represented by
-     * this <code>Nestable</code>, including this <code>Nestable</code>.
-     * 
-     * @return the throwable count
-     */
-    public int getThrowableCount();
-
-
-    /**
-     * Returns this <code>Nestable</code> and any nested
-     * <code>Throwable</code>s in an array of <code>Throwable</code>s, one
-     * element for each <code>Throwable</code>.
-     * 
-     * @return the <code>Throwable</code>s
-     */
-    public Throwable[] getThrowables();
-
-
-    /**
-     * Returns the index, numbered from 0, of the first occurrence of the
-     * specified type in the chain of <code>Throwable</code>s, or -1 if the
-     * specified type is not found in the chain.
-     * 
-     * @param type
-     *            <code>Class</code> to be found
-     * @return index of the first occurrence of the type in the chain, or -1 if
-     *         the type is not found
-     */
-    public int indexOfThrowable( Class type );
-
-
-    /**
-     * Returns the index, numbered from 0, of the first <code>Throwable</code>
-     * that matches the specified type in the chain of <code>Throwable</code>s
-     * with an index greater than or equal to the specified index, or -1 if the
-     * type is not found.
-     * 
-     * @param type
-     *            <code>Class</code> to be found
-     * @param fromIndex
-     *            the index, numbered from 0, of the starting position in the
-     *            chain to be searched
-     * @return index of the first occurrence of the type in the chain, or -1 if
-     *         the type is not found
-     * @throws IndexOutOfBoundsException
-     *             if the <code>fromIndex</code> argument is negative or not
-     *             less than the count of <code>Throwable</code>s in the
-     *             chain
-     */
-    public int indexOfThrowable( Class type, int fromIndex );
-
-
-    /**
-     * Prints the stack trace of this exception to the specified print writer.
-     * Includes information from the exception, if any, which caused this
-     * exception.
-     * 
-     * @param out
-     *            <code>PrintWriter</code> to use for output.
-     */
-    public void printStackTrace( PrintWriter out );
-
-
-    /**
-     * Prints the stack trace of this exception to the specified print stream.
-     * Includes information from the exception, if any, which caused this
-     * exception.
-     * 
-     * @param out
-     *            <code>PrintStream</code> to use for output.
-     */
-    public void printStackTrace( PrintStream out );
-
-
-    /**
-     * Prints the stack trace for this exception only--root cause not
-     * included--using the provided writer. Used by 
-     * {@link "org.apache.commons.lang.exception.NestableDelegate"} to write individual
-     * stack traces to a buffer. The implementation of this method should call
-     * <code>super.printStackTrace(out);</code> in most cases.
-     * 
-     * @param out
-     *            The writer to use.
-     */
-    public void printPartialStackTrace( PrintWriter out );
-
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableDelegate.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableDelegate.java
deleted file mode 100644
index 232fe39..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableDelegate.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.directory.shared.i18n.I18n;
-
-
-/**
- * <p>
- * A shared implementation of the nestable exception functionality.
- * </p>
- * <p>
- * The code is shared between
- * </p>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class NestableDelegate implements Serializable
-{
-
-    static final long serialVersionUID = -4140246270875850555L;
-
-    /**
-     * Constructor error message.
-     */
-    private transient static final String MUST_BE_THROWABLE = I18n.err( I18n.ERR_04419 );
-
-    /**
-     * Holds the reference to the exception or error that we're wrapping (which
-     * must be a {@link org.apache.commons.lang.exception.Nestable}
-     * implementation).
-     */
-    private Throwable nestable = null;
-
-    /**
-     * Whether to print the stack trace top-down. This public flag may be set by
-     * calling code, typically in initialisation.
-     * 
-     * @since 2.0
-     */
-    public static boolean topDown = true;
-
-    /**
-     * Whether to trim the repeated stack trace. This public flag may be set by
-     * calling code, typically in initialisation.
-     * 
-     * @since 2.0
-     */
-    public static boolean trimStackFrames = true;
-
-
-    /**
-     * Constructs a new <code>NestableDelegate</code> instance to manage the
-     * specified <code>Nestable</code>.
-     * 
-     * @param nestable
-     *            the Nestable implementation (<i>must</i> extend
-     *            {@link java.lang.Throwable})
-     * @since 2.0
-     */
-    public NestableDelegate(Nestable nestable)
-    {
-        if ( nestable instanceof Throwable )
-        {
-            this.nestable = ( Throwable ) nestable;
-        }
-        else
-        {
-            throw new IllegalArgumentException( MUST_BE_THROWABLE );
-        }
-    }
-
-
-    /**
-     * Returns the error message of the <code>Throwable</code> in the chain of
-     * <code>Throwable</code>s at the specified index, numbered from 0.
-     * 
-     * @param index
-     *            the index of the <code>Throwable</code> in the chain of
-     *            <code>Throwable</code>s
-     * @return the error message, or null if the <code>Throwable</code> at the
-     *         specified index in the chain does not contain a message
-     * @throws IndexOutOfBoundsException
-     *             if the <code>index</code> argument is negative or not less
-     *             than the count of <code>Throwable</code>s in the chain
-     * @since 2.0
-     */
-    public String getMessage( int index )
-    {
-        Throwable t = this.getThrowable( index );
-        if ( Nestable.class.isInstance( t ) )
-        {
-            return ( ( Nestable ) t ).getMessage( 0 );
-        }
-        else
-        {
-            return t.getMessage();
-        }
-    }
-
-
-    /**
-     * Returns the full message contained by the <code>Nestable</code> and any
-     * nested <code>Throwable</code>s.
-     * 
-     * @param baseMsg
-     *            the base message to use when creating the full message. Should
-     *            be generally be called via
-     *            <code>nestableHelper.getMessage(super.getMessage())</code>,
-     *            where <code>super</code> is an instance of {@link
-     *            java.lang.Throwable}.
-     * @return The concatenated message for this and all nested
-     *         <code>Throwable</code>s
-     * @since 2.0
-     */
-    public String getMessage( String baseMsg )
-    {
-        StringBuffer msg = new StringBuffer();
-        if ( baseMsg != null )
-        {
-            msg.append( baseMsg );
-        }
-
-        Throwable nestedCause = ExceptionUtils.getCause( this.nestable );
-        if ( nestedCause != null )
-        {
-            String causeMsg = nestedCause.getMessage();
-            if ( causeMsg != null )
-            {
-                if ( baseMsg != null )
-                {
-                    msg.append( ": " );
-                }
-                msg.append( causeMsg );
-            }
-
-        }
-        return ( msg.length() > 0 ? msg.toString() : null );
-    }
-
-
-    /**
-     * Returns the error message of this and any nested <code>Throwable</code>s
-     * in an array of Strings, one element for each message. Any
-     * <code>Throwable</code> not containing a message is represented in the
-     * array by a null. This has the effect of cause the length of the returned
-     * array to be equal to the result of the {@link #getThrowableCount()}
-     * operation.
-     * 
-     * @return the error messages
-     * @since 2.0
-     */
-    public String[] getMessages()
-    {
-        Throwable[] throwables = this.getThrowables();
-        String[] msgs = new String[throwables.length];
-        for ( int i = 0; i < throwables.length; i++ )
-        {
-            msgs[i] = ( Nestable.class.isInstance( throwables[i] ) ? ( ( Nestable ) throwables[i] ).getMessage( 0 )
-                : throwables[i].getMessage() );
-        }
-        return msgs;
-    }
-
-
-    /**
-     * Returns the <code>Throwable</code> in the chain of
-     * <code>Throwable</code>s at the specified index, numbered from 0.
-     * 
-     * @param index
-     *            the index, numbered from 0, of the <code>Throwable</code> in
-     *            the chain of <code>Throwable</code>s
-     * @return the <code>Throwable</code>
-     * @throws IndexOutOfBoundsException
-     *             if the <code>index</code> argument is negative or not less
-     *             than the count of <code>Throwable</code>s in the chain
-     * @since 2.0
-     */
-    public Throwable getThrowable( int index )
-    {
-        if ( index == 0 )
-        {
-            return this.nestable;
-        }
-        Throwable[] throwables = this.getThrowables();
-        return throwables[index];
-    }
-
-
-    /**
-     * Returns the number of <code>Throwable</code>s contained in the
-     * <code>Nestable</code> contained by this delegate.
-     * 
-     * @return the throwable count
-     * @since 2.0
-     */
-    public int getThrowableCount()
-    {
-        return ExceptionUtils.getThrowableCount( this.nestable );
-    }
-
-
-    /**
-     * Returns this delegate's <code>Nestable</code> and any nested
-     * <code>Throwable</code>s in an array of <code>Throwable</code>s, one
-     * element for each <code>Throwable</code>.
-     * 
-     * @return the <code>Throwable</code>s
-     * @since 2.0
-     */
-    public Throwable[] getThrowables()
-    {
-        return ExceptionUtils.getThrowables( this.nestable );
-    }
-
-
-    /**
-     * Returns the index, numbered from 0, of the first <code>Throwable</code>
-     * that matches the specified type in the chain of <code>Throwable</code>s
-     * held in this delegate's <code>Nestable</code> with an index greater
-     * than or equal to the specified index, or -1 if the type is not found.
-     * 
-     * @param type
-     *            <code>Class</code> to be found
-     * @param fromIndex
-     *            the index, numbered from 0, of the starting position in the
-     *            chain to be searched
-     * @return index of the first occurrence of the type in the chain, or -1 if
-     *         the type is not found
-     * @throws IndexOutOfBoundsException
-     *             if the <code>fromIndex</code> argument is negative or not
-     *             less than the count of <code>Throwable</code>s in the
-     *             chain
-     * @since 2.0
-     */
-    public int indexOfThrowable( Class<?> type, int fromIndex )
-    {
-        if ( fromIndex < 0 )
-        {
-            throw new IndexOutOfBoundsException( I18n.err( I18n.ERR_04420, fromIndex ) );
-        }
-        
-        Throwable[] throwables = ExceptionUtils.getThrowables( this.nestable );
-        
-        if ( fromIndex >= throwables.length )
-        {
-            throw new IndexOutOfBoundsException( I18n.err( I18n.ERR_04421, fromIndex, throwables.length ) );
-        }
-        
-        for ( int i = fromIndex; i < throwables.length; i++ )
-        {
-            if ( throwables[i].getClass().equals( type ) )
-            {
-                return i;
-            }
-        }
-        
-        return -1;
-    }
-
-
-    /**
-     * Prints the stack trace of this exception the the standar error stream.
-     */
-    public void printStackTrace()
-    {
-        printStackTrace( System.err );
-    }
-
-
-    /**
-     * Prints the stack trace of this exception to the specified stream.
-     * 
-     * @param out
-     *            <code>PrintStream</code> to use for output.
-     * @see #printStackTrace(PrintWriter)
-     */
-    public void printStackTrace( PrintStream out )
-    {
-        synchronized ( out )
-        {
-            PrintWriter pw = new PrintWriter( out, false );
-            printStackTrace( pw );
-            // Flush the PrintWriter before it's GC'ed.
-            pw.flush();
-        }
-    }
-
-
-    /**
-     * Prints the stack trace of this exception to the specified writer. If the
-     * Throwable class has a <code>getCause</code> method (i.e. running on
-     * jre1.4 or higher), this method just uses Throwable's printStackTrace()
-     * method. Otherwise, generates the stack-trace, by taking into account the
-     * 'topDown' and 'trimStackFrames' parameters. The topDown and
-     * trimStackFrames are set to 'true' by default (produces jre1.4-like stack
-     * trace).
-     * 
-     * @param out
-     *            <code>PrintWriter</code> to use for output.
-     */
-    public void printStackTrace( PrintWriter out )
-    {
-        Throwable throwable = this.nestable;
-        // if running on jre1.4 or higher, use default printStackTrace
-        if ( ExceptionUtils.isThrowableNested() )
-        {
-            if ( throwable instanceof Nestable )
-            {
-                ( ( Nestable ) throwable ).printPartialStackTrace( out );
-            }
-            else
-            {
-                throwable.printStackTrace( out );
-            }
-            return;
-        }
-
-        // generating the nested stack trace
-        List<String[]> stacks = new ArrayList<String[]>();
-        while ( throwable != null )
-        {
-            String[] st = getStackFrames( throwable );
-            stacks.add( st );
-            throwable = ExceptionUtils.getCause( throwable );
-        }
-
-        // If NOT topDown, reverse the stack
-        String separatorLine = "Caused by: ";
-        if ( !topDown )
-        {
-            separatorLine = "Rethrown as: ";
-            Collections.reverse( stacks );
-        }
-
-        // Remove the repeated lines in the stack
-        if ( trimStackFrames )
-        {
-            trimStackFrames( stacks );
-        }
-
-        synchronized ( out )
-        {
-            boolean isFirst = true;
-            
-            for ( String[] st:stacks )
-            {
-                if ( isFirst )
-                {
-                    isFirst = false;
-                }
-                else
-                {
-                    out.print( separatorLine );
-                }
-
-                for ( String s:st )
-                {
-                    out.println( s );
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Captures the stack trace associated with the specified
-     * <code>Throwable</code> object, decomposing it into a list of stack
-     * frames.
-     * 
-     * @param t
-     *            The <code>Throwable</code>.
-     * @return An array of strings describing each stack frame.
-     * @since 2.0
-     */
-    protected String[] getStackFrames( Throwable t )
-    {
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter( sw, true );
-
-        // Avoid infinite loop between decompose() and printStackTrace().
-        if ( t instanceof Nestable )
-        {
-            ( ( Nestable ) t ).printPartialStackTrace( pw );
-        }
-        else
-        {
-            t.printStackTrace( pw );
-        }
-        return ExceptionUtils.getStackFrames( sw.getBuffer().toString() );
-    }
-
-
-    /**
-     * Trims the stack frames. The first set is left untouched. The rest of the
-     * frames are truncated from the bottom by comparing with one just on top.
-     * 
-     * @param stacks
-     *            The list containing String[] elements
-     * @since 2.0
-     */
-    protected void trimStackFrames( List<String[]> stacks )
-    {
-        for ( int size = stacks.size(), i = size - 1; i > 0; i-- )
-        {
-            String[] curr = stacks.get( i );
-            String[] next = stacks.get( i - 1 );
-
-            List<String> currList = new ArrayList<String>( Arrays.asList( curr ) );
-            List<String> nextList = new ArrayList<String>( Arrays.asList( next ) );
-            ExceptionUtils.removeCommonFrames( currList, nextList );
-
-            int trimmed = curr.length - currList.size();
-            
-            if ( trimmed > 0 )
-            {
-                currList.add( "\t... " + trimmed + " more" );
-                stacks.set( i, currList.toArray( new String[currList.size()] ) );
-            }
-        }
-    }
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableError.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableError.java
deleted file mode 100644
index d2e4e24..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableError.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-
-/**
- * The base class of all errors which can contain other exceptions.
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class NestableError extends Error implements Nestable
-{
-
-    static final long serialVersionUID = -9211839990752243375L;
-
-    /**
-     * The helper instance which contains much of the code which we delegate to.
-     */
-    protected NestableDelegate delegate = new NestableDelegate( this );
-
-    /**
-     * Holds the reference to the exception or error that caused this exception
-     * to be thrown.
-     */
-    private Throwable cause = null;
-
-
-    /**
-     * Constructs a new <code>NestableError</code> without specified detail
-     * message.
-     */
-    public NestableError()
-    {
-        super();
-    }
-
-
-    /**
-     * Constructs a new <code>NestableError</code> with specified detail
-     * message.
-     * 
-     * @param msg
-     *            The error message.
-     */
-    public NestableError(String msg)
-    {
-        super( msg );
-    }
-
-
-    /**
-     * Constructs a new <code>NestableError</code> with specified nested
-     * <code>Throwable</code>.
-     * 
-     * @param cause
-     *            the exception or error that caused this exception to be thrown
-     */
-    public NestableError(Throwable cause)
-    {
-        super();
-        this.cause = cause;
-    }
-
-
-    /**
-     * Constructs a new <code>NestableError</code> with specified detail
-     * message and nested <code>Throwable</code>.
-     * 
-     * @param msg
-     *            the error message
-     * @param cause
-     *            the exception or error that caused this exception to be thrown
-     */
-    public NestableError(String msg, Throwable cause)
-    {
-        super( msg );
-        this.cause = cause;
-    }
-
-
-    public Throwable getCause()
-    {
-        return cause;
-    }
-
-
-    /**
-     * Returns the detail message string of this throwable. If it was created
-     * with a null message, returns the following: (cause==null ? null :
-     * cause.toString()).
-     */
-    public String getMessage()
-    {
-        if ( super.getMessage() != null )
-        {
-            return super.getMessage();
-        }
-        else if ( cause != null )
-        {
-            return cause.toString();
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    public String getMessage( int index )
-    {
-        if ( index == 0 )
-        {
-            return super.getMessage();
-        }
-        else
-        {
-            return delegate.getMessage( index );
-        }
-    }
-
-
-    public String[] getMessages()
-    {
-        return delegate.getMessages();
-    }
-
-
-    public Throwable getThrowable( int index )
-    {
-        return delegate.getThrowable( index );
-    }
-
-
-    public int getThrowableCount()
-    {
-        return delegate.getThrowableCount();
-    }
-
-
-    public Throwable[] getThrowables()
-    {
-        return delegate.getThrowables();
-    }
-
-
-    public int indexOfThrowable( Class type )
-    {
-        return delegate.indexOfThrowable( type, 0 );
-    }
-
-
-    public int indexOfThrowable( Class type, int fromIndex )
-    {
-        return delegate.indexOfThrowable( type, fromIndex );
-    }
-
-
-    public void printStackTrace()
-    {
-        delegate.printStackTrace();
-    }
-
-
-    public void printStackTrace( PrintStream out )
-    {
-        delegate.printStackTrace( out );
-    }
-
-
-    public void printStackTrace( PrintWriter out )
-    {
-        delegate.printStackTrace( out );
-    }
-
-
-    public final void printPartialStackTrace( PrintWriter out )
-    {
-        super.printStackTrace( out );
-    }
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableException.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableException.java
deleted file mode 100644
index 89a11d2..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableException.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-
-/**
- * The base class of all exceptions which can contain other exceptions. It is
- * intended to ease the debugging by carrying on the information about the
- * exception which was caught and provoked throwing the current exception.
- * Catching and rethrowing may occur multiple times, and provided that all
- * exceptions except the first one are descendants of
- * <code>NestedException</code>, when the exception is finally printed out
- * using any of the <code>
- * printStackTrace()</code> methods, the stack trace
- * will contain the information about all exceptions thrown and caught on the
- * way.
- * <p>
- * Running the following program
- * <p>
- * <blockquote>
- * 
- * <pre>
- *   1 import org.apache.commons.lang.exception.NestableException;
- *   2
- *   3 public class Test {
- *   4     public static void main( String[] args ) {
- *   5         try {
- *   6             a();
- *   7         } catch(Exception e) {
- *   8             e.printStackTrace();
- *   9         }
- *  10      }
- *  11
- *  12      public static void a() throws Exception {
- *  13          try {
- *  14              b();
- *  15          } catch(Exception e) {
- *  16              throw new NestableException(&quot;foo&quot;, e);
- *  17          }
- *  18      }
- *  19
- *  20      public static void b() throws Exception {
- *  21          try {
- *  22              c();
- *  23          } catch(Exception e) {
- *  24              throw new NestableException(&quot;bar&quot;, e);
- *  25          }
- *  26      }
- *  27
- *  28      public static void c() throws Exception {
- *  29          throw new Exception(&quot;baz&quot;);
- *  30      }
- *  31 }
- * </pre>
- * 
- * </blockquote>
- * <p>
- * Yields the following stack trace:
- * <p>
- * <blockquote>
- * 
- * <pre>
- *  org.apache.commons.lang.exception.NestableException: foo
- *          at Test.a(Test.java:16)
- *          at Test.main(Test.java:6)
- *  Caused by: org.apache.commons.lang.exception.NestableException: bar
- *          at Test.b(Test.java:24)
- *          at Test.a(Test.java:14)
- *          ... 1 more
- *  Caused by: java.lang.Exception: baz
- *          at Test.c(Test.java:29)
- *          at Test.b(Test.java:22)
- *          ... 2 more
- * </pre>
- * 
- * </blockquote><br>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class NestableException extends Exception implements Nestable
-{
-
-    static final long serialVersionUID = 3485795588970325053L;
-
-    /**
-     * The helper instance which contains much of the code which we delegate to.
-     */
-    protected NestableDelegate delegate = new NestableDelegate( this );
-
-    /**
-     * Holds the reference to the exception or error that caused this exception
-     * to be thrown.
-     */
-    private Throwable cause = null;
-
-
-    /**
-     * Constructs a new <code>NestableException</code> without specified
-     * detail message.
-     */
-    public NestableException()
-    {
-        super();
-    }
-
-
-    /**
-     * Constructs a new <code>NestableException</code> with specified detail
-     * message.
-     * 
-     * @param msg
-     *            The error message.
-     */
-    public NestableException(String msg)
-    {
-        super( msg );
-    }
-
-
-    /**
-     * Constructs a new <code>NestableException</code> with specified nested
-     * <code>Throwable</code>.
-     * 
-     * @param cause
-     *            the exception or error that caused this exception to be thrown
-     */
-    public NestableException(Throwable cause)
-    {
-        super();
-        this.cause = cause;
-    }
-
-
-    /**
-     * Constructs a new <code>NestableException</code> with specified detail
-     * message and nested <code>Throwable</code>.
-     * 
-     * @param msg
-     *            the error message
-     * @param cause
-     *            the exception or error that caused this exception to be thrown
-     */
-    public NestableException(String msg, Throwable cause)
-    {
-        super( msg );
-        this.cause = cause;
-    }
-
-
-    public Throwable getCause()
-    {
-        return cause;
-    }
-
-
-    /**
-     * Returns the detail message string of this throwable. If it was created
-     * with a null message, returns the following: (cause==null ? null :
-     * cause.toString()).
-     */
-    public String getMessage()
-    {
-        if ( super.getMessage() != null )
-        {
-            return super.getMessage();
-        }
-        else if ( cause != null )
-        {
-            return cause.toString();
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    public String getMessage( int index )
-    {
-        if ( index == 0 )
-        {
-            return super.getMessage();
-        }
-        else
-        {
-            return delegate.getMessage( index );
-        }
-    }
-
-
-    public String[] getMessages()
-    {
-        return delegate.getMessages();
-    }
-
-
-    public Throwable getThrowable( int index )
-    {
-        return delegate.getThrowable( index );
-    }
-
-
-    public int getThrowableCount()
-    {
-        return delegate.getThrowableCount();
-    }
-
-
-    public Throwable[] getThrowables()
-    {
-        return delegate.getThrowables();
-    }
-
-
-    public int indexOfThrowable( Class type )
-    {
-        return delegate.indexOfThrowable( type, 0 );
-    }
-
-
-    public int indexOfThrowable( Class type, int fromIndex )
-    {
-        return delegate.indexOfThrowable( type, fromIndex );
-    }
-
-
-    public void printStackTrace()
-    {
-        delegate.printStackTrace();
-    }
-
-
-    public void printStackTrace( PrintStream out )
-    {
-        delegate.printStackTrace( out );
-    }
-
-
-    public void printStackTrace( PrintWriter out )
-    {
-        delegate.printStackTrace( out );
-    }
-
-
-    public final void printPartialStackTrace( PrintWriter out )
-    {
-        super.printStackTrace( out );
-    }
-
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableRuntimeException.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableRuntimeException.java
deleted file mode 100644
index 6910ce3..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/NestableRuntimeException.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-
-/**
- * The base class of all runtime exceptions which can contain other exceptions.
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class NestableRuntimeException extends RuntimeException implements Nestable
-{
-
-    static final long serialVersionUID = -833907851887600575L;
-
-    /**
-     * The helper instance which contains much of the code which we delegate to.
-     */
-    protected NestableDelegate delegate = new NestableDelegate( this );
-
-    /**
-     * Holds the reference to the exception or error that caused this exception
-     * to be thrown.
-     */
-    private Throwable cause = null;
-
-
-    /**
-     * Constructs a new <code>NestableRuntimeException</code> without
-     * specified detail message.
-     */
-    public NestableRuntimeException()
-    {
-        super();
-    }
-
-
-    /**
-     * Constructs a new <code>NestableRuntimeException</code> with specified
-     * detail message.
-     * 
-     * @param msg
-     *            the error message
-     */
-    public NestableRuntimeException(String msg)
-    {
-        super( msg );
-    }
-
-
-    /**
-     * Constructs a new <code>NestableRuntimeException</code> with specified
-     * nested <code>Throwable</code>.
-     * 
-     * @param cause
-     *            the exception or error that caused this exception to be thrown
-     */
-    public NestableRuntimeException(Throwable cause)
-    {
-        super();
-        this.cause = cause;
-    }
-
-
-    /**
-     * Constructs a new <code>NestableRuntimeException</code> with specified
-     * detail message and nested <code>Throwable</code>.
-     * 
-     * @param msg
-     *            the error message
-     * @param cause
-     *            the exception or error that caused this exception to be thrown
-     */
-    public NestableRuntimeException(String msg, Throwable cause)
-    {
-        super( msg );
-        this.cause = cause;
-    }
-
-
-    public Throwable getCause()
-    {
-        return cause;
-    }
-
-
-    /**
-     * Returns the detail message string of this throwable. If it was created
-     * with a null message, returns the following: (cause==null ? null :
-     * cause.toString()).
-     */
-    public String getMessage()
-    {
-        if ( super.getMessage() != null )
-        {
-            return super.getMessage();
-        }
-        else if ( cause != null )
-        {
-            return cause.toString();
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    public String getMessage( int index )
-    {
-        if ( index == 0 )
-        {
-            return super.getMessage();
-        }
-        else
-        {
-            return delegate.getMessage( index );
-        }
-    }
-
-
-    public String[] getMessages()
-    {
-        return delegate.getMessages();
-    }
-
-
-    public Throwable getThrowable( int index )
-    {
-        return delegate.getThrowable( index );
-    }
-
-
-    public int getThrowableCount()
-    {
-        return delegate.getThrowableCount();
-    }
-
-
-    public Throwable[] getThrowables()
-    {
-        return delegate.getThrowables();
-    }
-
-
-    public int indexOfThrowable( Class type )
-    {
-        return delegate.indexOfThrowable( type, 0 );
-    }
-
-
-    public int indexOfThrowable( Class type, int fromIndex )
-    {
-        return delegate.indexOfThrowable( type, fromIndex );
-    }
-
-
-    public void printStackTrace()
-    {
-        delegate.printStackTrace();
-    }
-
-
-    public void printStackTrace( PrintStream out )
-    {
-        delegate.printStackTrace( out );
-    }
-
-
-    public void printStackTrace( PrintWriter out )
-    {
-        delegate.printStackTrace( out );
-    }
-
-
-    public final void printPartialStackTrace( PrintWriter out )
-    {
-        super.printStackTrace( out );
-    }
-
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ObjectUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/ObjectUtils.java
deleted file mode 100644
index a4e602b..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ObjectUtils.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.io.Serializable;
-
-
-/**
- * <p>
- * Operations on <code>Object</code>.
- * </p>
- * <p>
- * This class tries to handle <code>null</code> input gracefully. An exception
- * will generally not be thrown for a <code>null</code> input. Each method
- * documents its behaviour in more detail.
- * </p>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class ObjectUtils
-{
-
-    /**
-     * <p>
-     * Singleton used as a <code>null</code> placeholder where
-     * <code>null</code> has another meaning.
-     * </p>
-     * <p>
-     * For example, in a <code>HashMap</code> the
-     * {@link java.util.HashMap#get(java.lang.Object)} method returns
-     * <code>null</code> if the <code>Map</code> contains <code>null</code>
-     * or if there is no matching key. The <code>Null</code> placeholder can
-     * be used to distinguish between these two cases.
-     * </p>
-     * <p>
-     * Another example is <code>Hashtable</code>, where <code>null</code>
-     * cannot be stored.
-     * </p>
-     * <p>
-     * This instance is Serializable.
-     * </p>
-     */
-    public static final Null NULL = new Null();
-
-
-    /**
-     * <p>
-     * <code>ObjectUtils</code> instances should NOT be constructed in
-     * standard programming. Instead, the class should be used as
-     * <code>ObjectUtils.defaultIfNull("a","b");</code>.
-     * </p>
-     * <p>
-     * This constructor is public to permit tools that require a JavaBean
-     * instance to operate.
-     * </p>
-     */
-    public ObjectUtils()
-    {
-    }
-
-
-    // Defaulting
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Returns a default value if the object passed is <code>null</code>.
-     * </p>
-     * 
-     * <pre>
-     *  ObjectUtils.defaultIfNull(null, null)      = null
-     *  ObjectUtils.defaultIfNull(null, &quot;&quot;)        = &quot;&quot;
-     *  ObjectUtils.defaultIfNull(null, &quot;zz&quot;)      = &quot;zz&quot;
-     *  ObjectUtils.defaultIfNull(&quot;abc&quot;, *)        = &quot;abc&quot;
-     *  ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
-     * </pre>
-     * 
-     * @param object
-     *            the <code>Object</code> to test, may be <code>null</code>
-     * @param defaultValue
-     *            the default value to return, may be <code>null</code>
-     * @return <code>object</code> if it is not <code>null</code>,
-     *         defaultValue otherwise
-     */
-    public static Object defaultIfNull( Object object, Object defaultValue )
-    {
-        return ( object != null ? object : defaultValue );
-    }
-
-
-    /**
-     * <p>
-     * Compares two objects for equality, where either one or both objects may
-     * be <code>null</code>.
-     * </p>
-     * 
-     * <pre>
-     *  ObjectUtils.equals(null, null)                  = true
-     *  ObjectUtils.equals(null, &quot;&quot;)                    = false
-     *  ObjectUtils.equals(&quot;&quot;, null)                    = false
-     *  ObjectUtils.equals(&quot;&quot;, &quot;&quot;)                      = true
-     *  ObjectUtils.equals(Boolean.TRUE, null)          = false
-     *  ObjectUtils.equals(Boolean.TRUE, &quot;true&quot;)        = false
-     *  ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE)  = true
-     *  ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false
-     * </pre>
-     * 
-     * @param object1
-     *            the first object, may be <code>null</code>
-     * @param object2
-     *            the second object, may be <code>null</code>
-     * @return <code>true</code> if the values of both objects are the same
-     */
-    public static boolean equals( Object object1, Object object2 )
-    {
-        if ( object1 == object2 )
-        {
-            return true;
-        }
-        if ( ( object1 == null ) || ( object2 == null ) )
-        {
-            return false;
-        }
-        return object1.equals( object2 );
-    }
-
-
-    /**
-     * <p>
-     * Gets the hash code of an object returning zero when the object is
-     * <code>null</code>.
-     * </p>
-     * 
-     * <pre>
-     *  ObjectUtils.hashCode(null)   = 0
-     *  ObjectUtils.hashCode(obj)    = obj.hashCode()
-     * </pre>
-     * 
-     * @param obj
-     *            the object to obtain the hash code of, may be
-     *            <code>null</code>
-     * @return the hash code of the object, or zero if null
-     * @since 2.1
-     */
-    public static int hashCode( Object obj )
-    {
-        return ( ( obj == null ) ? 0 : obj.hashCode() );
-    }
-
-
-    // Identity ToString
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Gets the toString that would be produced by <code>Object</code> if a
-     * class did not override toString itself. <code>null</code> will return
-     * <code>null</code>.
-     * </p>
-     * 
-     * <pre>
-     *  ObjectUtils.identityToString(null)         = null
-     *  ObjectUtils.identityToString(&quot;&quot;)           = &quot;java.lang.String@1e23&quot;
-     *  ObjectUtils.identityToString(Boolean.TRUE) = &quot;java.lang.Boolean@7fa&quot;
-     * </pre>
-     * 
-     * @param object
-     *            the object to create a toString for, may be <code>null</code>
-     * @return the default toString text, or <code>null</code> if
-     *         <code>null</code> passed in
-     */
-    public static String identityToString( Object object )
-    {
-        if ( object == null )
-        {
-            return null;
-        }
-        return appendIdentityToString( null, object ).toString();
-    }
-
-
-    /**
-     * <p>
-     * Appends the toString that would be produced by <code>Object</code> if a
-     * class did not override toString itself. <code>null</code> will return
-     * <code>null</code>.
-     * </p>
-     * 
-     * <pre>
-     *  ObjectUtils.appendIdentityToString(*, null)            = null
-     *  ObjectUtils.appendIdentityToString(null, &quot;&quot;)           = &quot;java.lang.String@1e23&quot;
-     *  ObjectUtils.appendIdentityToString(null, Boolean.TRUE) = &quot;java.lang.Boolean@7fa&quot;
-     *  ObjectUtils.appendIdentityToString(buf, Boolean.TRUE)  = buf.append(&quot;java.lang.Boolean@7fa&quot;)
-     * </pre>
-     * 
-     * @param buffer
-     *            the buffer to append to, may be <code>null</code>
-     * @param object
-     *            the object to create a toString for, may be <code>null</code>
-     * @return the default toString text, or <code>null</code> if
-     *         <code>null</code> passed in
-     * @since 2.0
-     */
-    public static StringBuffer appendIdentityToString( StringBuffer buffer, Object object )
-    {
-        if ( object == null )
-        {
-            return null;
-        }
-        if ( buffer == null )
-        {
-            buffer = new StringBuffer();
-        }
-        return buffer.append( object.getClass().getName() ).append( '@' ).append(
-            Integer.toHexString( System.identityHashCode( object ) ) );
-    }
-
-
-    // ToString
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Gets the <code>toString</code> of an <code>Object</code> returning an
-     * empty string ("") if <code>null</code> input.
-     * </p>
-     * 
-     * <pre>
-     *  ObjectUtils.toString(null)         = &quot;&quot;
-     *  ObjectUtils.toString(&quot;&quot;)           = &quot;&quot;
-     *  ObjectUtils.toString(&quot;bat&quot;)        = &quot;bat&quot;
-     *  ObjectUtils.toString(Boolean.TRUE) = &quot;true&quot;
-     * </pre>
-     * 
-     * @see String#valueOf(Object)
-     * @param obj
-     *            the Object to <code>toString</code>, may be null
-     * @return the passed in Object's toString, or nullStr if <code>null</code>
-     *         input
-     * @since 2.0
-     */
-    public static String toString( Object obj )
-    {
-        return ( obj == null ? "" : obj.toString() );
-    }
-
-
-    /**
-     * <p>
-     * Gets the <code>toString</code> of an <code>Object</code> returning a
-     * specified text if <code>null</code> input.
-     * </p>
-     * 
-     * <pre>
-     *  ObjectUtils.toString(null, null)           = null
-     *  ObjectUtils.toString(null, &quot;null&quot;)         = &quot;null&quot;
-     *  ObjectUtils.toString(&quot;&quot;, &quot;null&quot;)           = &quot;&quot;
-     *  ObjectUtils.toString(&quot;bat&quot;, &quot;null&quot;)        = &quot;bat&quot;
-     *  ObjectUtils.toString(Boolean.TRUE, &quot;null&quot;) = &quot;true&quot;
-     * </pre>
-     * 
-     * @see String#valueOf(Object)
-     * @param obj
-     *            the Object to <code>toString</code>, may be null
-     * @param nullStr
-     *            the String to return if <code>null</code> input, may be null
-     * @return the passed in Object's toString, or nullStr if <code>null</code>
-     *         input
-     * @since 2.0
-     */
-    public static String toString( Object obj, String nullStr )
-    {
-        return ( obj == null ? nullStr : obj.toString() );
-    }
-
-    // Null
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Class used as a null placeholder where <code>null</code> has another
-     * meaning.
-     * </p>
-     * <p>
-     * For example, in a <code>HashMap</code> the
-     * {@link java.util.HashMap#get(java.lang.Object)} method returns
-     * <code>null</code> if the <code>Map</code> contains <code>null</code>
-     * or if there is no matching key. The <code>Null</code> placeholder can
-     * be used to distinguish between these two cases.
-     * </p>
-     * <p>
-     * Another example is <code>Hashtable</code>, where <code>null</code>
-     * cannot be stored.
-     * </p>
-     */
-    public static class Null implements Serializable
-    {
-        // declare serialization compatibility with Commons Lang 1.0
-        private static final long serialVersionUID = 7092611880189329093L;
-
-
-        /**
-         * Restricted constructor - singleton.
-         */
-        Null()
-        {
-        }
-
-
-        /**
-         * <p>
-         * Ensure singleton.
-         * </p>
-         * 
-         * @return the singleton value
-         */
-        private Object readResolve()
-        {
-            return ObjectUtils.NULL;
-        }
-    }
-
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ParserPipedInputStream.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/ParserPipedInputStream.java
deleted file mode 100644
index 6e28840..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ParserPipedInputStream.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.io.PipedInputStream;
-import java.io.IOException;
-
-
-/**
- * A piped input stream that fixes the "Read end Dead" issue when a single
- * thread is used.
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$
- */
-public class ParserPipedInputStream extends PipedInputStream
-{
-    protected synchronized void receive( int b ) throws IOException
-    {
-        while ( in == out )
-        {
-            /* full: kick any waiting readers */
-            notifyAll();
-            try
-            {
-                wait( 1000 );
-            }
-            catch ( InterruptedException ex )
-            {
-                throw new java.io.InterruptedIOException();
-            }
-        }
-
-        if ( in < 0 )
-        {
-            in = 0;
-            out = 0;
-        }
-
-        buffer[in++] = ( byte ) ( b & 0xFF );
-
-        if ( in >= buffer.length )
-        {
-            in = 0;
-        }
-    }
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/PreferencesDictionary.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/PreferencesDictionary.java
index b8fd4a1..de3aa3b 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/PreferencesDictionary.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/util/PreferencesDictionary.java
@@ -25,6 +25,7 @@
 import java.util.prefs.Preferences;
 import java.util.prefs.BackingStoreException;
 
+import org.apache.commons.lang.exception.NestableRuntimeException;
 import org.apache.directory.shared.i18n.I18n;
 
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/PropertiesUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/PropertiesUtils.java
index a340f60..3ce88eb 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/PropertiesUtils.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/util/PropertiesUtils.java
@@ -20,11 +20,10 @@
 package org.apache.directory.shared.ldap.util;
 
 
-
 import java.io.File;
-import java.io.InputStream;
-import java.io.IOException;
 import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Properties;
@@ -116,6 +115,8 @@
      *            a class to use for relative path references
      * @return the static properties
      */
+    // This will suppress PMD.EmptyCatchBlock warnings in this method
+    @SuppressWarnings("PMD.EmptyCatchBlock")
     public static Properties getStaticProperties( Class<?> ref )
     {
         final Properties properties = new Properties();
@@ -133,6 +134,20 @@
             {
                 return properties;
             }
+            finally
+            {
+                if ( input != null )
+                {
+                    try
+                    {
+                        input.close();
+                    }
+                    catch ( IOException e )
+                    {
+                        // Empty catch, we can't more than trying to close
+                    }
+                }
+            }
         }
 
         return properties;
@@ -148,6 +163,8 @@
      *            the relative path to the resoruce
      * @return the static properties
      */
+    // This will suppress PMD.EmptyCatchBlock warnings in this method
+    @SuppressWarnings("PMD.EmptyCatchBlock")
     public static Properties getStaticProperties( Class<?> ref, String path )
     {
         Properties properties = new Properties();
@@ -166,6 +183,20 @@
         {
             return properties;
         }
+        finally
+        {
+            if ( input != null )
+            {
+                try
+                {
+                    input.close();
+                }
+                catch ( IOException e )
+                {
+                    // Empty catch, we can't more than trying to close
+                }
+            }
+        }
 
         return properties;
     }
@@ -222,6 +253,8 @@
      *            the path to the resource
      * @return the loaded or new Properties
      */
+    // This will suppress PMD.EmptyCatchBlock warnings in this method
+    @SuppressWarnings("PMD.EmptyCatchBlock")
     public static Properties getProperties( ClassLoader classloader, String path )
     {
         Properties properties = new Properties();
@@ -237,6 +270,20 @@
             {
                 return properties;
             }
+            finally
+            {
+                if ( input != null )
+                {
+                    try
+                    {
+                        input.close();
+                    }
+                    catch ( IOException e )
+                    {
+                        // Empty catch, we can't more than trying to close
+                    }
+                }
+            }
         }
 
         return properties;
@@ -253,6 +300,8 @@
      *            the relative path to the resource
      * @return the loaded or new Properties
      */
+    // This will suppress PMD.EmptyCatchBlock warnings in this method
+    @SuppressWarnings("PMD.EmptyCatchBlock")
     public static Properties getProperties( Class<?> clazz, String path )
     {
         Properties properties = new Properties();
@@ -268,6 +317,20 @@
             {
                 return properties;
             }
+            finally
+            {
+                if ( input != null )
+                {
+                    try
+                    {
+                        input.close();
+                    }
+                    catch ( IOException e )
+                    {
+                        // Empty catch, we can't more than trying to close
+                    }
+                }
+            }
         }
 
         return properties;
@@ -309,7 +372,7 @@
         }
 
         Enumeration<?> list = expanded.propertyNames();
-        
+
         while ( list.hasMoreElements() )
         {
             String key = ( String ) list.nextElement();
@@ -416,13 +479,13 @@
         /*
          * H A N D L E S I N G L E V A L U E D K E Y S
          */
-        for ( Object key:keys.keySet() )
+        for ( Object key : keys.keySet() )
         {
-            String value = discover( (String)key, sources, haltOnDiscovery );
+            String value = discover( ( String ) key, sources, haltOnDiscovery );
 
             if ( value != null )
             {
-                keys.setProperty( (String)key, value );
+                keys.setProperty( ( String ) key, value );
             }
         }
     }
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ReflectionToStringBuilder.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/ReflectionToStringBuilder.java
deleted file mode 100644
index ffad8e6..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ReflectionToStringBuilder.java
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.directory.shared.i18n.I18n;
-
-
-/**
- * <p>
- * Assists in implementing {@link Object#toString()}methods using reflection.
- * </p>
- * <p>
- * This class uses reflection to determine the fields to append. Because these
- * fields are usually private, the class uses
- * {@link java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[], boolean)}
- * to change the visibility of the fields. This will fail under a security
- * manager, unless the appropriate permissions are set up correctly.
- * </p>
- * <p>
- * A typical invocation for this method would look like:
- * </p>
- * 
- * <pre>
- * public String toString()
- * {
- *     return ReflectionToStringBuilder.toString( this );
- * }
- * </pre>
- * 
- * <p>
- * You can also use the builder to debug 3rd party objects:
- * </p>
- * 
- * <pre>
- * System.out.println( &quot;An object: &quot; + ReflectionToStringBuilder.toString( anObject ) );
- * </pre>
- * 
- * <p>
- * A subclass can control field output by overriding the methods:
- * <ul>
- * <li>{@link #accept(java.lang.reflect.Field)}</li>
- * <li>{@link #getValue(java.lang.reflect.Field)}</li>
- * </ul>
- * </p>
- * <p>
- * For example, this method does <i>not</i> include the <code>password</code>
- * field in the returned <code>String</code>:
- * </p>
- * 
- * <pre>
- * public String toString()
- * {
- *     return ( new ReflectionToStringBuilder( this )
- *     {
- *         protected boolean accept( Field f )
- *         {
- *             return super.accept( f ) &amp;&amp; !f.getName().equals( &quot;password&quot; );
- *         }
- *     } ).toString();
- * }
- * </pre>
- * 
- * <p>
- * The exact format of the <code>toString</code> is determined by the
- * {@link ToStringStyle} passed into the constructor.
- * </p>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class ReflectionToStringBuilder extends ToStringBuilder
-{
-    /**
-     * <p>
-     * A registry of objects used by <code>reflectionToString</code> methods
-     * to detect cyclical object references and avoid infinite loops.
-     * </p>
-     */
-    private static ThreadLocal registry = new ThreadLocal()
-    {
-        protected synchronized Object initialValue()
-        {
-            // The HashSet implementation is not synchronized,
-            // which is just what we need here.
-            return new HashSet();
-        }
-    };
-
-
-    /**
-     * <p>
-     * Returns the registry of objects being traversed by the
-     * <code>reflectionToString</code> methods in the current thread.
-     * </p>
-     * 
-     * @return Set the registry of objects being traversed
-     */
-    static Set getRegistry()
-    {
-        return ( Set ) registry.get();
-    }
-
-
-    /**
-     * <p>
-     * Returns <code>true</code> if the registry contains the given object.
-     * Used by the reflection methods to avoid infinite loops.
-     * </p>
-     * 
-     * @param value
-     *            The object to lookup in the registry.
-     * @return boolean <code>true</code> if the registry contains the given
-     *         object.
-     */
-    static boolean isRegistered( Object value )
-    {
-        return getRegistry().contains( value );
-    }
-
-
-    /**
-     * <p>
-     * Registers the given object. Used by the reflection methods to avoid
-     * infinite loops.
-     * </p>
-     * 
-     * @param value
-     *            The object to register.
-     */
-    static void register( Object value )
-    {
-        getRegistry().add( value );
-    }
-
-
-    /**
-     * <p>
-     * This method uses reflection to build a suitable <code>toString</code>
-     * using the default <code>ToStringStyle</code>.
-     * <p>
-     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
-     * private fields. This means that it will throw a security exception if run
-     * under a security manager, if the permissions are not set up correctly. It
-     * is also not as efficient as testing explicitly.
-     * </p>
-     * <p>
-     * Transient members will be not be included, as they are likely derived.
-     * Static fields will not be included. Superclass fields will be appended.
-     * </p>
-     * 
-     * @param object
-     *            the Object to be output
-     * @return the String result
-     * @throws IllegalArgumentException
-     *             if the Object is <code>null</code>
-     */
-    public static String toString( Object object )
-    {
-        return toString( object, null, false, false, null );
-    }
-
-
-    /**
-     * <p>
-     * This method uses reflection to build a suitable <code>toString</code>.
-     * </p>
-     * <p>
-     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
-     * private fields. This means that it will throw a security exception if run
-     * under a security manager, if the permissions are not set up correctly. It
-     * is also not as efficient as testing explicitly.
-     * </p>
-     * <p>
-     * Transient members will be not be included, as they are likely derived.
-     * Static fields will not be included. Superclass fields will be appended.
-     * </p>
-     * <p>
-     * If the style is <code>null</code>, the default
-     * <code>ToStringStyle</code> is used.
-     * </p>
-     * 
-     * @param object
-     *            the Object to be output
-     * @param style
-     *            the style of the <code>toString</code> to create, may be
-     *            <code>null</code>
-     * @return the String result
-     * @throws IllegalArgumentException
-     *             if the Object or <code>ToStringStyle</code> is
-     *             <code>null</code>
-     */
-    public static String toString( Object object, ToStringStyle style )
-    {
-        return toString( object, style, false, false, null );
-    }
-
-
-    /**
-     * <p>
-     * This method uses reflection to build a suitable <code>toString</code>.
-     * </p>
-     * <p>
-     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
-     * private fields. This means that it will throw a security exception if run
-     * under a security manager, if the permissions are not set up correctly. It
-     * is also not as efficient as testing explicitly.
-     * </p>
-     * <p>
-     * If the <code>outputTransients</code> is <code>true</code>, transient
-     * members will be output, otherwise they are ignored, as they are likely
-     * derived fields, and not part of the value of the Object.
-     * </p>
-     * <p>
-     * Static fields will not be included. Superclass fields will be appended.
-     * </p>
-     * <p>
-     * If the style is <code>null</code>, the default
-     * <code>ToStringStyle</code> is used.
-     * </p>
-     * 
-     * @param object
-     *            the Object to be output
-     * @param style
-     *            the style of the <code>toString</code> to create, may be
-     *            <code>null</code>
-     * @param outputTransients
-     *            whether to include transient fields
-     * @return the String result
-     * @throws IllegalArgumentException
-     *             if the Object is <code>null</code>
-     */
-    public static String toString( Object object, ToStringStyle style, boolean outputTransients )
-    {
-        return toString( object, style, outputTransients, false, null );
-    }
-
-
-    /**
-     * <p>
-     * This method uses reflection to build a suitable <code>toString</code>.
-     * </p>
-     * <p>
-     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
-     * private fields. This means that it will throw a security exception if run
-     * under a security manager, if the permissions are not set up correctly. It
-     * is also not as efficient as testing explicitly.
-     * </p>
-     * <p>
-     * If the <code>outputTransients</code> is <code>true</code>, transient
-     * fields will be output, otherwise they are ignored, as they are likely
-     * derived fields, and not part of the value of the Object.
-     * </p>
-     * <p>
-     * If the <code>outputStatics</code> is <code>true</code>, static
-     * fields will be output, otherwise they are ignored.
-     * </p>
-     * <p>
-     * Static fields will not be included. Superclass fields will be appended.
-     * </p>
-     * <p>
-     * If the style is <code>null</code>, the default
-     * <code>ToStringStyle</code> is used.
-     * </p>
-     * 
-     * @param object
-     *            the Object to be output
-     * @param style
-     *            the style of the <code>toString</code> to create, may be
-     *            <code>null</code>
-     * @param outputTransients
-     *            whether to include transient fields
-     * @param outputStatics
-     *            whether to include transient fields
-     * @return the String result
-     * @throws IllegalArgumentException
-     *             if the Object is <code>null</code>
-     */
-    public static String toString( Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics )
-    {
-        return toString( object, style, outputTransients, outputStatics, null );
-    }
-
-
-    /**
-     * <p>
-     * This method uses reflection to build a suitable <code>toString</code>.
-     * </p>
-     * <p>
-     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
-     * private fields. This means that it will throw a security exception if run
-     * under a security manager, if the permissions are not set up correctly. It
-     * is also not as efficient as testing explicitly.
-     * </p>
-     * <p>
-     * If the <code>outputTransients</code> is <code>true</code>, transient
-     * fields will be output, otherwise they are ignored, as they are likely
-     * derived fields, and not part of the value of the Object.
-     * </p>
-     * <p>
-     * If the <code>outputStatics</code> is <code>true</code>, static
-     * fields will be output, otherwise they are ignored.
-     * </p>
-     * <p>
-     * Superclass fields will be appended up to and including the specified
-     * superclass. A null superclass is treated as <code>java.lang.Object</code>.
-     * </p>
-     * <p>
-     * If the style is <code>null</code>, the default
-     * <code>ToStringStyle</code> is used.
-     * </p>
-     * 
-     * @param object
-     *            the Object to be output
-     * @param style
-     *            the style of the <code>toString</code> to create, may be
-     *            <code>null</code>
-     * @param outputTransients
-     *            whether to include transient fields
-     * @param outputStatics
-     *            whether to include static fields
-     * @param reflectUpToClass
-     *            the superclass to reflect up to (inclusive), may be
-     *            <code>null</code>
-     * @return the String result
-     * @throws IllegalArgumentException
-     *             if the Object is <code>null</code>
-     */
-    public static String toString( Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics,
-        Class reflectUpToClass )
-    {
-        return new ReflectionToStringBuilder( object, style, null, reflectUpToClass, outputTransients, outputStatics )
-            .toString();
-    }
-
-
-    /**
-     * <p>
-     * This method uses reflection to build a suitable <code>toString</code>.
-     * </p>
-     * <p>
-     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
-     * private fields. This means that it will throw a security exception if run
-     * under a security manager, if the permissions are not set up correctly. It
-     * is also not as efficient as testing explicitly.
-     * </p>
-     * <p>
-     * If the <code>outputTransients</code> is <code>true</code>, transient
-     * members will be output, otherwise they are ignored, as they are likely
-     * derived fields, and not part of the value of the Object.
-     * </p>
-     * <p>
-     * Static fields will not be included. Superclass fields will be appended up
-     * to and including the specified superclass. A null superclass is treated
-     * as <code>java.lang.Object</code>.
-     * </p>
-     * <p>
-     * If the style is <code>null</code>, the default
-     * <code>ToStringStyle</code> is used.
-     * </p>
-     * 
-     * @deprecated Use
-     *             {@link #toString(Object,ToStringStyle,boolean,boolean,Class)}
-     * @param object
-     *            the Object to be output
-     * @param style
-     *            the style of the <code>toString</code> to create, may be
-     *            <code>null</code>
-     * @param outputTransients
-     *            whether to include transient fields
-     * @param reflectUpToClass
-     *            the superclass to reflect up to (inclusive), may be
-     *            <code>null</code>
-     * @return the String result
-     * @throws IllegalArgumentException
-     *             if the Object is <code>null</code>
-     */
-    public static String toString( Object object, ToStringStyle style, boolean outputTransients, Class reflectUpToClass )
-    {
-        return new ReflectionToStringBuilder( object, style, null, reflectUpToClass, outputTransients ).toString();
-    }
-
-
-    /**
-     * <p>
-     * Unregisters the given object.
-     * </p>
-     * <p>
-     * Used by the reflection methods to avoid infinite loops.
-     * </p>
-     * 
-     * @param value
-     *            The object to unregister.
-     */
-    static void unregister( Object value )
-    {
-        getRegistry().remove( value );
-    }
-
-    /**
-     * Whether or not to append static fields.
-     */
-    private boolean appendStatics = false;
-
-    /**
-     * Whether or not to append transient fields.
-     */
-    private boolean appendTransients = false;
-
-    /**
-     * The last super class to stop appending fields for.
-     */
-    private Class upToClass = null;
-
-
-    /**
-     * <p>
-     * Constructor.
-     * </p>
-     * <p>
-     * This constructor outputs using the default style set with
-     * <code>setDefaultStyle</code>.
-     * </p>
-     * 
-     * @param object
-     *            the Object to build a <code>toString</code> for, must not be
-     *            <code>null</code>
-     * @throws IllegalArgumentException
-     *             if the Object passed in is <code>null</code>
-     */
-    public ReflectionToStringBuilder(Object object)
-    {
-        super( object );
-    }
-
-
-    /**
-     * <p>
-     * Constructor.
-     * </p>
-     * <p>
-     * If the style is <code>null</code>, the default style is used.
-     * </p>
-     * 
-     * @param object
-     *            the Object to build a <code>toString</code> for, must not be
-     *            <code>null</code>
-     * @param style
-     *            the style of the <code>toString</code> to create, may be
-     *            <code>null</code>
-     * @throws IllegalArgumentException
-     *             if the Object passed in is <code>null</code>
-     */
-    public ReflectionToStringBuilder(Object object, ToStringStyle style)
-    {
-        super( object, style );
-    }
-
-
-    /**
-     * <p>
-     * Constructor.
-     * </p>
-     * <p>
-     * If the style is <code>null</code>, the default style is used.
-     * </p>
-     * <p>
-     * If the buffer is <code>null</code>, a new one is created.
-     * </p>
-     * 
-     * @param object
-     *            the Object to build a <code>toString</code> for
-     * @param style
-     *            the style of the <code>toString</code> to create, may be
-     *            <code>null</code>
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate, may be
-     *            <code>null</code>
-     * @throws IllegalArgumentException
-     *             if the Object passed in is <code>null</code>
-     */
-    public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer)
-    {
-        super( object, style, buffer );
-    }
-
-
-    /**
-     * Constructor.
-     * 
-     * @deprecated Use
-     *             {@link #ReflectionToStringBuilder(Object,ToStringStyle,StringBuffer,Class,boolean,boolean)}.
-     * @param object
-     *            the Object to build a <code>toString</code> for
-     * @param style
-     *            the style of the <code>toString</code> to create, may be
-     *            <code>null</code>
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate, may be
-     *            <code>null</code>
-     * @param reflectUpToClass
-     *            the superclass to reflect up to (inclusive), may be
-     *            <code>null</code>
-     * @param outputTransients
-     *            whether to include transient fields
-     */
-    public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer, Class reflectUpToClass,
-        boolean outputTransients)
-    {
-        super( object, style, buffer );
-        this.setUpToClass( reflectUpToClass );
-        this.setAppendTransients( outputTransients );
-    }
-
-
-    /**
-     * Constructor.
-     * 
-     * @param object
-     *            the Object to build a <code>toString</code> for
-     * @param style
-     *            the style of the <code>toString</code> to create, may be
-     *            <code>null</code>
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate, may be
-     *            <code>null</code>
-     * @param reflectUpToClass
-     *            the superclass to reflect up to (inclusive), may be
-     *            <code>null</code>
-     * @param outputTransients
-     *            whether to include transient fields
-     * @param outputStatics
-     *            whether to include static fields
-     */
-    public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer, Class reflectUpToClass,
-        boolean outputTransients, boolean outputStatics)
-    {
-        super( object, style, buffer );
-        this.setUpToClass( reflectUpToClass );
-        this.setAppendTransients( outputTransients );
-        this.setAppendStatics( outputStatics );
-    }
-
-
-    /**
-     * Returns whether or not to append the given <code>Field</code>.
-     * <ul>
-     * <li>Transient fields are appended only if {@link #isAppendTransients()}
-     * returns <code>true</code>.
-     * <li>Static fields are appended only if {@link #isAppendStatics()}
-     * returns <code>true</code>.
-     * <li>Inner class fields are not appened.</li>
-     * </ul>
-     * 
-     * @param field
-     *            The Field to test.
-     * @return Whether or not to append the given <code>Field</code>.
-     */
-    protected boolean accept( Field field )
-    {
-        if ( field.getName().indexOf( '$' ) != -1 )
-        {
-            // Reject field from inner class.
-            return false;
-        }
-        if ( Modifier.isTransient( field.getModifiers() ) && !this.isAppendTransients() )
-        {
-            // transients.
-            return false;
-        }
-        if ( Modifier.isStatic( field.getModifiers() ) && !this.isAppendStatics() )
-        {
-            // transients.
-            return false;
-        }
-        return true;
-    }
-
-
-    /**
-     * <p>
-     * Appends the fields and values defined by the given object of the given
-     * Class.
-     * </p>
-     * <p>
-     * If a cycle is detected as an object is &quot;toString()'ed&quot;, such an
-     * object is rendered as if <code>Object.toString()</code> had been called
-     * and not implemented by the object.
-     * </p>
-     * 
-     * @param clazz
-     *            The class of object parameter
-     */
-    protected void appendFieldsIn( Class clazz )
-    {
-        if ( isRegistered( this.getObject() ) )
-        {
-            // The object has already been appended, therefore we have an
-            // object cycle.
-            // Append a simple Object.toString style string. The field name is
-            // already appended at this point.
-            this.appendAsObjectToString( this.getObject() );
-            return;
-        }
-        try
-        {
-            this.registerObject();
-            if ( clazz.isArray() )
-            {
-                this.reflectionAppendArray( this.getObject() );
-                return;
-            }
-            Field[] fields = clazz.getDeclaredFields();
-            AccessibleObject.setAccessible( fields, true );
-            for ( int i = 0; i < fields.length; i++ )
-            {
-                Field field = fields[i];
-                String fieldName = field.getName();
-                if ( this.accept( field ) )
-                {
-                    try
-                    {
-                        // Warning: Field.get(Object) creates wrappers objects
-                        // for primitive types.
-                        Object fieldValue = this.getValue( field );
-                        if ( isRegistered( fieldValue ) && !field.getType().isPrimitive() )
-                        {
-                            // A known field value has already been appended,
-                            // therefore we have an object cycle,
-                            // append a simple Object.toString style string.
-                            this.getStyle().appendFieldStart( this.getStringBuffer(), fieldName );
-                            this.appendAsObjectToString( fieldValue );
-                            // The recursion out of
-                            // builder.append(fieldName, fieldValue);
-                            // below will append the field
-                            // end marker.
-                        }
-                        else
-                        {
-                            try
-                            {
-                                this.registerObject();
-                                this.append( fieldName, fieldValue );
-                            }
-                            finally
-                            {
-                                this.unregisterObject();
-                            }
-                        }
-                    }
-                    catch ( IllegalAccessException ex )
-                    {
-                        // this can't happen. Would get a Security exception
-                        // instead
-                        // throw a runtime exception in case the impossible
-                        // happens.
-                        throw new InternalError( I18n.err( I18n.ERR_04424, ex.getLocalizedMessage() ) );
-                    }
-                }
-            }
-        }
-        finally
-        {
-            this.unregisterObject();
-        }
-    }
-
-
-    /**
-     * <p>
-     * Gets the last super class to stop appending fields for.
-     * </p>
-     * 
-     * @return The last super class to stop appending fields for.
-     */
-    public Class getUpToClass()
-    {
-        return this.upToClass;
-    }
-
-
-    /**
-     * <p>
-     * Calls <code>java.lang.reflect.Field.get(Object)</code>.
-     * </p>
-     * 
-     * @param field
-     *            The Field to query.
-     * @return The Object from the given Field.
-     * @throws IllegalArgumentException
-     *             see {@link java.lang.reflect.Field#get(Object)}
-     * @throws IllegalAccessException
-     *             see {@link java.lang.reflect.Field#get(Object)}
-     * @see java.lang.reflect.Field#get(Object)
-     */
-    protected Object getValue( Field field ) throws IllegalArgumentException, IllegalAccessException
-    {
-        return field.get( this.getObject() );
-    }
-
-
-    /**
-     * <p>
-     * Gets whether or not to append static fields.
-     * </p>
-     * 
-     * @return Whether or not to append static fields.
-     */
-    public boolean isAppendStatics()
-    {
-        return this.appendStatics;
-    }
-
-
-    /**
-     * <p>
-     * Gets whether or not to append transient fields.
-     * </p>
-     * 
-     * @return Whether or not to append transient fields.
-     */
-    public boolean isAppendTransients()
-    {
-        return this.appendTransients;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code> array.
-     * </p>
-     * 
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder reflectionAppendArray( Object array )
-    {
-        this.getStyle().reflectionAppendArrayDetail( this.getStringBuffer(), null, array );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Registers this builder's source object to avoid infinite loops when
-     * processing circular object references.
-     * </p>
-     */
-    void registerObject()
-    {
-        register( this.getObject() );
-    }
-
-
-    /**
-     * <p>
-     * Sets whether or not to append static fields.
-     * </p>
-     * 
-     * @param appendStatics
-     *            Whether or not to append static fields.
-     */
-    public void setAppendStatics( boolean appendStatics )
-    {
-        this.appendStatics = appendStatics;
-    }
-
-
-    /**
-     * <p>
-     * Sets whether or not to append transient fields.
-     * </p>
-     * 
-     * @param appendTransients
-     *            Whether or not to append transient fields.
-     */
-    public void setAppendTransients( boolean appendTransients )
-    {
-        this.appendTransients = appendTransients;
-    }
-
-
-    /**
-     * <p>
-     * Sets the last super class to stop appending fields for.
-     * </p>
-     * 
-     * @param clazz
-     *            The last super class to stop appending fields for.
-     */
-    public void setUpToClass( Class clazz )
-    {
-        this.upToClass = clazz;
-    }
-
-
-    /**
-     * <p>
-     * Gets the String built by this builder.
-     * </p>
-     * 
-     * @return the built string
-     */
-    public String toString()
-    {
-        if ( this.getObject() == null )
-        {
-            return this.getStyle().getNullText();
-        }
-        Class clazz = this.getObject().getClass();
-        this.appendFieldsIn( clazz );
-        while ( clazz.getSuperclass() != null && clazz != this.getUpToClass() )
-        {
-            clazz = clazz.getSuperclass();
-            this.appendFieldsIn( clazz );
-        }
-        return super.toString();
-    }
-
-
-    /**
-     * <p>
-     * Unregisters this builder's source object to avoid infinite loops when
-     * processing circular object references.
-     * </p>
-     */
-    void unregisterObject()
-    {
-        unregister( this.getObject() );
-    }
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/SequencedHashMap.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/SequencedHashMap.java
index 4d4280c..ef80d15 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/SequencedHashMap.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/util/SequencedHashMap.java
@@ -37,6 +37,7 @@
 import java.util.NoSuchElementException;
 import java.util.Set;
 
+import org.apache.commons.collections.KeyValue;
 import org.apache.directory.shared.i18n.I18n;
 
 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/SpringClassUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/SpringClassUtils.java
deleted file mode 100644
index 64fd8df..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/SpringClassUtils.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-
-package org.apache.directory.shared.ldap.util;
-
-
-import java.beans.Introspector;
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashSet;
-import java.util.Set;
-
-
-/**
- * Miscellaneous class utility methods. Mainly for internal use within the
- * framework; consider Jakarta's Commons Lang for a more comprehensive suite
- * of utilities.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public abstract class SpringClassUtils
-{
-
-    /** Suffix for array class names */
-    public static final String ARRAY_SUFFIX = "[]";
-
-    /** All primitive classes */
-    private static Class[] PRIMITIVE_CLASSES =
-        { boolean.class, byte.class, char.class, short.class, int.class, long.class, float.class, double.class };
-
-    /** The package separator character '.' */
-    private static final char PACKAGE_SEPARATOR_CHAR = '.';
-
-    /** The inner class separator character '$' */
-    private static final char INNER_CLASS_SEPARATOR_CHAR = '$';
-
-    /** The CGLIB class separator character "$$" */
-    private static final String CGLIB_CLASS_SEPARATOR_CHAR = "$$";
-
-
-    /**
-     * Return a default ClassLoader to use (never <code>null</code>).
-     * Returns the thread context ClassLoader, if available.
-     * The ClassLoader that loaded the ClassUtils class will be used as fallback.
-     * <p>Call this method if you intend to use the thread context ClassLoader
-     * in a scenario where you absolutely need a non-null ClassLoader reference:
-     * for example, for class path resource loading (but not necessarily for
-     * <code>Class.forName</code>, which accepts a <code>null</code> ClassLoader
-     * reference as well).
-     * @see java.lang.Thread#getContextClassLoader()
-     */
-    public static ClassLoader getDefaultClassLoader()
-    {
-        ClassLoader cl = Thread.currentThread().getContextClassLoader();
-        if ( cl == null )
-        {
-            // No thread context class loader -> use class loader of this class.
-            cl = SpringClassUtils.class.getClassLoader();
-        }
-        return cl;
-    }
-
-
-    /**
-     * Replacement for <code>Class.forName()</code> that also returns Class instances
-     * for primitives (like "int") and array class names (like "String[]").
-     * <p>Always uses the thread context class loader.
-     * @param name the name of the Class
-     * @return Class instance for the supplied name
-     * @see java.lang.Class#forName(String, boolean, ClassLoader)
-     * @see java.lang.Thread#getContextClassLoader()
-     */
-    public static Class forName( String name ) throws ClassNotFoundException
-    {
-        return forName( name, Thread.currentThread().getContextClassLoader() );
-    }
-
-
-    /**
-     * Replacement for <code>Class.forName()</code> that also returns Class instances
-     * for primitives (like "int") and array class names (like "String[]").
-     * @param name the name of the Class
-     * @param classLoader the class loader to use
-     * @return Class instance for the supplied name
-     * @see java.lang.Class#forName(String, boolean, ClassLoader)
-     * @see java.lang.Thread#getContextClassLoader()
-     */
-    public static Class forName( String name, ClassLoader classLoader ) throws ClassNotFoundException
-    {
-        Class clazz = resolvePrimitiveClassName( name );
-        if ( clazz != null )
-        {
-            return clazz;
-        }
-        if ( name.endsWith( ARRAY_SUFFIX ) )
-        {
-            // special handling for array class names
-            String elementClassName = name.substring( 0, name.length() - ARRAY_SUFFIX.length() );
-            Class elementClass = SpringClassUtils.forName( elementClassName, classLoader );
-            return Array.newInstance( elementClass, 0 ).getClass();
-        }
-        return Class.forName( name, true, classLoader );
-    }
-
-
-    /**
-     * Resolve the given class name as primitive class, if appropriate.
-     * @param name the name of the potentially primitive class
-     * @return the primitive class, or <code>null</code> if the name does not denote
-     * a primitive class
-     */
-    public static Class resolvePrimitiveClassName( String name )
-    {
-        // Most class names will be quite long, considering that they
-        // SHOULD sit in a package, so a length check is worthwhile.
-        if ( name.length() <= 8 )
-        {
-            // could be a primitive - likely
-            for ( int i = 0; i < PRIMITIVE_CLASSES.length; i++ )
-            {
-                Class clazz = PRIMITIVE_CLASSES[i];
-                if ( clazz.getName().equals( name ) )
-                {
-                    return clazz;
-                }
-            }
-        }
-        return null;
-    }
-
-
-    /**
-     * Return the short string name of a Java class in decapitalized
-     * JavaBeans property format.
-     * @param clazz the class
-     * @return the short name rendered in a standard JavaBeans property format
-     * @see java.beans.Introspector#decapitalize(String)
-     */
-    public static String getShortNameAsProperty( Class clazz )
-    {
-        return Introspector.decapitalize( getShortName( clazz ) );
-    }
-
-
-    /**
-     * Get the class name without the qualified package name.
-     * @param clazz the class to get the short name for
-     * @return the class name of the class without the package name
-     * @throws IllegalArgumentException if the class is null
-     */
-    public static String getShortName( Class clazz )
-    {
-        return getShortName( clazz.getName() );
-    }
-
-
-    /**
-     * Get the class name without the qualified package name.
-     * @param className the className to get the short name for
-     * @return the class name of the class without the package name
-     * @throws IllegalArgumentException if the className is empty
-     */
-    public static String getShortName( String className )
-    {
-        //Assert.hasLength(className, "class name must not be empty");
-        int lastDotIndex = className.lastIndexOf( PACKAGE_SEPARATOR_CHAR );
-        int nameEndIndex = className.indexOf( CGLIB_CLASS_SEPARATOR_CHAR );
-        if ( nameEndIndex == -1 )
-        {
-            nameEndIndex = className.length();
-        }
-        String shortName = className.substring( lastDotIndex + 1, nameEndIndex );
-        shortName = shortName.replace( INNER_CLASS_SEPARATOR_CHAR, PACKAGE_SEPARATOR_CHAR );
-        return shortName;
-    }
-
-
-    /**
-     * Return the qualified name of the given method, consisting of
-     * fully qualified interface/class name + "." + method name.
-     * @param method the method
-     * @return the qualified name of the method
-     */
-    public static String getQualifiedMethodName( Method method )
-    {
-        //Assert.notNull(method, "Method must not be empty");
-        return method.getDeclaringClass().getName() + "." + method.getName();
-    }
-
-
-    /**
-     * Determine whether the given class has a method with the given signature.
-     * Essentially translates <code>NoSuchMethodException</code> to "false".
-     * @param clazz the clazz to analyze
-     * @param methodName the name of the method
-     * @param paramTypes the parameter types of the method
-     */
-    public static boolean hasMethod( Class clazz, String methodName, Class[] paramTypes )
-    {
-        try
-        {
-            clazz.getMethod( methodName, paramTypes );
-            return true;
-        }
-        catch ( NoSuchMethodException ex )
-        {
-            return false;
-        }
-    }
-
-
-    /**
-     * Return the number of methods with a given name (with any argument types),
-     * for the given class and/or its superclasses. Includes non-public methods.
-     * @param clazz the clazz to check
-     * @param methodName the name of the method
-     * @return the number of methods with the given name
-     */
-    public static int getMethodCountForName( Class clazz, String methodName )
-    {
-        int count = 0;
-        do
-        {
-            for ( int i = 0; i < clazz.getDeclaredMethods().length; i++ )
-            {
-                Method method = clazz.getDeclaredMethods()[i];
-                if ( methodName.equals( method.getName() ) )
-                {
-                    count++;
-                }
-            }
-            clazz = clazz.getSuperclass();
-        }
-        while ( clazz != null );
-        return count;
-    }
-
-
-    /**
-     * Does the given class and/or its superclasses at least have one or more
-     * methods (with any argument types)? Includes non-public methods.
-     * @param clazz the clazz to check
-     * @param methodName the name of the method
-     * @return whether there is at least one method with the given name
-     */
-    public static boolean hasAtLeastOneMethodWithName( Class clazz, String methodName )
-    {
-        do
-        {
-            for ( int i = 0; i < clazz.getDeclaredMethods().length; i++ )
-            {
-                Method method = clazz.getDeclaredMethods()[i];
-                
-                if ( methodName.equals( method.getName() ) )
-                {
-                    return true;
-                }
-            }
-            clazz = clazz.getSuperclass();
-        }
-        while ( clazz != null );
-        
-        return false;
-    }
-
-
-    /**
-     * Return a static method of a class.
-     * @param methodName the static method name
-     * @param clazz the class which defines the method
-     * @param args the parameter types to the method
-     * @return the static method, or <code>null</code> if no static method was found
-     * @throws IllegalArgumentException if the method name is blank or the clazz is null
-     */
-    // This will suppress PMD.EmptyCatchBlock warnings in this method
-    @SuppressWarnings("PMD.EmptyCatchBlock")
-    public static Method getStaticMethod( Class clazz, String methodName, Class[] args )
-    {
-        try
-        {
-            Method method = clazz.getDeclaredMethod( methodName, args );
-            
-            if ( ( method.getModifiers() & Modifier.STATIC ) != 0 )
-            {
-                return method;
-            }
-        }
-        catch ( NoSuchMethodException ex )
-        {
-        }
-        
-        return null;
-    }
-
-
-    /**
-     * Return a path suitable for use with ClassLoader.getResource (also
-     * suitable for use with Class.getResource by prepending a slash ('/') to
-     * the return value. Built by taking the package of the specified class
-     * file, converting all dots ('.') to slashes ('/'), adding a trailing slash
-     * if necesssary, and concatenating the specified resource name to this.
-     * <br/>As such, this function may be used to build a path suitable for
-     * loading a resource file that is in the same package as a class file,
-     * although {link org.springframework.core.io.ClassPathResource} is usually
-     * even more convenient.
-     * @param clazz the Class whose package will be used as the base
-     * @param resourceName the resource name to append. A leading slash is optional.
-     * @return the built-up resource path
-     * @see java.lang.ClassLoader#getResource
-     * @see java.lang.Class#getResource
-     */
-    public static String addResourcePathToPackagePath( Class clazz, String resourceName )
-    {
-        if ( !resourceName.startsWith( "/" ) )
-        {
-            return classPackageAsResourcePath( clazz ) + "/" + resourceName;
-        }
-
-        return classPackageAsResourcePath( clazz ) + resourceName;
-    }
-
-
-    /**
-     * Given an input class object, return a string which consists of the
-     * class's package name as a pathname, i.e., all dots ('.') are replaced by
-     * slashes ('/'). Neither a leading nor trailing slash is added. The result
-     * could be concatenated with a slash and the name of a resource, and fed
-     * directly to ClassLoader.getResource(). For it to be fed to Class.getResource,
-     * a leading slash would also have to be prepended to the return value.
-     * @param clazz the input class. A null value or the default (empty) package
-     * will result in an empty string ("") being returned.
-     * @return a path which represents the package name
-     * @see java.lang.ClassLoader#getResource
-     * @see java.lang.Class#getResource
-     */
-    public static String classPackageAsResourcePath( Class clazz )
-    {
-        if ( clazz == null || clazz.getPackage() == null )
-        {
-            return "";
-        }
-        
-        return clazz.getPackage().getName().replace( '.', '/' );
-    }
-
-
-    /**
-     * Return all interfaces that the given object implements as array,
-     * including ones implemented by superclasses.
-     * @param object the object to analyse for interfaces
-     * @return all interfaces that the given object implements as array
-     */
-    public static Class[] getAllInterfaces( Object object )
-    {
-        Set<Class> interfaces = getAllInterfacesAsSet( object );
-        return interfaces.toArray( new Class[interfaces.size()] );
-    }
-
-
-    /**
-     * Return all interfaces that the given class implements as array,
-     * including ones implemented by superclasses.
-     * @param clazz the class to analyse for interfaces
-     * @return all interfaces that the given object implements as array
-     */
-    public static Class[] getAllInterfacesForClass( Class clazz )
-    {
-        Set<Class> interfaces = getAllInterfacesForClassAsSet( clazz );
-        return interfaces.toArray( new Class[interfaces.size()] );
-    }
-
-
-    /**
-     * Return all interfaces that the given object implements as List,
-     * including ones implemented by superclasses.
-     * @param object the object to analyse for interfaces
-     * @return all interfaces that the given object implements as List
-     */
-    public static Set<Class> getAllInterfacesAsSet( Object object )
-    {
-        return getAllInterfacesForClassAsSet( object.getClass() );
-    }
-
-
-    /**
-     * Return all interfaces that the given class implements as Set,
-     * including ones implemented by superclasses.
-     * @param clazz the class to analyse for interfaces
-     * @return all interfaces that the given object implements as Set
-     */
-    public static Set<Class> getAllInterfacesForClassAsSet( Class clazz )
-    {
-        Set<Class> interfaces = new HashSet<Class>();
-
-        while ( clazz != null )
-        {
-            for ( int i = 0; i < clazz.getInterfaces().length; i++ )
-            {
-                Class ifc = clazz.getInterfaces()[i];
-                interfaces.add( ifc );
-            }
-
-            clazz = clazz.getSuperclass();
-        }
-
-        return interfaces;
-    }
-
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java
index c79b1f1..78479ba 100644
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java
+++ b/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java
@@ -497,12 +497,9 @@
             ch = buf[i];
 
             // filter out all uppercase characters
-            if ( toLowerCase )
+            if ( toLowerCase && Character.isUpperCase( ch ) )
             {
-                if ( Character.isUpperCase( ch ) )
-                {
-                    ch = Character.toLowerCase( ch );
-                }
+                ch = Character.toLowerCase( ch );
             }
 
             // Check to see if we should add space
@@ -887,6 +884,7 @@
      * @return the filter accepted path component Strings in the order
      *         encountered
      */
+    @SuppressWarnings("PMD.CollapsibleIfStatements") // Used because of comments
     public static final List<String> getPaths( String paths, FileFilter filter )
     {
         int start = 0;
@@ -3397,89 +3395,6 @@
 
 
     /**
-     * Decodes sequences of escaped hex within an attribute's value into 
-     * a UTF-8 String.  The hex is decoded inline and the complete decoded
-     * String is returned.
-     * 
-     * @param str the string containing hex escapes
-     * @return the decoded string
-     */
-    public static final String decodeEscapedHex( String str ) throws InvalidNameException
-    {
-        if ( str == null )
-        {
-            throw new InvalidNameException( I18n.err( I18n.ERR_04433 ) );
-        }
-        
-        int length = str.length();
-        
-        if ( length == 0 )
-        {
-            throw new InvalidNameException( I18n.err( I18n.ERR_04434 ) );
-        }
-        
-        // create buffer and add everything before start of scan
-        StringBuffer buf = new StringBuffer();
-        ByteBuffer bb = new ByteBuffer();
-        boolean escaped = false;
-        
-        // start scaning until we find an escaped series of bytes
-        for ( int ii = 0; ii < length; ii++ )
-        {
-            char c = str.charAt( ii );
-            
-            if ( !escaped && c == '\\' )
-            {
-                // we have the start of a hex escape sequence
-                if ( isHex( str, ii+1 ) && isHex ( str, ii+2 ) )
-                {
-                    bb.clear();
-                    int advancedBy = collectEscapedHexBytes( bb, str, ii );
-                    ii+=advancedBy-1;
-                    buf.append( StringTools.utf8ToString( bb.buffer(), bb.position() ) );
-                    escaped = false;
-                    continue;
-                }
-                else
-                {
-                    // It may be an escaped char ( ' ', '"', '#', '+', ',', ';', '<', '=', '>', '\' )
-                    escaped = true;
-                    continue;
-                }
-            }
-            
-            if ( escaped )
-            {
-                if ( DNUtils.isPairCharOnly( c ) )
-                {
-                    // It is an escaped char ( ' ', '"', '#', '+', ',', ';', '<', '=', '>', '\' )
-                    // Stores it into the buffer without the '\'
-                    escaped = false;
-                    buf.append( c );
-                    continue;
-                }
-                else
-                {
-                    throw new InvalidNameException( I18n.err( I18n.ERR_04435 ) );
-                }
-            }
-            else
-            {
-                buf.append( str.charAt( ii ) );
-            }
-        }
-        
-        if ( escaped )
-        {
-            // We should not have a '\' at the end of the string
-            throw new InvalidNameException( I18n.err( I18n.ERR_04436 ) );
-        }
-
-        return buf.toString();
-    }
-
-
-    /**
      * Convert an escaoed list of bytes to a byte[]
      * 
      * @param str the string containing hex escapes
@@ -3531,39 +3446,6 @@
 
 
     /**
-     * Collects an hex sequence from a string, and returns the value
-     * as an integer, after having modified the initial value (the escaped
-     * hex value is transsformed to the byte it represents).
-     *
-     * @param bb the buffer which will contain the unescaped byte
-     * @param str the initial string with ecaped chars 
-     * @param index the position in the string of the escaped data
-     * @return the byte as an integer
-     */
-    public static int collectEscapedHexBytes( ByteBuffer bb, String str, int index )
-    {
-        int advanceBy = 0;
-        
-        for ( int ii = index; ii < str.length(); ii += 3, advanceBy += 3 )
-        {
-            // we have the start of a hex escape sequence
-            if ( ( str.charAt( ii ) == '\\' ) && isHex( str, ii+1 ) && isHex ( str, ii+2 ) )
-            {
-                int bite = ( StringTools.HEX_VALUE[str.charAt( ii+1 )] << 4 ) + 
-                    StringTools.HEX_VALUE[str.charAt( ii+2 )];
-                bb.append( bite );
-            }
-            else
-            {
-                break;
-            }
-        }
-        
-        return advanceBy;
-    }
-    
-    
-    /**
      * Thansform an array of ASCII bytes to a string. the byte array should contains
      * only values in [0, 127].
      * 
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/SystemUtils.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/SystemUtils.java
deleted file mode 100644
index eaf9770..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/SystemUtils.java
+++ /dev/null
@@ -1,1601 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.io.File;
-
-import org.apache.directory.shared.i18n.I18n;
-
-
-/**
- * <p>
- * Helpers for <code>java.lang.System</code>.
- * </p>
- * <p>
- * If a system property cannot be read due to security restrictions, the
- * corresponding field in this class will be set to <code>null</code> and a
- * message will be written to <code>System.err</code>.
- * </p>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class SystemUtils
-{
-
-    /**
-     * The prefix String for all Windows OS.
-     */
-    private static final String OS_NAME_WINDOWS_PREFIX = "Windows";
-
-    // System property constants
-    // -----------------------------------------------------------------------
-    // These MUST be declared first. Other constants depend on this.
-
-    /**
-     * The System property key for the user home directory.
-     */
-    private static final String USER_HOME_KEY = "user.home";
-
-    /**
-     * The System property key for the user directory.
-     */
-    private static final String USER_DIR_KEY = "user.dir";
-
-    /**
-     * The System property key for the Java IO temporary directory.
-     */
-    private static final String JAVA_IO_TMPDIR_KEY = "java.io.tmpdir";
-
-    /**
-     * The System property key for the Java home directory.
-     */
-    private static final String JAVA_HOME_KEY = "java.home";
-
-    /**
-     * <p>
-     * The <code>awt.toolkit</code> System Property.
-     * </p>
-     * <p>
-     * Holds a class name, on Windows XP this is
-     * <code>sun.awt.windows.WToolkit</code>.
-     * </p>
-     * <p>
-     * <b>On platforms without a GUI, this value is <code>null</code>.</b>
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.1
-     */
-    public static final String AWT_TOOLKIT = getSystemProperty( "awt.toolkit" );
-
-    /**
-     * <p>
-     * The <code>file.encoding</code> System Property.
-     * </p>
-     * <p>
-     * File encoding, such as <code>Cp1252</code>.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.0
-     * @since Java 1.2
-     */
-    public static final String FILE_ENCODING = getSystemProperty( "file.encoding" );
-
-    /**
-     * <p>
-     * The <code>file.separator</code> System Property. File separator (<code>&quot;/&quot;</code>
-     * on UNIX).
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String FILE_SEPARATOR = getSystemProperty( "file.separator" );
-
-    /**
-     * <p>
-     * The <code>java.awt.fonts</code> System Property.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.1
-     */
-    public static final String JAVA_AWT_FONTS = getSystemProperty( "java.awt.fonts" );
-
-    /**
-     * <p>
-     * The <code>java.awt.graphicsenv</code> System Property.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.1
-     */
-    public static final String JAVA_AWT_GRAPHICSENV = getSystemProperty( "java.awt.graphicsenv" );
-
-    /**
-     * <p>
-     * The <code>java.awt.headless</code> System Property. The value of this
-     * property is the String <code>"true"</code> or <code>"false"</code>.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @see #isJavaAwtHeadless()
-     * @since 2.1
-     * @since Java 1.4
-     */
-    public static final String JAVA_AWT_HEADLESS = getSystemProperty( "java.awt.headless" );
-
-    /**
-     * <p>
-     * The <code>java.awt.printerjob</code> System Property.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.1
-     */
-    public static final String JAVA_AWT_PRINTERJOB = getSystemProperty( "java.awt.printerjob" );
-
-    /**
-     * <p>
-     * The <code>java.class.path</code> System Property. Java class path.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String JAVA_CLASS_PATH = getSystemProperty( "java.class.path" );
-
-    /**
-     * <p>
-     * The <code>java.class.version</code> System Property. Java class format
-     * version number.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String JAVA_CLASS_VERSION = getSystemProperty( "java.class.version" );
-
-    /**
-     * <p>
-     * The <code>java.compiler</code> System Property. Name of JIT compiler to
-     * use. First in JDK version 1.2. Not used in Sun JDKs after 1.2.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.2. Not used in Sun versions after 1.2.
-     */
-    public static final String JAVA_COMPILER = getSystemProperty( "java.compiler" );
-
-    /**
-     * <p>
-     * The <code>java.endorsed.dirs</code> System Property. Path of endorsed
-     * directory or directories.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.4
-     */
-    public static final String JAVA_ENDORSED_DIRS = getSystemProperty( "java.endorsed.dirs" );
-
-    /**
-     * <p>
-     * The <code>java.ext.dirs</code> System Property. Path of extension
-     * directory or directories.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.3
-     */
-    public static final String JAVA_EXT_DIRS = getSystemProperty( "java.ext.dirs" );
-
-    /**
-     * <p>
-     * The <code>java.home</code> System Property. Java installation
-     * directory.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String JAVA_HOME = getSystemProperty( JAVA_HOME_KEY );
-
-    /**
-     * <p>
-     * The <code>java.io.tmpdir</code> System Property. Default temp file
-     * path.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.2
-     */
-    public static final String JAVA_IO_TMPDIR = getSystemProperty( JAVA_IO_TMPDIR_KEY );
-
-    /**
-     * <p>
-     * The <code>java.library.path</code> System Property. List of paths to
-     * search when loading libraries.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.2
-     */
-    public static final String JAVA_LIBRARY_PATH = getSystemProperty( "java.library.path" );
-
-    /**
-     * <p>
-     * The <code>java.runtime.name</code> System Property. Java Runtime
-     * Environment name.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.0
-     * @since Java 1.3
-     */
-    public static final String JAVA_RUNTIME_NAME = getSystemProperty( "java.runtime.name" );
-
-    /**
-     * <p>
-     * The <code>java.runtime.version</code> System Property. Java Runtime
-     * Environment version.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.0
-     * @since Java 1.3
-     */
-    public static final String JAVA_RUNTIME_VERSION = getSystemProperty( "java.runtime.version" );
-
-    /**
-     * <p>
-     * The <code>java.specification.name</code> System Property. Java Runtime
-     * Environment specification name.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.2
-     */
-    public static final String JAVA_SPECIFICATION_NAME = getSystemProperty( "java.specification.name" );
-
-    /**
-     * <p>
-     * The <code>java.specification.vendor</code> System Property. Java
-     * Runtime Environment specification vendor.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.2
-     */
-    public static final String JAVA_SPECIFICATION_VENDOR = getSystemProperty( "java.specification.vendor" );
-
-    /**
-     * <p>
-     * The <code>java.specification.version</code> System Property. Java
-     * Runtime Environment specification version.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.3
-     */
-    public static final String JAVA_SPECIFICATION_VERSION = getSystemProperty( "java.specification.version" );
-
-    /**
-     * <p>
-     * The <code>java.util.prefs.PreferencesFactory</code> System Property. A
-     * class name.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.1
-     * @since Java 1.4
-     */
-    public static final String JAVA_UTIL_PREFS_PREFERENCES_FACTORY = getSystemProperty( "java.util.prefs.PreferencesFactory" );
-
-    /**
-     * <p>
-     * The <code>java.vendor</code> System Property. Java vendor-specific
-     * string.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String JAVA_VENDOR = getSystemProperty( "java.vendor" );
-
-    /**
-     * <p>
-     * The <code>java.vendor.url</code> System Property. Java vendor URL.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String JAVA_VENDOR_URL = getSystemProperty( "java.vendor.url" );
-
-    /**
-     * <p>
-     * The <code>java.version</code> System Property. Java version number.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String JAVA_VERSION = getSystemProperty( "java.version" );
-
-    /**
-     * <p>
-     * The <code>java.vm.info</code> System Property. Java Virtual Machine
-     * implementation info.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.0
-     * @since Java 1.2
-     */
-    public static final String JAVA_VM_INFO = getSystemProperty( "java.vm.info" );
-
-    /**
-     * <p>
-     * The <code>java.vm.name</code> System Property. Java Virtual Machine
-     * implementation name.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.2
-     */
-    public static final String JAVA_VM_NAME = getSystemProperty( "java.vm.name" );
-
-    /**
-     * <p>
-     * The <code>java.vm.specification.name</code> System Property. Java
-     * Virtual Machine specification name.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.2
-     */
-    public static final String JAVA_VM_SPECIFICATION_NAME = getSystemProperty( "java.vm.specification.name" );
-
-    /**
-     * <p>
-     * The <code>java.vm.specification.vendor</code> System Property. Java
-     * Virtual Machine specification vendor.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.2
-     */
-    public static final String JAVA_VM_SPECIFICATION_VENDOR = getSystemProperty( "java.vm.specification.vendor" );
-
-    /**
-     * <p>
-     * The <code>java.vm.specification.version</code> System Property. Java
-     * Virtual Machine specification version.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.2
-     */
-    public static final String JAVA_VM_SPECIFICATION_VERSION = getSystemProperty( "java.vm.specification.version" );
-
-    /**
-     * <p>
-     * The <code>java.vm.vendor</code> System Property. Java Virtual Machine
-     * implementation vendor.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.2
-     */
-    public static final String JAVA_VM_VENDOR = getSystemProperty( "java.vm.vendor" );
-
-    /**
-     * <p>
-     * The <code>java.vm.version</code> System Property. Java Virtual Machine
-     * implementation version.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.2
-     */
-    public static final String JAVA_VM_VERSION = getSystemProperty( "java.vm.version" );
-
-    /**
-     * <p>
-     * The <code>line.separator</code> System Property. Line separator (<code>&quot;\n<&quot;</code>
-     * on UNIX).
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String LINE_SEPARATOR = getSystemProperty( "line.separator" );
-
-    /**
-     * <p>
-     * The <code>os.arch</code> System Property. Operating system
-     * architecture.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String OS_ARCH = getSystemProperty( "os.arch" );
-
-    /**
-     * <p>
-     * The <code>os.name</code> System Property. Operating system name.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String OS_NAME = getSystemProperty( "os.name" );
-
-    /**
-     * <p>
-     * The <code>os.version</code> System Property. Operating system version.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String OS_VERSION = getSystemProperty( "os.version" );
-
-    /**
-     * <p>
-     * The <code>path.separator</code> System Property. Path separator (<code>&quot;:&quot;</code>
-     * on UNIX).
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String PATH_SEPARATOR = getSystemProperty( "path.separator" );
-
-    /**
-     * <p>
-     * The <code>user.country</code> or <code>user.region</code> System
-     * Property. User's country code, such as <code>GB</code>. First in JDK
-     * version 1.2 as <code>user.region</code>. Renamed to
-     * <code>user.country</code> in 1.4
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.0
-     * @since Java 1.2
-     */
-    public static final String USER_COUNTRY = ( getSystemProperty( "user.country" ) == null ? getSystemProperty( "user.region" )
-        : getSystemProperty( "user.country" ) );
-
-    /**
-     * <p>
-     * The <code>user.dir</code> System Property. User's current working
-     * directory.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String USER_DIR = getSystemProperty( USER_DIR_KEY );
-
-    /**
-     * <p>
-     * The <code>user.home</code> System Property. User's home directory.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String USER_HOME = getSystemProperty( USER_HOME_KEY );
-
-    /**
-     * <p>
-     * The <code>user.language</code> System Property. User's language code,
-     * such as <code>"en"</code>.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.0
-     * @since Java 1.2
-     */
-    public static final String USER_LANGUAGE = getSystemProperty( "user.language" );
-
-    /**
-     * <p>
-     * The <code>user.name</code> System Property. User's account name.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since Java 1.1
-     */
-    public static final String USER_NAME = getSystemProperty( "user.name" );
-
-    /**
-     * <p>
-     * The <code>user.timezone</code> System Property. For example:
-     * <code>"America/Los_Angeles"</code>.
-     * </p>
-     * <p>
-     * Defaults to <code>null</code> if the runtime does not have security
-     * access to read this property or the property does not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If
-     * {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this
-     * class is loaded, the value will be out of sync with that System property.
-     * </p>
-     * 
-     * @since 2.1
-     */
-    public static final String USER_TIMEZONE = getSystemProperty( "user.timezone" );
-
-    // Java version
-    // -----------------------------------------------------------------------
-    // These MUST be declared after those above as they depend on the
-    // values being set up
-
-    /**
-     * <p>
-     * Gets the Java version as a <code>float</code>.
-     * </p>
-     * <p>
-     * Example return values:
-     * </p>
-     * <ul>
-     * <li><code>1.2f</code> for JDK 1.2
-     * <li><code>1.31f</code> for JDK 1.3.1
-     * </ul>
-     * <p>
-     * The field will return zero if {@link #JAVA_VERSION} is <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final float JAVA_VERSION_FLOAT = getJavaVersionAsFloat();
-
-    /**
-     * <p>
-     * Gets the Java version as an <code>int</code>.
-     * </p>
-     * <p>
-     * Example return values:
-     * </p>
-     * <ul>
-     * <li><code>120</code> for JDK 1.2
-     * <li><code>131</code> for JDK 1.3.1
-     * </ul>
-     * <p>
-     * The field will return zero if {@link #JAVA_VERSION} is <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final int JAVA_VERSION_INT = getJavaVersionAsInt();
-
-    // Java version checks
-    // -----------------------------------------------------------------------
-    // These MUST be declared after those above as they depend on the
-    // values being set up
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Java version 1.1 (also 1.1.x versions).
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if {@link #JAVA_VERSION} is
-     * <code>null</code>.
-     * </p>
-     */
-    public static final boolean IS_JAVA_1_1 = getJavaVersionMatches( "1.1" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Java version 1.2 (also 1.2.x versions).
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if {@link #JAVA_VERSION} is
-     * <code>null</code>.
-     * </p>
-     */
-    public static final boolean IS_JAVA_1_2 = getJavaVersionMatches( "1.2" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Java version 1.3 (also 1.3.x versions).
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if {@link #JAVA_VERSION} is
-     * <code>null</code>.
-     * </p>
-     */
-    public static final boolean IS_JAVA_1_3 = getJavaVersionMatches( "1.3" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Java version 1.4 (also 1.4.x versions).
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if {@link #JAVA_VERSION} is
-     * <code>null</code>.
-     * </p>
-     */
-    public static final boolean IS_JAVA_1_4 = getJavaVersionMatches( "1.4" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Java version 1.5 (also 1.5.x versions).
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if {@link #JAVA_VERSION} is
-     * <code>null</code>.
-     * </p>
-     */
-    public static final boolean IS_JAVA_1_5 = getJavaVersionMatches( "1.5" );
-
-    // Operating system checks
-    // -----------------------------------------------------------------------
-    // These MUST be declared after those above as they depend on the
-    // values being set up
-    // OS names from http://www.vamphq.com/os.html
-    // Selected ones included - please advise commons-dev@jakarta.apache.org
-    // if you want another added or a mistake corrected
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is AIX.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_AIX = getOSMatches( "AIX" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is HP-UX.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_HP_UX = getOSMatches( "HP-UX" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Irix.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_IRIX = getOSMatches( "Irix" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Linux.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_LINUX = getOSMatches( "Linux" ) || getOSMatches( "LINUX" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Mac.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_MAC = getOSMatches( "Mac" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Mac.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_MAC_OSX = getOSMatches( "Mac OS X" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is OS/2.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_OS2 = getOSMatches( "OS/2" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Solaris.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_SOLARIS = getOSMatches( "Solaris" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is SunOS.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_SUN_OS = getOSMatches( "SunOS" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is a POSIX compilant system, as in any of
-     * AIX, HP-UX, Irix, Linux, MacOSX, Solaris or SUN OS.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.1
-     */
-    public static final boolean IS_OS_UNIX = IS_OS_AIX || IS_OS_HP_UX || IS_OS_IRIX || IS_OS_LINUX || IS_OS_MAC_OSX
-        || IS_OS_SOLARIS || IS_OS_SUN_OS;
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Windows.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_WINDOWS = getOSMatches( OS_NAME_WINDOWS_PREFIX );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Windows 2000.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_WINDOWS_2000 = getOSMatches( OS_NAME_WINDOWS_PREFIX, "5.0" );
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Windows 95.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_WINDOWS_95 = getOSMatches( OS_NAME_WINDOWS_PREFIX + " 9", "4.0" );
-
-    // JDK 1.2 running on Windows98 returns 'Windows 95', hence the above
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Windows 98.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_WINDOWS_98 = getOSMatches( OS_NAME_WINDOWS_PREFIX + " 9", "4.1" );
-
-    // JDK 1.2 running on Windows98 returns 'Windows 95', hence the above
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Windows ME.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_WINDOWS_ME = getOSMatches( OS_NAME_WINDOWS_PREFIX, "4.9" );
-
-    // JDK 1.2 running on WindowsME may return 'Windows 95', hence the above
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Windows NT.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_WINDOWS_NT = getOSMatches( OS_NAME_WINDOWS_PREFIX + " NT" );
-
-    // Windows 2000 returns 'Windows 2000' but may suffer from same JDK1.2
-    // problem
-
-    /**
-     * <p>
-     * Is <code>true</code> if this is Windows XP.
-     * </p>
-     * <p>
-     * The field will return <code>false</code> if <code>OS_NAME</code> is
-     * <code>null</code>.
-     * </p>
-     * 
-     * @since 2.0
-     */
-    public static final boolean IS_OS_WINDOWS_XP = getOSMatches( OS_NAME_WINDOWS_PREFIX, "5.1" );
-
-
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * SystemUtils instances should NOT be constructed in standard programming.
-     * Instead, the class should be used as
-     * <code>SystemUtils.FILE_SEPARATOR</code>.
-     * </p>
-     * <p>
-     * This constructor is public to permit tools that require a JavaBean
-     * instance to operate.
-     * </p>
-     */
-    public SystemUtils()
-    {
-        // no init.
-    }
-
-
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Gets the Java version number as a <code>float</code>.
-     * </p>
-     * <p>
-     * Example return values:
-     * </p>
-     * <ul>
-     * <li><code>1.2f</code> for JDK 1.2
-     * <li><code>1.31f</code> for JDK 1.3.1
-     * </ul>
-     * 
-     * @return the version, for example 1.31f for JDK 1.3.1
-     * @deprecated Use {@link #JAVA_VERSION_FLOAT} instead. Method will be
-     *             removed in Commons Lang 3.0.
-     */
-    public static float getJavaVersion()
-    {
-        return JAVA_VERSION_FLOAT;
-    }
-
-
-    /**
-     * <p>
-     * Gets the Java version number as a <code>float</code>.
-     * </p>
-     * <p>
-     * Example return values:
-     * </p>
-     * <ul>
-     * <li><code>1.2f</code> for JDK 1.2
-     * <li><code>1.31f</code> for JDK 1.3.1
-     * </ul>
-     * <p>
-     * Patch releases are not reported. Zero is returned if
-     * {@link #JAVA_VERSION} is <code>null</code>.
-     * </p>
-     * 
-     * @return the version, for example 1.31f for JDK 1.3.1
-     */
-    private static float getJavaVersionAsFloat()
-    {
-        if ( JAVA_VERSION == null )
-        {
-            return 0f;
-        }
-        String str = JAVA_VERSION.substring( 0, 3 );
-        if ( JAVA_VERSION.length() >= 5 )
-        {
-            str = str + JAVA_VERSION.substring( 4, 5 );
-        }
-        return Float.parseFloat( str );
-    }
-
-
-    /**
-     * <p>
-     * Gets the Java version number as an <code>int</code>.
-     * </p>
-     * <p>
-     * Example return values:
-     * </p>
-     * <ul>
-     * <li><code>120</code> for JDK 1.2
-     * <li><code>131</code> for JDK 1.3.1
-     * </ul>
-     * <p>
-     * Patch releases are not reported. Zero is returned if
-     * {@link #JAVA_VERSION} is <code>null</code>.
-     * </p>
-     * 
-     * @return the version, for example 131 for JDK 1.3.1
-     */
-    private static int getJavaVersionAsInt()
-    {
-        if ( JAVA_VERSION == null )
-        {
-            return 0;
-        }
-        String str = JAVA_VERSION.substring( 0, 1 );
-        str = str + JAVA_VERSION.substring( 2, 3 );
-        if ( JAVA_VERSION.length() >= 5 )
-        {
-            str = str + JAVA_VERSION.substring( 4, 5 );
-        }
-        else
-        {
-            str = str + "0";
-        }
-        return Integer.parseInt( str );
-    }
-
-
-    /**
-     * <p>
-     * Decides if the java version matches.
-     * </p>
-     * 
-     * @param versionPrefix
-     *            the prefix for the java version
-     * @return true if matches, or false if not or can't determine
-     */
-    private static boolean getJavaVersionMatches( String versionPrefix )
-    {
-        if ( JAVA_VERSION == null )
-        {
-            return false;
-        }
-        return JAVA_VERSION.startsWith( versionPrefix );
-    }
-
-
-    /**
-     * <p>
-     * Decides if the operating system matches.
-     * </p>
-     * 
-     * @param osNamePrefix
-     *            the prefix for the os name
-     * @return true if matches, or false if not or can't determine
-     */
-    private static boolean getOSMatches( String osNamePrefix )
-    {
-        if ( OS_NAME == null )
-        {
-            return false;
-        }
-        return OS_NAME.startsWith( osNamePrefix );
-    }
-
-
-    /**
-     * <p>
-     * Decides if the operating system matches.
-     * </p>
-     * 
-     * @param osNamePrefix
-     *            the prefix for the os name
-     * @param osVersionPrefix
-     *            the prefix for the version
-     * @return true if matches, or false if not or can't determine
-     */
-    private static boolean getOSMatches( String osNamePrefix, String osVersionPrefix )
-    {
-        if ( OS_NAME == null || OS_VERSION == null )
-        {
-            return false;
-        }
-        return OS_NAME.startsWith( osNamePrefix ) && OS_VERSION.startsWith( osVersionPrefix );
-    }
-
-
-    // -----------------------------------------------------------------------
-    /**
-     * <p>
-     * Gets a System property, defaulting to <code>null</code> if the property
-     * cannot be read.
-     * </p>
-     * <p>
-     * If a <code>SecurityException</code> is caught, the return value is
-     * <code>null</code> and a message is written to <code>System.err</code>.
-     * </p>
-     * 
-     * @param property
-     *            the system property name
-     * @return the system property value or <code>null</code> if a security
-     *         problem occurs
-     */
-    private static String getSystemProperty( String property )
-    {
-        try
-        {
-            return System.getProperty( property );
-        }
-        catch ( SecurityException ex )
-        {
-            // we are not allowed to look at this property
-            System.err.println( I18n.err( I18n.ERR_04437, property ) );
-            return null;
-        }
-    }
-
-
-    /**
-     * <p>
-     * Is the Java version at least the requested version.
-     * </p>
-     * <p>
-     * Example input:
-     * </p>
-     * <ul>
-     * <li><code>1.2f</code> to test for JDK 1.2</li>
-     * <li><code>1.31f</code> to test for JDK 1.3.1</li>
-     * </ul>
-     * 
-     * @param requiredVersion
-     *            the required version, for example 1.31f
-     * @return <code>true</code> if the actual version is equal or greater
-     *         than the required version
-     */
-    public static boolean isJavaVersionAtLeast( float requiredVersion )
-    {
-        return ( JAVA_VERSION_FLOAT >= requiredVersion );
-    }
-
-
-    /**
-     * <p>
-     * Is the Java version at least the requested version.
-     * </p>
-     * <p>
-     * Example input:
-     * </p>
-     * <ul>
-     * <li><code>120</code> to test for JDK 1.2 or greater</li>
-     * <li><code>131</code> to test for JDK 1.3.1 or greater</li>
-     * </ul>
-     * 
-     * @param requiredVersion
-     *            the required version, for example 131
-     * @return <code>true</code> if the actual version is equal or greater
-     *         than the required version
-     * @since 2.0
-     */
-    public static boolean isJavaVersionAtLeast( int requiredVersion )
-    {
-        return ( JAVA_VERSION_INT >= requiredVersion );
-    }
-
-
-    /**
-     * Returns whether the {@link #JAVA_AWT_HEADLESS} value is <code>true</code>.
-     * 
-     * @return <code>true</code> if <code>JAVA_AWT_HEADLESS</code> is
-     *         <code>"true"</code>, <code>false</code> otherwise.
-     * @see #JAVA_AWT_HEADLESS
-     * @since 2.1
-     * @since Java 1.4
-     */
-    public static boolean isJavaAwtHeadless()
-    {
-        return JAVA_AWT_HEADLESS != null ? JAVA_AWT_HEADLESS.equals( Boolean.TRUE.toString() ) : false;
-    }
-
-
-    /**
-     * <p>
-     * Gets the Java home directory as a <code>File</code>.
-     * </p>
-     * 
-     * @return a directory
-     * @throws SecurityException
-     *             if a security manager exists and its
-     *             <code>checkPropertyAccess</code> method doesn't allow
-     *             access to the specified system property.
-     * @see System#getProperty(String)
-     */
-    public static File getJavaHome()
-    {
-        return new File( System.getProperty( JAVA_HOME_KEY ) );
-    }
-
-
-    /**
-     * <p>
-     * Gets the Java IO temporary directory as a <code>File</code>.
-     * </p>
-     * 
-     * @return a directory
-     * @throws SecurityException
-     *             if a security manager exists and its
-     *             <code>checkPropertyAccess</code> method doesn't allow
-     *             access to the specified system property.
-     * @see System#getProperty(String)
-     */
-    public static File getJavaIoTmpDir()
-    {
-        return new File( System.getProperty( JAVA_IO_TMPDIR_KEY ) );
-    }
-
-
-    /**
-     * <p>
-     * Gets the user directory as a <code>File</code>.
-     * </p>
-     * 
-     * @return a directory
-     * @throws SecurityException
-     *             if a security manager exists and its
-     *             <code>checkPropertyAccess</code> method doesn't allow
-     *             access to the specified system property.
-     * @see System#getProperty(String)
-     */
-    public static File getUserDir()
-    {
-        return new File( System.getProperty( USER_DIR_KEY ) );
-    }
-
-
-    /**
-     * <p>
-     * Gets the user home directory as a <code>File</code>.
-     * </p>
-     * 
-     * @return a directory
-     * @throws SecurityException
-     *             if a security manager exists and its
-     *             <code>checkPropertyAccess</code> method doesn't allow
-     *             access to the specified system property.
-     * @see System#getProperty(String)
-     */
-    public static File getUserHome()
-    {
-        return new File( System.getProperty( USER_HOME_KEY ) );
-    }
-
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ToStringBuilder.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/ToStringBuilder.java
deleted file mode 100644
index f95faf6..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ToStringBuilder.java
+++ /dev/null
@@ -1,1386 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-import org.apache.directory.shared.i18n.I18n;
-
-
-/**
- * <p>
- * Assists in implementing {@link Object#toString()} methods.
- * </p>
- * <p>
- * This class enables a good and consistent <code>toString()</code> to be
- * built for any class or object. This class aims to simplify the process by:
- * </p>
- * <ul>
- * <li>allowing field names</li>
- * <li>handling all types consistently</li>
- * <li>handling nulls consistently</li>
- * <li>outputting arrays and multi-dimensional arrays</li>
- * <li>enabling the detail level to be controlled for Objects and Collections</li>
- * <li>handling class hierarchies</li>
- * </ul>
- * <p>
- * To use this class write code as follows:
- * </p>
- * 
- * <pre>
- *  public class Person {
- *    String name;
- *    int age;
- *    boolean isSmoker;
- *  
- *    ...
- *  
- *    public String toString() {
- *      return new ToStringBuilder(this).
- *        append(&quot;name&quot;, name).
- *        append(&quot;age&quot;, age).
- *        append(&quot;smoker&quot;, smoker).
- *        toString();
- *    }
- *  }
- * </pre>
- * 
- * <p>
- * This will produce a toString of the format:
- * <code>Person@7f54[name=Stephen,age=29,smoker=false]</code>
- * </p>
- * <p>
- * To add the superclass <code>toString</code>, use {@link #appendSuper}. To
- * append the <code>toString</code> from an object that is delegated to (or
- * any other object), use {@link #appendToString}.
- * </p>
- * <p>
- * Alternatively, there is a method that uses reflection to determine the fields
- * to test. Because these fields are usually private, the method,
- * <code>reflectionToString</code>, uses
- * <code>AccessibleObject.setAccessible</code> to change the visibility of the
- * fields. This will fail under a security manager, unless the appropriate
- * permissions are set up correctly. It is also slower than testing explicitly.
- * </p>
- * <p>
- * A typical invocation for this method would look like:
- * </p>
- * 
- * <pre>
- * public String toString()
- * {
- *     return ToStringBuilder.reflectionToString( this );
- * }
- * </pre>
- * 
- * <p>
- * You can also use the builder to debug 3rd party objects:
- * </p>
- * 
- * <pre>
- * System.out.println( &quot;An object: &quot; + ToStringBuilder.reflectionToString( anObject ) );
- * </pre>
- * 
- * <p>
- * The exact format of the <code>toString</code> is determined by the
- * {@link ToStringStyle} passed into the constructor.
- * </p>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class ToStringBuilder
-{
-
-    /**
-     * The default style of output to use.
-     */
-    private static ToStringStyle defaultStyle = ToStringStyle.DEFAULT_STYLE;
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the default <code>ToStringStyle</code> to use.
-     * </p>
-     * <p>
-     * This could allow the <code>ToStringStyle</code> to be controlled for an
-     * entire application with one call.
-     * </p>
-     * <p>
-     * This might be used to have a verbose <code>ToStringStyle</code> during
-     * development and a compact <code>ToStringStyle</code> in production.
-     * </p>
-     * 
-     * @return the default <code>ToStringStyle</code>
-     */
-    public static ToStringStyle getDefaultStyle()
-    {
-        return defaultStyle;
-    }
-
-
-    /**
-     * <p>
-     * Forwards to <code>ReflectionToStringBuilder</code>.
-     * </p>
-     * 
-     * @see ReflectionToStringBuilder#toString(Object)
-     */
-    public static String reflectionToString( Object object )
-    {
-        return ReflectionToStringBuilder.toString( object );
-    }
-
-
-    /**
-     * <p>
-     * Forwards to <code>ReflectionToStringBuilder</code>.
-     * </p>
-     * 
-     * @see ReflectionToStringBuilder#toString(Object,ToStringStyle)
-     */
-    public static String reflectionToString( Object object, ToStringStyle style )
-    {
-        return ReflectionToStringBuilder.toString( object, style );
-    }
-
-
-    /**
-     * <p>
-     * Forwards to <code>ReflectionToStringBuilder</code>.
-     * </p>
-     * 
-     * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean)
-     */
-    public static String reflectionToString( Object object, ToStringStyle style, boolean outputTransients )
-    {
-        return ReflectionToStringBuilder.toString( object, style, outputTransients, false, null );
-    }
-
-
-    /**
-     * <p>
-     * Forwards to <code>ReflectionToStringBuilder</code>.
-     * </p>
-     * 
-     * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean,boolean,Class)
-     * @since 2.0
-     */
-    public static String reflectionToString( Object object, ToStringStyle style, boolean outputTransients,
-        Class reflectUpToClass )
-    {
-        return ReflectionToStringBuilder.toString( object, style, outputTransients, false, reflectUpToClass );
-    }
-
-
-    /**
-     * <p>
-     * Sets the default <code>ToStringStyle</code> to use.
-     * </p>
-     * 
-     * @param style
-     *            the default <code>ToStringStyle</code>
-     * @throws IllegalArgumentException
-     *             if the style is <code>null</code>
-     */
-    public static void setDefaultStyle( ToStringStyle style )
-    {
-        if ( style == null )
-        {
-            throw new IllegalArgumentException( I18n.err( I18n.ERR_04438 ) );
-        }
-        defaultStyle = style;
-    }
-
-    /**
-     * Current toString buffer.
-     */
-    private final StringBuffer buffer;
-
-    /**
-     * The object being output.
-     */
-    private final Object object;
-
-    /**
-     * The style of output to use.
-     */
-    private final ToStringStyle style;
-
-
-    /**
-     * <p>
-     * Constructor for <code>ToStringBuilder</code>.
-     * </p>
-     * <p>
-     * This constructor outputs using the default style set with
-     * <code>setDefaultStyle</code>.
-     * </p>
-     * 
-     * @param object
-     *            the Object to build a <code>toString</code> for
-     * @throws IllegalArgumentException
-     *             if the Object passed in is <code>null</code>
-     */
-    public ToStringBuilder(Object object)
-    {
-        this( object, getDefaultStyle(), null );
-    }
-
-
-    /**
-     * <p>
-     * Constructor for <code>ToStringBuilder</code> specifying the output
-     * style.
-     * </p>
-     * <p>
-     * If the style is <code>null</code>, the default style is used.
-     * </p>
-     * 
-     * @param object
-     *            the Object to build a <code>toString</code> for
-     * @param style
-     *            the style of the <code>toString</code> to create, may be
-     *            <code>null</code>
-     * @throws IllegalArgumentException
-     *             if the Object passed in is <code>null</code>
-     */
-    public ToStringBuilder(Object object, ToStringStyle style)
-    {
-        this( object, style, null );
-    }
-
-
-    /**
-     * <p>
-     * Constructor for <code>ToStringBuilder</code>.
-     * </p>
-     * <p>
-     * If the style is <code>null</code>, the default style is used.
-     * </p>
-     * <p>
-     * If the buffer is <code>null</code>, a new one is created.
-     * </p>
-     * 
-     * @param object
-     *            the Object to build a <code>toString</code> for
-     * @param style
-     *            the style of the <code>toString</code> to create, may be
-     *            <code>null</code>
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate, may be
-     *            <code>null</code>
-     */
-    public ToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer)
-    {
-        if ( style == null )
-        {
-            style = getDefaultStyle();
-        }
-        if ( buffer == null )
-        {
-            buffer = new StringBuffer( 512 );
-        }
-        this.buffer = buffer;
-        this.style = style;
-        this.object = object;
-
-        style.appendStart( buffer, object );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>boolean</code> value.
-     * </p>
-     * 
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( boolean value )
-    {
-        style.append( buffer, null, value );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>boolean</code> array.
-     * </p>
-     * 
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( boolean[] array )
-    {
-        style.append( buffer, null, array, null );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>byte</code> value.
-     * </p>
-     * 
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( byte value )
-    {
-        style.append( buffer, null, value );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>byte</code> array.
-     * </p>
-     * 
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( byte[] array )
-    {
-        style.append( buffer, null, array, null );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>char</code> value.
-     * </p>
-     * 
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( char value )
-    {
-        style.append( buffer, null, value );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>char</code> array.
-     * </p>
-     * 
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( char[] array )
-    {
-        style.append( buffer, null, array, null );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>double</code> value.
-     * </p>
-     * 
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( double value )
-    {
-        style.append( buffer, null, value );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>double</code> array.
-     * </p>
-     * 
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( double[] array )
-    {
-        style.append( buffer, null, array, null );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>float</code> value.
-     * </p>
-     * 
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( float value )
-    {
-        style.append( buffer, null, value );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>float</code> array.
-     * </p>
-     * 
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( float[] array )
-    {
-        style.append( buffer, null, array, null );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>int</code> value.
-     * </p>
-     * 
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( int value )
-    {
-        style.append( buffer, null, value );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>int</code> array.
-     * </p>
-     * 
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( int[] array )
-    {
-        style.append( buffer, null, array, null );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>long</code> value.
-     * </p>
-     * 
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( long value )
-    {
-        style.append( buffer, null, value );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>long</code> array.
-     * </p>
-     * 
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( long[] array )
-    {
-        style.append( buffer, null, array, null );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code> value.
-     * </p>
-     * 
-     * @param object
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( Object object )
-    {
-        style.append( buffer, null, object, null );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code> array.
-     * </p>
-     * 
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( Object[] array )
-    {
-        style.append( buffer, null, array, null );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>short</code> value.
-     * </p>
-     * 
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( short value )
-    {
-        style.append( buffer, null, value );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>short</code> array.
-     * </p>
-     * 
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( short[] array )
-    {
-        style.append( buffer, null, array, null );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>boolean</code> value.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, boolean value )
-    {
-        style.append( buffer, fieldName, value );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>boolean</code> array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>hashCode</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, boolean[] array )
-    {
-        style.append( buffer, fieldName, array, null );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>boolean</code> array.
-     * </p>
-     * <p>
-     * A boolean parameter controls the level of detail to show. Setting
-     * <code>true</code> will output the array in full. Setting
-     * <code>false</code> will output a summary, typically the size of the
-     * array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, boolean[] array, boolean fullDetail )
-    {
-        style.append( buffer, fieldName, array, BooleanUtils.toBooleanObject( fullDetail ) );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>byte</code> value.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, byte value )
-    {
-        style.append( buffer, fieldName, value );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>byte</code> array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, byte[] array )
-    {
-        style.append( buffer, fieldName, array, null );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>byte</code> array.
-     * </p>
-     * <p>
-     * A boolean parameter controls the level of detail to show. Setting
-     * <code>true</code> will output the array in full. Setting
-     * <code>false</code> will output a summary, typically the size of the
-     * array.
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, byte[] array, boolean fullDetail )
-    {
-        style.append( buffer, fieldName, array, BooleanUtils.toBooleanObject( fullDetail ) );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>char</code> value.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, char value )
-    {
-        style.append( buffer, fieldName, value );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>char</code> array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, char[] array )
-    {
-        style.append( buffer, fieldName, array, null );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>char</code> array.
-     * </p>
-     * <p>
-     * A boolean parameter controls the level of detail to show. Setting
-     * <code>true</code> will output the array in full. Setting
-     * <code>false</code> will output a summary, typically the size of the
-     * array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, char[] array, boolean fullDetail )
-    {
-        style.append( buffer, fieldName, array, BooleanUtils.toBooleanObject( fullDetail ) );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>double</code> value.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, double value )
-    {
-        style.append( buffer, fieldName, value );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>double</code> array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, double[] array )
-    {
-        style.append( buffer, fieldName, array, null );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>double</code> array.
-     * </p>
-     * <p>
-     * A boolean parameter controls the level of detail to show. Setting
-     * <code>true</code> will output the array in full. Setting
-     * <code>false</code> will output a summary, typically the size of the
-     * array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, double[] array, boolean fullDetail )
-    {
-        style.append( buffer, fieldName, array, BooleanUtils.toBooleanObject( fullDetail ) );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>float</code> value.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, float value )
-    {
-        style.append( buffer, fieldName, value );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>float</code> array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, float[] array )
-    {
-        style.append( buffer, fieldName, array, null );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>float</code> array.
-     * </p>
-     * <p>
-     * A boolean parameter controls the level of detail to show. Setting
-     * <code>true</code> will output the array in full. Setting
-     * <code>false</code> will output a summary, typically the size of the
-     * array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, float[] array, boolean fullDetail )
-    {
-        style.append( buffer, fieldName, array, BooleanUtils.toBooleanObject( fullDetail ) );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>int</code> value.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, int value )
-    {
-        style.append( buffer, fieldName, value );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>int</code> array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, int[] array )
-    {
-        style.append( buffer, fieldName, array, null );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>int</code> array.
-     * </p>
-     * <p>
-     * A boolean parameter controls the level of detail to show. Setting
-     * <code>true</code> will output the array in full. Setting
-     * <code>false</code> will output a summary, typically the size of the
-     * array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, int[] array, boolean fullDetail )
-    {
-        style.append( buffer, fieldName, array, BooleanUtils.toBooleanObject( fullDetail ) );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>long</code> value.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, long value )
-    {
-        style.append( buffer, fieldName, value );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>long</code> array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, long[] array )
-    {
-        style.append( buffer, fieldName, array, null );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>long</code> array.
-     * </p>
-     * <p>
-     * A boolean parameter controls the level of detail to show. Setting
-     * <code>true</code> will output the array in full. Setting
-     * <code>false</code> will output a summary, typically the size of the
-     * array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, long[] array, boolean fullDetail )
-    {
-        style.append( buffer, fieldName, array, BooleanUtils.toBooleanObject( fullDetail ) );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code> value.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param object
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, Object object )
-    {
-        style.append( buffer, fieldName, object, null );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code> value.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param object
-     *            the value to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, Object object, boolean fullDetail )
-    {
-        style.append( buffer, fieldName, object, BooleanUtils.toBooleanObject( fullDetail ) );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code> array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, Object[] array )
-    {
-        style.append( buffer, fieldName, array, null );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code> array.
-     * </p>
-     * <p>
-     * A boolean parameter controls the level of detail to show. Setting
-     * <code>true</code> will output the array in full. Setting
-     * <code>false</code> will output a summary, typically the size of the
-     * array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, Object[] array, boolean fullDetail )
-    {
-        style.append( buffer, fieldName, array, BooleanUtils.toBooleanObject( fullDetail ) );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>short</code> value.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, short value )
-    {
-        style.append( buffer, fieldName, value );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>short</code> array.
-     * </p>
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, short[] array )
-    {
-        style.append( buffer, fieldName, array, null );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>short</code> array.
-     * </p>
-     * <p>
-     * A boolean parameter controls the level of detail to show. Setting
-     * <code>true</code> will output the array in full. Setting
-     * <code>false</code> will output a summary, typically the size of the
-     * array.
-     * 
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info
-     * @return this
-     */
-    public ToStringBuilder append( String fieldName, short[] array, boolean fullDetail )
-    {
-        style.append( buffer, fieldName, array, BooleanUtils.toBooleanObject( fullDetail ) );
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Appends with the same format as the default <code>Object toString()
-     * </code>
-     * method. Appends the class name followed by
-     * {@link System#identityHashCode(java.lang.Object)}.
-     * </p>
-     * 
-     * @param object
-     *            the <code>Object</code> whose class name and id to output
-     * @return this
-     * @since 2.0
-     */
-    public ToStringBuilder appendAsObjectToString( Object object )
-    {
-        ObjectUtils.appendIdentityToString( this.getStringBuffer(), object );
-        return this;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append the <code>toString</code> from the superclass.
-     * </p>
-     * <p>
-     * This method assumes that the superclass uses the same
-     * <code>ToStringStyle</code> as this one.
-     * </p>
-     * <p>
-     * If <code>superToString</code> is <code>null</code>, no change is
-     * made.
-     * </p>
-     * 
-     * @param superToString
-     *            the result of <code>super.toString()</code>
-     * @return this
-     * @since 2.0
-     */
-    public ToStringBuilder appendSuper( String superToString )
-    {
-        if ( superToString != null )
-        {
-            style.appendSuper( buffer, superToString );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Append the <code>toString</code> from another object.
-     * </p>
-     * <p>
-     * This method is useful where a class delegates most of the implementation
-     * of its properties to another class. You can then call
-     * <code>toString()</code> on the other class and pass the result into
-     * this method.
-     * </p>
-     * 
-     * <pre>
-     * private AnotherObject delegate;
-     * 
-     * private String fieldInThisClass;
-     * 
-     * 
-     * public String toString()
-     * {
-     *     return new ToStringBuilder( this ).appendToString( delegate.toString() ).append( fieldInThisClass ).toString();
-     * }
-     * </pre>
-     * 
-     * <p>
-     * This method assumes that the other object uses the same
-     * <code>ToStringStyle</code> as this one.
-     * </p>
-     * <p>
-     * If the <code>toString</code> is <code>null</code>, no change is
-     * made.
-     * </p>
-     * 
-     * @param toString
-     *            the result of <code>toString()</code> on another object
-     * @return this
-     * @since 2.0
-     */
-    public ToStringBuilder appendToString( String toString )
-    {
-        if ( toString != null )
-        {
-            style.appendToString( buffer, toString );
-        }
-        return this;
-    }
-
-
-    /**
-     * <p>
-     * Returns the <code>Object</code> being output.
-     * </p>
-     * 
-     * @return The object being output.
-     * @since 2.0
-     */
-    public Object getObject()
-    {
-        return object;
-    }
-
-
-    /**
-     * <p>
-     * Gets the <code>StringBuffer</code> being populated.
-     * </p>
-     * 
-     * @return the <code>StringBuffer</code> being populated
-     */
-    public StringBuffer getStringBuffer()
-    {
-        return buffer;
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the <code>ToStringStyle</code> being used.
-     * </p>
-     * 
-     * @return the <code>ToStringStyle</code> being used
-     * @since 2.0
-     */
-    public ToStringStyle getStyle()
-    {
-        return style;
-    }
-
-
-    /**
-     * <p>
-     * Returns the built <code>toString</code>.
-     * </p>
-     * <p>
-     * This method appends the end of data indicator, and can only be called
-     * once. Use {@link #getStringBuffer} to get the current string state.
-     * </p>
-     * <p>
-     * If the object is <code>null</code>, return the style's
-     * <code>nullText</code>
-     * </p>
-     * 
-     * @return the String <code>toString</code>
-     */
-    public String toString()
-    {
-        if ( this.getObject() == null )
-        {
-            this.getStringBuffer().append( this.getStyle().getNullText() );
-        }
-        else
-        {
-            style.appendEnd( this.getStringBuffer(), this.getObject() );
-        }
-        return this.getStringBuffer().toString();
-    }
-
-}
diff --git a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ToStringStyle.java b/ldap/src/main/java/org/apache/directory/shared/ldap/util/ToStringStyle.java
deleted file mode 100644
index 41be97c..0000000
--- a/ldap/src/main/java/org/apache/directory/shared/ldap/util/ToStringStyle.java
+++ /dev/null
@@ -1,3063 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.shared.ldap.util;
-
-
-import java.io.Serializable;
-import java.lang.reflect.Array;
-import java.util.Collection;
-import java.util.Map;
-
-
-/**
- * <p>
- * Controls <code>String</code> formatting for {@link ToStringBuilder}. The
- * main public interface is always via <code>ToStringBuilder</code>.
- * </p>
- * <p>
- * These classes are intended to be used as <code>Singletons</code>. There is
- * no need to instantiate a new style each time. A program will generally use
- * one of the predefined constants on this class. Alternatively, the
- * class can be used to set the individual settings. Thus most styles can be
- * achieved without subclassing.
- * </p>
- * <p>
- * If required, a subclass can override as many or as few of the methods as it
- * requires. Each object type (from <code>boolean</code> to <code>long</code>
- * to <code>Object</code> to <code>int[]</code>) has its own methods to
- * output it. Most have two versions, detail and summary.
- * <p>
- * For example, the detail version of the array based methods will output the
- * whole array, whereas the summary method will just output the array length.
- * </p>
- * 
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public abstract class ToStringStyle implements Serializable
-{
-
-    static final long serialVersionUID = -3594451267200535036L;
-
-    /**
-     * The default toString style.
-     */
-    public static final ToStringStyle DEFAULT_STYLE = new DefaultToStringStyle();
-
-    /**
-     * The multi line toString style.
-     */
-    public static final ToStringStyle MULTI_LINE_STYLE = new MultiLineToStringStyle();
-
-    /**
-     * The no field names toString style.
-     */
-    public static final ToStringStyle NO_FIELD_NAMES_STYLE = new NoFieldNameToStringStyle();
-
-    /**
-     * The short prefix toString style.
-     */
-    public static final ToStringStyle SHORT_PREFIX_STYLE = new ShortPrefixToStringStyle();
-
-    /**
-     * The simple toString style.
-     */
-    public static final ToStringStyle SIMPLE_STYLE = new SimpleToStringStyle();
-
-    /**
-     * Whether to use the field names, the default is <code>true</code>.
-     */
-    private boolean useFieldNames = true;
-
-    /**
-     * Whether to use the class name, the default is <code>true</code>.
-     */
-    private boolean useClassName = true;
-
-    /**
-     * Whether to use short class names, the default is <code>false</code>.
-     */
-    private boolean useShortClassName = false;
-
-    /**
-     * Whether to use the identity hash code, the default is <code>true</code>.
-     */
-    private boolean useIdentityHashCode = true;
-
-    /**
-     * The content start <code>'['</code>.
-     */
-    private String contentStart = "[";
-
-    /**
-     * The content end <code>']'</code>.
-     */
-    private String contentEnd = "]";
-
-    /**
-     * The field name value separator <code>'='</code>.
-     */
-    private String fieldNameValueSeparator = "=";
-
-    /**
-     * Whether the field separator should be added before any other fields.
-     */
-    private boolean fieldSeparatorAtStart = false;
-
-    /**
-     * Whether the field separator should be added after any other fields.
-     */
-    private boolean fieldSeparatorAtEnd = false;
-
-    /**
-     * The field separator <code>','</code>.
-     */
-    private String fieldSeparator = ",";
-
-    /**
-     * The array start <code>'{'</code>.
-     */
-    private String arrayStart = "{";
-
-    /**
-     * The array separator <code>','</code>.
-     */
-    private String arraySeparator = ",";
-
-    /**
-     * The detail for array content.
-     */
-    private boolean arrayContentDetail = true;
-
-    /**
-     * The array end <code>'}'</code>.
-     */
-    private String arrayEnd = "}";
-
-    /**
-     * The value to use when fullDetail is <code>null</code>, the default
-     * value is <code>true</code>.
-     */
-    private boolean defaultFullDetail = true;
-
-    /**
-     * The <code>null</code> text <code>'&lt;null&gt;'</code>.
-     */
-    private String nullText = "<null>";
-
-    /**
-     * The summary size text start <code>'<size'</code>.
-     */
-    private String sizeStartText = "<size=";
-
-    /**
-     * The summary size text start <code>'&gt;'</code>.
-     */
-    private String sizeEndText = ">";
-
-    /**
-     * The summary object text start <code>'&lt;'</code>.
-     */
-    private String summaryObjectStartText = "<";
-
-    /**
-     * The summary object text start <code>'&gt;'</code>.
-     */
-    private String summaryObjectEndText = ">";
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Constructor.
-     * </p>
-     */
-    protected ToStringStyle()
-    {
-        super();
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the superclass toString.
-     * </p>
-     * <p>
-     * A <code>null</code> <code>superToString</code> is ignored.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param superToString
-     *            the <code>super.toString()</code>
-     * @since 2.0
-     */
-    public void appendSuper( StringBuffer buffer, String superToString )
-    {
-        appendToString( buffer, superToString );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> another toString.
-     * </p>
-     * <p>
-     * A <code>null</code> <code>toString</code> is ignored.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param toString
-     *            the additional <code>toString</code>
-     * @since 2.0
-     */
-    public void appendToString( StringBuffer buffer, String toString )
-    {
-        if ( toString != null )
-        {
-            int pos1 = toString.indexOf( contentStart ) + contentStart.length();
-            int pos2 = toString.lastIndexOf( contentEnd );
-            if ( pos1 != pos2 && pos1 >= 0 && pos2 >= 0 )
-            {
-                String data = toString.substring( pos1, pos2 );
-                if ( fieldSeparatorAtStart )
-                {
-                    removeLastFieldSeparator( buffer );
-                }
-                buffer.append( data );
-                appendFieldSeparator( buffer );
-            }
-        }
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the start of data indicator.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param object
-     *            the <code>Object</code> to build a <code>toString</code>
-     *            for
-     */
-    public void appendStart( StringBuffer buffer, Object object )
-    {
-        if ( object != null )
-        {
-            appendClassName( buffer, object );
-            appendIdentityHashCode( buffer, object );
-            appendContentStart( buffer );
-            if ( fieldSeparatorAtStart )
-            {
-                appendFieldSeparator( buffer );
-            }
-        }
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the end of data indicator.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param object
-     *            the <code>Object</code> to build a <code>toString</code>
-     *            for.
-     */
-    public void appendEnd( StringBuffer buffer, Object object )
-    {
-        if ( this.fieldSeparatorAtEnd == false )
-        {
-            removeLastFieldSeparator( buffer );
-        }
-        appendContentEnd( buffer );
-    }
-
-
-    /**
-     * <p>
-     * Remove the last field separator from the buffer.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @since 2.0
-     */
-    protected void removeLastFieldSeparator( StringBuffer buffer )
-    {
-        int len = buffer.length();
-        int sepLen = fieldSeparator.length();
-        if ( len > 0 && sepLen > 0 && len >= sepLen )
-        {
-            boolean match = true;
-            for ( int i = 0; i < sepLen; i++ )
-            {
-                if ( buffer.charAt( len - 1 - i ) != fieldSeparator.charAt( sepLen - 1 - i ) )
-                {
-                    match = false;
-                    break;
-                }
-            }
-            if ( match )
-            {
-                buffer.setLength( len - sepLen );
-            }
-        }
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code> value,
-     * printing the full <code>toString</code> of the <code>Object</code>
-     * passed in.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info, <code>null</code> for style decides
-     */
-    public void append( StringBuffer buffer, String fieldName, Object value, Boolean fullDetail )
-    {
-        appendFieldStart( buffer, fieldName );
-
-        if ( value == null )
-        {
-            appendNullText( buffer, fieldName );
-
-        }
-        else
-        {
-            appendInternal( buffer, fieldName, value, isFullDetail( fullDetail ) );
-        }
-
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code>,
-     * correctly interpreting its type.
-     * </p>
-     * <p>
-     * This method performs the main lookup by Class type to correctly route
-     * arrays, <code>Collections</code>, <code>Maps</code> and
-     * <code>Objects</code> to the appropriate method.
-     * </p>
-     * <p>
-     * Either detail or summary views can be specified.
-     * </p>
-     * <p>
-     * If a cycle is detected, an object will be appended with the
-     * <code>Object.toString()</code> format.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param value
-     *            the value to add to the <code>toString</code>, not
-     *            <code>null</code>
-     * @param detail
-     *            output detail or not
-     */
-    protected void appendInternal( StringBuffer buffer, String fieldName, Object value, boolean detail )
-    {
-        if ( ReflectionToStringBuilder.isRegistered( value )
-            && !( value instanceof Number || value instanceof Boolean || value instanceof Character ) )
-        {
-            ObjectUtils.appendIdentityToString( buffer, value );
-
-        }
-        else if ( value instanceof Collection )
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, ( Collection ) value );
-            }
-            else
-            {
-                appendSummarySize( buffer, fieldName, ( ( Collection ) value ).size() );
-            }
-
-        }
-        else if ( value instanceof Map )
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, ( Map ) value );
-            }
-            else
-            {
-                appendSummarySize( buffer, fieldName, ( ( Map ) value ).size() );
-            }
-
-        }
-        else if ( value instanceof long[] )
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, ( long[] ) value );
-            }
-            else
-            {
-                appendSummary( buffer, fieldName, ( long[] ) value );
-            }
-
-        }
-        else if ( value instanceof int[] )
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, ( int[] ) value );
-            }
-            else
-            {
-                appendSummary( buffer, fieldName, ( int[] ) value );
-            }
-
-        }
-        else if ( value instanceof short[] )
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, ( short[] ) value );
-            }
-            else
-            {
-                appendSummary( buffer, fieldName, ( short[] ) value );
-            }
-
-        }
-        else if ( value instanceof byte[] )
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, ( byte[] ) value );
-            }
-            else
-            {
-                appendSummary( buffer, fieldName, ( byte[] ) value );
-            }
-
-        }
-        else if ( value instanceof char[] )
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, ( char[] ) value );
-            }
-            else
-            {
-                appendSummary( buffer, fieldName, ( char[] ) value );
-            }
-
-        }
-        else if ( value instanceof double[] )
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, ( double[] ) value );
-            }
-            else
-            {
-                appendSummary( buffer, fieldName, ( double[] ) value );
-            }
-
-        }
-        else if ( value instanceof float[] )
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, ( float[] ) value );
-            }
-            else
-            {
-                appendSummary( buffer, fieldName, ( float[] ) value );
-            }
-
-        }
-        else if ( value instanceof boolean[] )
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, ( boolean[] ) value );
-            }
-            else
-            {
-                appendSummary( buffer, fieldName, ( boolean[] ) value );
-            }
-
-        }
-        else if ( value.getClass().isArray() )
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, ( Object[] ) value );
-            }
-            else
-            {
-                appendSummary( buffer, fieldName, ( Object[] ) value );
-            }
-
-        }
-        else
-        {
-            if ( detail )
-            {
-                appendDetail( buffer, fieldName, value );
-            }
-            else
-            {
-                appendSummary( buffer, fieldName, value );
-            }
-        }
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code> value,
-     * printing the full detail of the <code>Object</code>.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param value
-     *            the value to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, Object value )
-    {
-        buffer.append( value );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>Collection</code>.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param coll
-     *            the <code>Collection</code> to add to the
-     *            <code>toString</code>, not <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, Collection coll )
-    {
-        buffer.append( coll );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>Map<code>.</p>
-     *
-     * @param buffer  the <code>StringBuffer</code> to populate
-     * @param fieldName  the field name, typically not used as already appended
-     * @param map  the <code>Map</code> to add to the <code>toString</code>,
-     *  not <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, Map map )
-    {
-        buffer.append( map );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code> value,
-     * printing a summary of the <code>Object</code>.
-     * </P>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param value
-     *            the value to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendSummary( StringBuffer buffer, String fieldName, Object value )
-    {
-        buffer.append( summaryObjectStartText );
-        buffer.append( getShortClassName( value.getClass() ) );
-        buffer.append( summaryObjectEndText );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>long</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    public void append( StringBuffer buffer, String fieldName, long value )
-    {
-        appendFieldStart( buffer, fieldName );
-        appendDetail( buffer, fieldName, value );
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>long</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, long value )
-    {
-        buffer.append( value );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>int</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    public void append( StringBuffer buffer, String fieldName, int value )
-    {
-        appendFieldStart( buffer, fieldName );
-        appendDetail( buffer, fieldName, value );
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>int</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, int value )
-    {
-        buffer.append( value );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>short</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    public void append( StringBuffer buffer, String fieldName, short value )
-    {
-        appendFieldStart( buffer, fieldName );
-        appendDetail( buffer, fieldName, value );
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>short</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, short value )
-    {
-        buffer.append( value );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>byte</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    public void append( StringBuffer buffer, String fieldName, byte value )
-    {
-        appendFieldStart( buffer, fieldName );
-        appendDetail( buffer, fieldName, value );
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>byte</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, byte value )
-    {
-        buffer.append( value );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>char</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    public void append( StringBuffer buffer, String fieldName, char value )
-    {
-        appendFieldStart( buffer, fieldName );
-        appendDetail( buffer, fieldName, value );
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>char</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, char value )
-    {
-        buffer.append( value );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>double</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    public void append( StringBuffer buffer, String fieldName, double value )
-    {
-        appendFieldStart( buffer, fieldName );
-        appendDetail( buffer, fieldName, value );
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>double</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, double value )
-    {
-        buffer.append( value );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>float</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    public void append( StringBuffer buffer, String fieldName, float value )
-    {
-        appendFieldStart( buffer, fieldName );
-        appendDetail( buffer, fieldName, value );
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>float</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, float value )
-    {
-        buffer.append( value );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>boolean</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    public void append( StringBuffer buffer, String fieldName, boolean value )
-    {
-        appendFieldStart( buffer, fieldName );
-        appendDetail( buffer, fieldName, value );
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>boolean</code> value.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param value
-     *            the value to add to the <code>toString</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, boolean value )
-    {
-        buffer.append( value );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>Object</code> array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the toString
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info, <code>null</code> for style decides
-     */
-    public void append( StringBuffer buffer, String fieldName, Object[] array, Boolean fullDetail )
-    {
-        appendFieldStart( buffer, fieldName );
-
-        if ( array == null )
-        {
-            appendNullText( buffer, fieldName );
-
-        }
-        else if ( isFullDetail( fullDetail ) )
-        {
-            appendDetail( buffer, fieldName, array );
-
-        }
-        else
-        {
-            appendSummary( buffer, fieldName, array );
-        }
-
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the detail of an
-     * <code>Object</code> array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, Object[] array )
-    {
-        buffer.append( arrayStart );
-        for ( int i = 0; i < array.length; i++ )
-        {
-            Object item = array[i];
-            if ( i > 0 )
-            {
-                buffer.append( arraySeparator );
-            }
-            if ( item == null )
-            {
-                appendNullText( buffer, fieldName );
-
-            }
-            else
-            {
-                appendInternal( buffer, fieldName, item, arrayContentDetail );
-            }
-        }
-        buffer.append( arrayEnd );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the detail of an array type.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     * @since 2.0
-     */
-    protected void reflectionAppendArrayDetail( StringBuffer buffer, String fieldName, Object array )
-    {
-        buffer.append( arrayStart );
-        int length = Array.getLength( array );
-        for ( int i = 0; i < length; i++ )
-        {
-            Object item = Array.get( array, i );
-            if ( i > 0 )
-            {
-                buffer.append( arraySeparator );
-            }
-            if ( item == null )
-            {
-                appendNullText( buffer, fieldName );
-
-            }
-            else
-            {
-                appendInternal( buffer, fieldName, item, arrayContentDetail );
-            }
-        }
-        buffer.append( arrayEnd );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a summary of an <code>Object</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendSummary( StringBuffer buffer, String fieldName, Object[] array )
-    {
-        appendSummarySize( buffer, fieldName, array.length );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>long</code> array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info, <code>null</code> for style decides
-     */
-    public void append( StringBuffer buffer, String fieldName, long[] array, Boolean fullDetail )
-    {
-        appendFieldStart( buffer, fieldName );
-
-        if ( array == null )
-        {
-            appendNullText( buffer, fieldName );
-
-        }
-        else if ( isFullDetail( fullDetail ) )
-        {
-            appendDetail( buffer, fieldName, array );
-
-        }
-        else
-        {
-            appendSummary( buffer, fieldName, array );
-        }
-
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the detail of a <code>long</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, long[] array )
-    {
-        buffer.append( arrayStart );
-        for ( int i = 0; i < array.length; i++ )
-        {
-            if ( i > 0 )
-            {
-                buffer.append( arraySeparator );
-            }
-            appendDetail( buffer, fieldName, array[i] );
-        }
-        buffer.append( arrayEnd );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a summary of a <code>long</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendSummary( StringBuffer buffer, String fieldName, long[] array )
-    {
-        appendSummarySize( buffer, fieldName, array.length );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an <code>int</code> array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info, <code>null</code> for style decides
-     */
-    public void append( StringBuffer buffer, String fieldName, int[] array, Boolean fullDetail )
-    {
-        appendFieldStart( buffer, fieldName );
-
-        if ( array == null )
-        {
-            appendNullText( buffer, fieldName );
-
-        }
-        else if ( isFullDetail( fullDetail ) )
-        {
-            appendDetail( buffer, fieldName, array );
-
-        }
-        else
-        {
-            appendSummary( buffer, fieldName, array );
-        }
-
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the detail of an <code>int</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, int[] array )
-    {
-        buffer.append( arrayStart );
-        for ( int i = 0; i < array.length; i++ )
-        {
-            if ( i > 0 )
-            {
-                buffer.append( arraySeparator );
-            }
-            appendDetail( buffer, fieldName, array[i] );
-        }
-        buffer.append( arrayEnd );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a summary of an <code>int</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendSummary( StringBuffer buffer, String fieldName, int[] array )
-    {
-        appendSummarySize( buffer, fieldName, array.length );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>short</code> array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info, <code>null</code> for style decides
-     */
-    public void append( StringBuffer buffer, String fieldName, short[] array, Boolean fullDetail )
-    {
-        appendFieldStart( buffer, fieldName );
-
-        if ( array == null )
-        {
-            appendNullText( buffer, fieldName );
-
-        }
-        else if ( isFullDetail( fullDetail ) )
-        {
-            appendDetail( buffer, fieldName, array );
-
-        }
-        else
-        {
-            appendSummary( buffer, fieldName, array );
-        }
-
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the detail of a <code>short</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, short[] array )
-    {
-        buffer.append( arrayStart );
-        for ( int i = 0; i < array.length; i++ )
-        {
-            if ( i > 0 )
-            {
-                buffer.append( arraySeparator );
-            }
-            appendDetail( buffer, fieldName, array[i] );
-        }
-        buffer.append( arrayEnd );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a summary of a <code>short</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendSummary( StringBuffer buffer, String fieldName, short[] array )
-    {
-        appendSummarySize( buffer, fieldName, array.length );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>byte</code> array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info, <code>null</code> for style decides
-     */
-    public void append( StringBuffer buffer, String fieldName, byte[] array, Boolean fullDetail )
-    {
-        appendFieldStart( buffer, fieldName );
-
-        if ( array == null )
-        {
-            appendNullText( buffer, fieldName );
-
-        }
-        else if ( isFullDetail( fullDetail ) )
-        {
-            appendDetail( buffer, fieldName, array );
-
-        }
-        else
-        {
-            appendSummary( buffer, fieldName, array );
-        }
-
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the detail of a <code>byte</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, byte[] array )
-    {
-        buffer.append( arrayStart );
-        for ( int i = 0; i < array.length; i++ )
-        {
-            if ( i > 0 )
-            {
-                buffer.append( arraySeparator );
-            }
-            appendDetail( buffer, fieldName, array[i] );
-        }
-        buffer.append( arrayEnd );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a summary of a <code>byte</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendSummary( StringBuffer buffer, String fieldName, byte[] array )
-    {
-        appendSummarySize( buffer, fieldName, array.length );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>char</code> array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the <code>toString</code>
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info, <code>null</code> for style decides
-     */
-    public void append( StringBuffer buffer, String fieldName, char[] array, Boolean fullDetail )
-    {
-        appendFieldStart( buffer, fieldName );
-
-        if ( array == null )
-        {
-            appendNullText( buffer, fieldName );
-
-        }
-        else if ( isFullDetail( fullDetail ) )
-        {
-            appendDetail( buffer, fieldName, array );
-
-        }
-        else
-        {
-            appendSummary( buffer, fieldName, array );
-        }
-
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the detail of a <code>char</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, char[] array )
-    {
-        buffer.append( arrayStart );
-        for ( int i = 0; i < array.length; i++ )
-        {
-            if ( i > 0 )
-            {
-                buffer.append( arraySeparator );
-            }
-            appendDetail( buffer, fieldName, array[i] );
-        }
-        buffer.append( arrayEnd );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a summary of a <code>char</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendSummary( StringBuffer buffer, String fieldName, char[] array )
-    {
-        appendSummarySize( buffer, fieldName, array.length );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>double</code> array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the toString
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info, <code>null</code> for style decides
-     */
-    public void append( StringBuffer buffer, String fieldName, double[] array, Boolean fullDetail )
-    {
-        appendFieldStart( buffer, fieldName );
-
-        if ( array == null )
-        {
-            appendNullText( buffer, fieldName );
-
-        }
-        else if ( isFullDetail( fullDetail ) )
-        {
-            appendDetail( buffer, fieldName, array );
-
-        }
-        else
-        {
-            appendSummary( buffer, fieldName, array );
-        }
-
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the detail of a <code>double</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, double[] array )
-    {
-        buffer.append( arrayStart );
-        for ( int i = 0; i < array.length; i++ )
-        {
-            if ( i > 0 )
-            {
-                buffer.append( arraySeparator );
-            }
-            appendDetail( buffer, fieldName, array[i] );
-        }
-        buffer.append( arrayEnd );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a summary of a <code>double</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendSummary( StringBuffer buffer, String fieldName, double[] array )
-    {
-        appendSummarySize( buffer, fieldName, array.length );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>float</code> array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the toString
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info, <code>null</code> for style decides
-     */
-    public void append( StringBuffer buffer, String fieldName, float[] array, Boolean fullDetail )
-    {
-        appendFieldStart( buffer, fieldName );
-
-        if ( array == null )
-        {
-            appendNullText( buffer, fieldName );
-
-        }
-        else if ( isFullDetail( fullDetail ) )
-        {
-            appendDetail( buffer, fieldName, array );
-
-        }
-        else
-        {
-            appendSummary( buffer, fieldName, array );
-        }
-
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the detail of a <code>float</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, float[] array )
-    {
-        buffer.append( arrayStart );
-        for ( int i = 0; i < array.length; i++ )
-        {
-            if ( i > 0 )
-            {
-                buffer.append( arraySeparator );
-            }
-            appendDetail( buffer, fieldName, array[i] );
-        }
-        buffer.append( arrayEnd );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a summary of a <code>float</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendSummary( StringBuffer buffer, String fieldName, float[] array )
-    {
-        appendSummarySize( buffer, fieldName, array.length );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a <code>boolean</code> array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     * @param array
-     *            the array to add to the toString
-     * @param fullDetail
-     *            <code>true</code> for detail, <code>false</code> for
-     *            summary info, <code>null</code> for style decides
-     */
-    public void append( StringBuffer buffer, String fieldName, boolean[] array, Boolean fullDetail )
-    {
-        appendFieldStart( buffer, fieldName );
-
-        if ( array == null )
-        {
-            appendNullText( buffer, fieldName );
-
-        }
-        else if ( isFullDetail( fullDetail ) )
-        {
-            appendDetail( buffer, fieldName, array );
-
-        }
-        else
-        {
-            appendSummary( buffer, fieldName, array );
-        }
-
-        appendFieldEnd( buffer, fieldName );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the detail of a
-     * <code>boolean</code> array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendDetail( StringBuffer buffer, String fieldName, boolean[] array )
-    {
-        buffer.append( arrayStart );
-        for ( int i = 0; i < array.length; i++ )
-        {
-            if ( i > 0 )
-            {
-                buffer.append( arraySeparator );
-            }
-            appendDetail( buffer, fieldName, array[i] );
-        }
-        buffer.append( arrayEnd );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a summary of a <code>boolean</code>
-     * array.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     * @param array
-     *            the array to add to the <code>toString</code>, not
-     *            <code>null</code>
-     */
-    protected void appendSummary( StringBuffer buffer, String fieldName, boolean[] array )
-    {
-        appendSummarySize( buffer, fieldName, array.length );
-    }
-
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the class name.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param object
-     *            the <code>Object</code> whose name to output
-     */
-    protected void appendClassName( StringBuffer buffer, Object object )
-    {
-        if ( useClassName && object != null )
-        {
-            if ( useShortClassName )
-            {
-                buffer.append( getShortClassName( object.getClass() ) );
-            }
-            else
-            {
-                buffer.append( object.getClass().getName() );
-            }
-        }
-    }
-
-
-    /**
-     * <p>
-     * Append the {@link System#identityHashCode(java.lang.Object)}.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param object
-     *            the <code>Object</code> whose id to output
-     */
-    protected void appendIdentityHashCode( StringBuffer buffer, Object object )
-    {
-        if ( this.isUseIdentityHashCode() && object != null )
-        {
-            buffer.append( '@' );
-            buffer.append( Integer.toHexString( System.identityHashCode( object ) ) );
-        }
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the content start.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     */
-    protected void appendContentStart( StringBuffer buffer )
-    {
-        buffer.append( contentStart );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the content end.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     */
-    protected void appendContentEnd( StringBuffer buffer )
-    {
-        buffer.append( contentEnd );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> an indicator for <code>null</code>.
-     * </p>
-     * <p>
-     * The default indicator is <code>'&lt;null&gt;'</code>.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name, typically not used as already appended
-     */
-    protected void appendNullText( StringBuffer buffer, String fieldName )
-    {
-        buffer.append( nullText );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the field separator.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     */
-    protected void appendFieldSeparator( StringBuffer buffer )
-    {
-        buffer.append( fieldSeparator );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> the field start.
-     * </p>
-     * 
-     * @param buffer
-     *            the <code>StringBuffer</code> to populate
-     * @param fieldName
-     *            the field name
-     */
-    protected void appendFieldStart( StringBuffer buffer, String fieldName )
-    {
-        if ( useFieldNames && fieldName != null )
-        {
-            buffer.append( fieldName );
-            buffer.append( fieldNameValueSeparator );
-        }
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString<code> the field end.</p>
-     * 
-     * @param buffer  the <code>StringBuffer</code> to populate
-     * @param fieldName  the field name, typically not used as already appended
-     */
-    protected void appendFieldEnd( StringBuffer buffer, String fieldName )
-    {
-        appendFieldSeparator( buffer );
-    }
-
-
-    /**
-     * <p>
-     * Append to the <code>toString</code> a size summary.
-     * </p>
-     * <p>
-     * The size summary is used to summarize the contents of
-     * <code>Collections</code>, <code>Maps</code> and arrays.
-     * </p>
-     * <p>
-     * The output consists of a prefix, the passed in size and a suffix.
-     * </p>
-     * <p>
-     * The default format is <code>'&lt;size=n&gt;'<code>.</p>
-     *
-     * @param buffer  the <code>StringBuffer</code> to populate
-     * @param fieldName  the field name, typically not used as already appended
-     * @param size  the size to append
-     */
-    protected void appendSummarySize( StringBuffer buffer, String fieldName, int size )
-    {
-        buffer.append( sizeStartText );
-        buffer.append( size );
-        buffer.append( sizeEndText );
-    }
-
-
-    /**
-     * <p>
-     * Is this field to be output in full detail.
-     * </p>
-     * <p>
-     * This method converts a detail request into a detail level. The calling
-     * code may request full detail (<code>true</code>), but a subclass
-     * might ignore that and always return <code>false</code>. The calling
-     * code may pass in <code>null</code> indicating that it doesn't care
-     * about the detail level. In this case the default detail level is used.
-     * </p>
-     * 
-     * @param fullDetailRequest
-     *            the detail level requested
-     * @return whether full detail is to be shown
-     */
-    protected boolean isFullDetail( Boolean fullDetailRequest )
-    {
-        if ( fullDetailRequest == null )
-        {
-            return defaultFullDetail;
-        }
-        return fullDetailRequest.booleanValue();
-    }
-
-
-    /**
-     * <p>
-     * Gets the short class name for a class.
-     * </p>
-     * <p>
-     * The short class name is the classname excluding the package name.
-     * </p>
-     * 
-     * @param cls
-     *            the <code>Class</code> to get the short name of
-     * @return the short name
-     */
-    protected String getShortClassName( Class cls )
-    {
-        return ClassUtils.getShortClassName( cls );
-    }
-
-
-    // Setters and getters for the customizable parts of the style
-    // These methods are not expected to be overridden, except to make public
-    // (They are not public so that immutable subclasses can be written)
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets whether to use the class name.
-     * </p>
-     * 
-     * @return the current useClassName flag
-     */
-    protected boolean isUseClassName()
-    {
-        return useClassName;
-    }
-
-
-    /**
-     * <p>
-     * Sets whether to use the class name.
-     * </p>
-     * 
-     * @param useClassName
-     *            the new useClassName flag
-     */
-    protected void setUseClassName( boolean useClassName )
-    {
-        this.useClassName = useClassName;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets whether to output short or long class names.
-     * </p>
-     * 
-     * @return the current useShortClassName flag
-     * @since 2.0
-     */
-    protected boolean isUseShortClassName()
-    {
-        return useShortClassName;
-    }
-
-
-    /**
-     * <p>
-     * Gets whether to output short or long class names.
-     * </p>
-     * 
-     * @return the current shortClassName flag
-     * @deprecated Use {@link #isUseShortClassName()} Method will be removed in
-     *             Commons Lang 3.0.
-     */
-    protected boolean isShortClassName()
-    {
-        return useShortClassName;
-    }
-
-
-    /**
-     * <p>
-     * Sets whether to output short or long class names.
-     * </p>
-     * 
-     * @param useShortClassName
-     *            the new useShortClassName flag
-     * @since 2.0
-     */
-    protected void setUseShortClassName( boolean useShortClassName )
-    {
-        this.useShortClassName = useShortClassName;
-    }
-
-
-    /**
-     * <p>
-     * Sets whether to output short or long class names.
-     * </p>
-     * 
-     * @param shortClassName
-     *            the new shortClassName flag
-     * @deprecated Use {@link #setUseShortClassName(boolean)} Method will be
-     *             removed in Commons Lang 3.0.
-     */
-    protected void setShortClassName( boolean shortClassName )
-    {
-        this.useShortClassName = shortClassName;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets whether to use the identity hash code.
-     * </p>
-     * 
-     * @return the current useIdentityHashCode flag
-     */
-    protected boolean isUseIdentityHashCode()
-    {
-        return useIdentityHashCode;
-    }
-
-
-    /**
-     * <p>
-     * Sets whether to use the identity hash code.
-     * </p>
-     * 
-     * @param useIdentityHashCode
-     *            the new useIdentityHashCode flag
-     */
-    protected void setUseIdentityHashCode( boolean useIdentityHashCode )
-    {
-        this.useIdentityHashCode = useIdentityHashCode;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets whether to use the field names passed in.
-     * </p>
-     * 
-     * @return the current useFieldNames flag
-     */
-    protected boolean isUseFieldNames()
-    {
-        return useFieldNames;
-    }
-
-
-    /**
-     * <p>
-     * Sets whether to use the field names passed in.
-     * </p>
-     * 
-     * @param useFieldNames
-     *            the new useFieldNames flag
-     */
-    protected void setUseFieldNames( boolean useFieldNames )
-    {
-        this.useFieldNames = useFieldNames;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets whether to use full detail when the caller doesn't specify.
-     * </p>
-     * 
-     * @return the current defaultFullDetail flag
-     */
-    protected boolean isDefaultFullDetail()
-    {
-        return defaultFullDetail;
-    }
-
-
-    /**
-     * <p>
-     * Sets whether to use full detail when the caller doesn't specify.
-     * </p>
-     * 
-     * @param defaultFullDetail
-     *            the new defaultFullDetail flag
-     */
-    protected void setDefaultFullDetail( boolean defaultFullDetail )
-    {
-        this.defaultFullDetail = defaultFullDetail;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets whether to output array content detail.
-     * </p>
-     * 
-     * @return the current array content detail setting
-     */
-    protected boolean isArrayContentDetail()
-    {
-        return arrayContentDetail;
-    }
-
-
-    /**
-     * <p>
-     * Sets whether to output array content detail.
-     * </p>
-     * 
-     * @param arrayContentDetail
-     *            the new arrayContentDetail flag
-     */
-    protected void setArrayContentDetail( boolean arrayContentDetail )
-    {
-        this.arrayContentDetail = arrayContentDetail;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the array start text.
-     * </p>
-     * 
-     * @return the current array start text
-     */
-    protected String getArrayStart()
-    {
-        return arrayStart;
-    }
-
-
-    /**
-     * <p>
-     * Sets the array start text.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param arrayStart
-     *            the new array start text
-     */
-    protected void setArrayStart( String arrayStart )
-    {
-        if ( arrayStart == null )
-        {
-            arrayStart = "";
-        }
-        this.arrayStart = arrayStart;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the array end text.
-     * </p>
-     * 
-     * @return the current array end text
-     */
-    protected String getArrayEnd()
-    {
-        return arrayEnd;
-    }
-
-
-    /**
-     * <p>
-     * Sets the array end text.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param arrayEnd
-     *            the new array end text
-     */
-    protected void setArrayEnd( String arrayEnd )
-    {
-        if ( arrayStart == null )
-        {
-            arrayStart = "";
-        }
-        this.arrayEnd = arrayEnd;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the array separator text.
-     * </p>
-     * 
-     * @return the current array separator text
-     */
-    protected String getArraySeparator()
-    {
-        return arraySeparator;
-    }
-
-
-    /**
-     * <p>
-     * Sets the array separator text.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param arraySeparator
-     *            the new array separator text
-     */
-    protected void setArraySeparator( String arraySeparator )
-    {
-        if ( arraySeparator == null )
-        {
-            arraySeparator = "";
-        }
-        this.arraySeparator = arraySeparator;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the content start text.
-     * </p>
-     * 
-     * @return the current content start text
-     */
-    protected String getContentStart()
-    {
-        return contentStart;
-    }
-
-
-    /**
-     * <p>
-     * Sets the content start text.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param contentStart
-     *            the new content start text
-     */
-    protected void setContentStart( String contentStart )
-    {
-        if ( contentStart == null )
-        {
-            contentStart = "";
-        }
-        this.contentStart = contentStart;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the content end text.
-     * </p>
-     * 
-     * @return the current content end text
-     */
-    protected String getContentEnd()
-    {
-        return contentEnd;
-    }
-
-
-    /**
-     * <p>
-     * Sets the content end text.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param contentEnd
-     *            the new content end text
-     */
-    protected void setContentEnd( String contentEnd )
-    {
-        if ( contentEnd == null )
-        {
-            contentEnd = "";
-        }
-        this.contentEnd = contentEnd;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the field name value separator text.
-     * </p>
-     * 
-     * @return the current field name value separator text
-     */
-    protected String getFieldNameValueSeparator()
-    {
-        return fieldNameValueSeparator;
-    }
-
-
-    /**
-     * <p>
-     * Sets the field name value separator text.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param fieldNameValueSeparator
-     *            the new field name value separator text
-     */
-    protected void setFieldNameValueSeparator( String fieldNameValueSeparator )
-    {
-        if ( fieldNameValueSeparator == null )
-        {
-            fieldNameValueSeparator = "";
-        }
-        this.fieldNameValueSeparator = fieldNameValueSeparator;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the field separator text.
-     * </p>
-     * 
-     * @return the current field separator text
-     */
-    protected String getFieldSeparator()
-    {
-        return fieldSeparator;
-    }
-
-
-    /**
-     * <p>
-     * Sets the field separator text.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param fieldSeparator
-     *            the new field separator text
-     */
-    protected void setFieldSeparator( String fieldSeparator )
-    {
-        if ( fieldSeparator == null )
-        {
-            fieldSeparator = "";
-        }
-        this.fieldSeparator = fieldSeparator;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets whether the field separator should be added at the start of each
-     * buffer.
-     * </p>
-     * 
-     * @return the fieldSeparatorAtStart flag
-     * @since 2.0
-     */
-    protected boolean isFieldSeparatorAtStart()
-    {
-        return fieldSeparatorAtStart;
-    }
-
-
-    /**
-     * <p>
-     * Sets whether the field separator should be added at the start of each
-     * buffer.
-     * </p>
-     * 
-     * @param fieldSeparatorAtStart
-     *            the fieldSeparatorAtStart flag
-     * @since 2.0
-     */
-    protected void setFieldSeparatorAtStart( boolean fieldSeparatorAtStart )
-    {
-        this.fieldSeparatorAtStart = fieldSeparatorAtStart;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets whether the field separator should be added at the end of each
-     * buffer.
-     * </p>
-     * 
-     * @return fieldSeparatorAtEnd flag
-     * @since 2.0
-     */
-    protected boolean isFieldSeparatorAtEnd()
-    {
-        return fieldSeparatorAtEnd;
-    }
-
-
-    /**
-     * <p>
-     * Sets whether the field separator should be added at the end of each
-     * buffer.
-     * </p>
-     * 
-     * @param fieldSeparatorAtEnd
-     *            the fieldSeparatorAtEnd flag
-     * @since 2.0
-     */
-    protected void setFieldSeparatorAtEnd( boolean fieldSeparatorAtEnd )
-    {
-        this.fieldSeparatorAtEnd = fieldSeparatorAtEnd;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the text to output when <code>null</code> found.
-     * </p>
-     * 
-     * @return the current text to output when null found
-     */
-    protected String getNullText()
-    {
-        return nullText;
-    }
-
-
-    /**
-     * <p>
-     * Sets the text to output when <code>null</code> found.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param nullText
-     *            the new text to output when null found
-     */
-    protected void setNullText( String nullText )
-    {
-        if ( nullText == null )
-        {
-            nullText = "";
-        }
-        this.nullText = nullText;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the start text to output when a <code>Collection</code>,
-     * <code>Map</code> or array size is output.
-     * </p>
-     * <p>
-     * This is output before the size value.
-     * </p>
-     * 
-     * @return the current start of size text
-     */
-    protected String getSizeStartText()
-    {
-        return sizeStartText;
-    }
-
-
-    /**
-     * <p>
-     * Sets the start text to output when a <code>Collection</code>,
-     * <code>Map</code> or array size is output.
-     * </p>
-     * <p>
-     * This is output before the size value.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param sizeStartText
-     *            the new start of size text
-     */
-    protected void setSizeStartText( String sizeStartText )
-    {
-        if ( sizeStartText == null )
-        {
-            sizeStartText = "";
-        }
-        this.sizeStartText = sizeStartText;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the end text to output when a <code>Collection</code>,
-     * <code>Map</code> or array size is output.
-     * </p>
-     * <p>
-     * This is output after the size value.
-     * </p>
-     * 
-     * @return the current end of size text
-     */
-    protected String getSizeEndText()
-    {
-        return sizeEndText;
-    }
-
-
-    /**
-     * <p>
-     * Sets the end text to output when a <code>Collection</code>,
-     * <code>Map</code> or array size is output.
-     * </p>
-     * <p>
-     * This is output after the size value.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param sizeEndText
-     *            the new end of size text
-     */
-    protected void setSizeEndText( String sizeEndText )
-    {
-        if ( sizeEndText == null )
-        {
-            sizeEndText = "";
-        }
-        this.sizeEndText = sizeEndText;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the start text to output when an <code>Object</code> is output in
-     * summary mode.
-     * </p>
-     * <p>
-     * This is output before the size value.
-     * </p>
-     * 
-     * @return the current start of summary text
-     */
-    protected String getSummaryObjectStartText()
-    {
-        return summaryObjectStartText;
-    }
-
-
-    /**
-     * <p>
-     * Sets the start text to output when an <code>Object</code> is output in
-     * summary mode.
-     * </p>
-     * <p>
-     * This is output before the size value.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param summaryObjectStartText
-     *            the new start of summary text
-     */
-    protected void setSummaryObjectStartText( String summaryObjectStartText )
-    {
-        if ( summaryObjectStartText == null )
-        {
-            summaryObjectStartText = "";
-        }
-        this.summaryObjectStartText = summaryObjectStartText;
-    }
-
-
-    // ---------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Gets the end text to output when an <code>Object</code> is output in
-     * summary mode.
-     * </p>
-     * <p>
-     * This is output after the size value.
-     * </p>
-     * 
-     * @return the current end of summary text
-     */
-    protected String getSummaryObjectEndText()
-    {
-        return summaryObjectEndText;
-    }
-
-
-    /**
-     * <p>
-     * Sets the end text to output when an <code>Object</code> is output in
-     * summary mode.
-     * </p>
-     * <p>
-     * This is output after the size value.
-     * </p>
-     * <p>
-     * <code>null</code> is accepted, but will be converted to an empty
-     * String.
-     * </p>
-     * 
-     * @param summaryObjectEndText
-     *            the new end of summary text
-     */
-    protected void setSummaryObjectEndText( String summaryObjectEndText )
-    {
-        if ( summaryObjectEndText == null )
-        {
-            summaryObjectEndText = "";
-        }
-        this.summaryObjectEndText = summaryObjectEndText;
-    }
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * Default <code>ToStringStyle</code>.
-     * </p>
-     * <p>
-     * This is an inner class rather than using
-     * <code>StandardToStringStyle</code> to ensure its immutability.
-     * </p>
-     */
-    private static final class DefaultToStringStyle extends ToStringStyle
-    {
-
-        static final long serialVersionUID = -3594451267200535036L;
-
-
-        /**
-         * <p>
-         * Constructor.
-         * </p>
-         * <p>
-         * Use the static constant rather than instantiating.
-         * </p>
-         */
-        private DefaultToStringStyle()
-        {
-            super();
-        }
-
-
-        /**
-         * <p>
-         * Ensure <code>Singleton</code> after serialization.
-         * </p>
-         * 
-         * @return the singleton
-         */
-        private Object readResolve()
-        {
-            return ToStringStyle.DEFAULT_STYLE;
-        }
-
-    }
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * <code>ToStringStyle</code> that does not print out the field names.
-     * </p>
-     * <p>
-     * This is an inner class rather than using
-     * <code>StandardToStringStyle</code> to ensure its immutability.
-     */
-    private static final class NoFieldNameToStringStyle extends ToStringStyle
-    {
-
-        static final long serialVersionUID = -3594451267200535036L;
-
-
-        /**
-         * <p>
-         * Constructor.
-         * </p>
-         * <p>
-         * Use the static constant rather than instantiating.
-         * </p>
-         */
-        private NoFieldNameToStringStyle()
-        {
-            super();
-            this.setUseFieldNames( false );
-        }
-
-
-        /**
-         * <p>
-         * Ensure <code>Singleton</code> after serialization.
-         * </p>
-         * 
-         * @return the singleton
-         */
-        private Object readResolve()
-        {
-            return ToStringStyle.NO_FIELD_NAMES_STYLE;
-        }
-
-    }
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * <code>ToStringStyle</code> that prints out the short class name and no
-     * identity hashcode.
-     * </p>
-     * <p>
-     * This is an inner class rather than using
-     * <code>StandardToStringStyle</code> to ensure its immutability.
-     * </p>
-     */
-    private static final class ShortPrefixToStringStyle extends ToStringStyle
-    {
-
-        static final long serialVersionUID = -3594451267200535036L;
-
-
-        /**
-         * <p>
-         * Constructor.
-         * </p>
-         * <p>
-         * Use the static constant rather than instantiating.
-         * </p>
-         */
-        private ShortPrefixToStringStyle()
-        {
-            super();
-            this.setUseShortClassName( true );
-            this.setUseIdentityHashCode( false );
-        }
-
-
-        /**
-         * <p>
-         * Ensure <code>Singleton</ode> after serialization.</p>
-         * @return the singleton
-         */
-        private Object readResolve()
-        {
-            return ToStringStyle.SHORT_PREFIX_STYLE;
-        }
-
-    }
-
-    /**
-     * <p>
-     * <code>ToStringStyle</code> that does not print out the classname,
-     * identity hashcode, content start or field name.
-     * </p>
-     * <p>
-     * This is an inner class rather than using
-     * <code>StandardToStringStyle</code> to ensure its immutability.
-     * </p>
-     */
-    private static final class SimpleToStringStyle extends ToStringStyle
-    {
-
-        static final long serialVersionUID = -3594451267200535036L;
-
-
-        /**
-         * <p>
-         * Constructor.
-         * </p>
-         * <p>
-         * Use the static constant rather than instantiating.
-         * </p>
-         */
-        private SimpleToStringStyle()
-        {
-            super();
-            this.setUseClassName( false );
-            this.setUseIdentityHashCode( false );
-            this.setUseFieldNames( false );
-            this.setContentStart( "" );
-            this.setContentEnd( "" );
-        }
-
-
-        /**
-         * <p>
-         * Ensure <code>Singleton</ode> after serialization.</p>
-         * @return the singleton
-         */
-        private Object readResolve()
-        {
-            return ToStringStyle.SIMPLE_STYLE;
-        }
-
-    }
-
-    // ----------------------------------------------------------------------------
-
-    /**
-     * <p>
-     * <code>ToStringStyle</code> that outputs on multiple lines.
-     * </p>
-     * <p>
-     * This is an inner class rather than using
-     * <code>StandardToStringStyle</code> to ensure its immutability.
-     * </p>
-     */
-    private static final class MultiLineToStringStyle extends ToStringStyle
-    {
-
-        static final long serialVersionUID = -3594451267200535036L;
-
-
-        /**
-         * <p>
-         * Constructor.
-         * </p>
-         * <p>
-         * Use the static constant rather than instantiating.
-         * </p>
-         */
-        private MultiLineToStringStyle()
-        {
-            super();
-            this.setContentStart( "[" );
-            this.setFieldSeparator( SystemUtils.LINE_SEPARATOR + "  " );
-            this.setFieldSeparatorAtStart( true );
-            this.setContentEnd( SystemUtils.LINE_SEPARATOR + "]" );
-        }
-
-
-        /**
-         * <p>
-         * Ensure <code>Singleton</code> after serialization.
-         * </p>
-         * 
-         * @return the singleton
-         */
-        private Object readResolve()
-        {
-            return ToStringStyle.MULTI_LINE_STYLE;
-        }
-
-    }
-
-    // ----------------------------------------------------------------------------
-
-    // Removed, as the XML style needs more work for escaping characters,
-    // arrays,
-    // collections, maps and embedded beans.
-    // /**
-    // * ToStringStyle that outputs in XML style
-    // */
-    // private static class XMLToStringStyle extends ToStringStyle {
-    //        
-    // /**
-    // * Constructor - use the static constant rather than instantiating.
-    // */
-    // private XMLToStringStyle() {
-    // super();
-    // nullText = "null";
-    // sizeStartText = "size=";
-    // sizeEndText = "";
-    // }
-    //        
-    // /**
-    // * @see ToStringStyle#appendStart(StringBuffer, Object)
-    // */
-    // public void appendStart(StringBuffer buffer, Object object) {
-    // buffer.append('<');
-    // buffer.append(getShortClassName(object.getClass()));
-    // buffer.append(" class=\"");
-    // appendClassName(buffer, object);
-    // buffer.append("\" hashCode=\"");
-    // appendIdentityHashCode(buffer, object);
-    // buffer.append("\">");
-    // buffer.append(SystemUtils.LINE_SEPARATOR);
-    // buffer.append(" ");
-    // }
-    //
-    // /**
-    // * @see ToStringStyle#appendFieldStart(StringBuffer, String)
-    // */
-    // protected void appendFieldStart(StringBuffer buffer, String fieldName) {
-    // buffer.append('<');
-    // buffer.append(fieldName);
-    // buffer.append('>');
-    // }
-    //
-    // /**
-    // * @see ToStringStyle#appendFieldEnd(StringBuffer, String)
-    // */
-    // protected void appendFieldEnd(StringBuffer buffer, String fieldName) {
-    // buffer.append("</");
-    // buffer.append(fieldName);
-    // buffer.append('>');
-    // buffer.append(SystemUtils.LINE_SEPARATOR);
-    // buffer.append(" ");
-    // }
-    //
-    // /**
-    // * @see ToStringStyle#appendEnd(StringBuffer, Object)
-    // */
-    // public void appendEnd(StringBuffer buffer, Object object) {
-    // int len = buffer.length();
-    // if (len > 2 && buffer.charAt(len - 1) == ' ' && buffer.charAt(len - 2) ==
-    // ' ') {
-    // buffer.setLength(len - 2);
-    // }
-    // buffer.append("</");
-    // buffer.append(getShortClassName(object.getClass()));
-    // buffer.append("\">");
-    // }
-    //
-    // }
-
-}
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ArrayNamingEnumerationTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ArrayNamingEnumerationTest.java
index 2ce7cfc..9c1e5b7 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ArrayNamingEnumerationTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ArrayNamingEnumerationTest.java
@@ -22,8 +22,8 @@
 
 import java.util.NoSuchElementException;
 
+import org.apache.commons.lang.ArrayUtils;
 import org.apache.directory.shared.ldap.message.ArrayNamingEnumeration;
-import org.apache.directory.shared.ldap.util.ArrayUtils;
 import org.junit.Test;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/CompareRequestImplTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/CompareRequestImplTest.java
index 360f71e..a350d05 100755
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/CompareRequestImplTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/CompareRequestImplTest.java
@@ -47,7 +47,7 @@
     private static final Map<String, Control> EMPTY_CONTROL_MAP = new HashMap<String, Control>();
 
     /**
-     * Tests the same object referrence for equality.
+     * Tests the same object reference for equality.
      */
     @Test
     public void testEqualsSameObj()
@@ -79,6 +79,37 @@
 
 
     /**
+     * Tests the same object reference for equal hashCode.
+     */
+    @Test
+    public void testHashCodeSameObj()
+    {
+        CompareRequestImpl req = new CompareRequestImpl( 5 );
+        assertTrue( req.hashCode() == req.hashCode() );
+    }
+
+
+    /**
+     * Tests for equal hashCode using exact copies.
+     */
+    @Test
+    public void testHashCodeExactCopy() throws LdapException
+    {
+        CompareRequestImpl req0 = new CompareRequestImpl( 5 );
+        req0.setName( new DN( "cn=admin,dc=example,dc=com" ) );
+        req0.setAttributeId( "objectClass" );
+        req0.setAssertionValue( "top" );
+
+        CompareRequestImpl req1 = new CompareRequestImpl( 5 );
+        req1.setName( new DN( "cn=admin,dc=example,dc=com" ) );
+        req1.setAttributeId( "objectClass" );
+        req1.setAssertionValue( "top" );
+
+        assertTrue( req0.hashCode() == req1.hashCode() );
+    }
+
+
+    /**
      * Test for inequality when only the IDs are different.
      */
     @Test
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/DeleteRequestImplTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/DeleteRequestImplTest.java
index 382ed1c..f5ac83f 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/DeleteRequestImplTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/DeleteRequestImplTest.java
@@ -46,7 +46,7 @@
     private static final Map<String, Control> EMPTY_CONTROL_MAP = new HashMap<String, Control>();
 
     /**
-     * Tests the same object referrence for equality.
+     * Tests the same object reference for equality.
      */
     @Test
     public void testEqualsSameObj()
@@ -73,6 +73,33 @@
 
 
     /**
+     * Tests the same object reference for equal hashCode.
+     */
+    @Test
+    public void testHashCodeSameObj()
+    {
+        DeleteRequestImpl req = new DeleteRequestImpl( 5 );
+        assertTrue( req.hashCode() == req.hashCode() );
+    }
+
+
+    /**
+     * Tests for equal hashCode using exact copies.
+     */
+    @Test
+    public void testHashCodeExactCopy() throws LdapException
+    {
+        DeleteRequestImpl req0 = new DeleteRequestImpl( 5 );
+        req0.setName( new DN( "cn=admin,dc=example,dc=com" ) );
+
+        DeleteRequestImpl req1 = new DeleteRequestImpl( 5 );
+        req1.setName( new DN( "cn=admin,dc=example,dc=com" ) );
+
+        assertTrue( req0.hashCode() == req1.hashCode() );
+    }
+
+
+    /**
      * Test for inequality when only the IDs are different.
      */
     @Test
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ExtendedRequestImplTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ExtendedRequestImplTest.java
index 5e42618..5d1a731 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ExtendedRequestImplTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ExtendedRequestImplTest.java
@@ -47,7 +47,7 @@
     private static final Map<String, Control> EMPTY_CONTROL_MAP = new HashMap<String, Control>();
 
     /**
-     * Tests the same object referrence for equality.
+     * Tests the same object reference for equality.
      */
     @Test
     public void testEqualsSameObj()
@@ -77,6 +77,35 @@
 
 
     /**
+     * Tests the same object reference for equal hashCode.
+     */
+    @Test
+    public void testHashCodeSameObj()
+    {
+        ExtendedRequestImpl req = new ExtendedRequestImpl( 5 );
+        assertTrue( req.hashCode() == req.hashCode() );
+    }
+
+
+    /**
+     * Tests for equal hashCode using exact copies.
+     */
+    @Test
+    public void testHashCodeExactCopy()
+    {
+        ExtendedRequestImpl req0 = new ExtendedRequestImpl( 5 );
+        req0.setOid( "1.1.1.1" );
+        req0.setPayload( "Hello World!".getBytes() );
+
+        ExtendedRequestImpl req1 = new ExtendedRequestImpl( 5 );
+        req1.setOid( "1.1.1.1" );
+        req1.setPayload( "Hello World!".getBytes() );
+
+        assertTrue( req0.hashCode() == req1.hashCode() );
+    }
+
+
+    /**
      * Test for inequality when only the IDs are different.
      */
     @Test
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ExtendedResponseImplTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ExtendedResponseImplTest.java
index 9c0c1f3..3ccd9fe 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ExtendedResponseImplTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ExtendedResponseImplTest.java
@@ -228,6 +228,29 @@
 
 
     /**
+     * Tests for equal hashCode using the same object.
+     */
+    @Test
+    public void testHashCodeSameObj()
+    {
+        ExtendedResponseImpl resp = createStub();
+        assertTrue( resp.hashCode() == resp.hashCode() );
+    }
+
+
+    /**
+     * Tests for equal hashCode using an exact copy.
+     */
+    @Test
+    public void testHashCodeExactCopy()
+    {
+        ExtendedResponseImpl resp0 = createStub();
+        ExtendedResponseImpl resp1 = createStub();
+        assertTrue( resp0.hashCode() == resp1.hashCode() );
+    }
+
+
+    /**
      * Tests inequality when messageIds are different.
      */
     @Test
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/LdapResultImplTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/LdapResultImplTest.java
index 567e690..2692083 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/LdapResultImplTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/LdapResultImplTest.java
@@ -176,6 +176,74 @@
 
 
     /**
+     * Tests to make sure the two same objects have equal HashCode.
+     */
+    @Test
+    public void testHashCodeSameObj()
+    {
+        LdapResultImpl r0 = new LdapResultImpl();
+        assertTrue( r0.hashCode() == r0.hashCode() );
+    }
+
+
+    /**
+     * Tests to make sure a default LdapResultImpl has equal hashCode another one just
+     * created.
+     */
+    @Test
+    public void testHashCodeDefaultCopy()
+    {
+        LdapResultImpl r0 = new LdapResultImpl();
+        LdapResultImpl r1 = new LdapResultImpl();
+
+        assertTrue( r0.hashCode() == r1.hashCode() );
+    }
+
+
+    /**
+     * Tests for equal hashCode when the lockable parent is not the same.
+     */
+    @Test
+    public void testHashCodeDiffLockableParent()
+    {
+        LdapResultImpl r0 = new LdapResultImpl();
+        LdapResultImpl r1 = new LdapResultImpl();
+
+        assertTrue( r0.hashCode() == r1.hashCode() );
+    }
+
+
+    /**
+     * Tests two non default carbon copies for equal hashCode.
+     */
+    @Test
+    public void testHashCodeCarbonCopy() throws LdapException
+    {
+        LdapResultImpl r0 = new LdapResultImpl();
+        LdapResultImpl r1 = new LdapResultImpl();
+
+        r0.setErrorMessage( "blah blah blah" );
+        r1.setErrorMessage( "blah blah blah" );
+
+        r0.setMatchedDn( new DN( "dc=example,dc=com" ) );
+        r1.setMatchedDn( new DN( "dc=example,dc=com" ) );
+
+        r0.setResultCode( ResultCodeEnum.TIME_LIMIT_EXCEEDED );
+        r1.setResultCode( ResultCodeEnum.TIME_LIMIT_EXCEEDED );
+
+        InternalReferral refs0 = new ReferralImpl();
+        refs0.addLdapUrl( "ldap://someserver.com" );
+        refs0.addLdapUrl( "ldap://anotherserver.org" );
+
+        InternalReferral refs1 = new ReferralImpl();
+        refs1.addLdapUrl( "ldap://someserver.com" );
+        refs1.addLdapUrl( "ldap://anotherserver.org" );
+
+        assertTrue( r0.hashCode() == r1.hashCode() );
+    }
+
+
+    /**
      * Tests for inequality when the error message is different.
      */
     @Test
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ModifyDnRequestImplTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ModifyDnRequestImplTest.java
index 9ac410a..95a906e 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ModifyDnRequestImplTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ModifyDnRequestImplTest.java
@@ -73,7 +73,7 @@
 
 
     /**
-     * Tests the same object referrence for equality.
+     * Tests the same object reference for equality.
      */
     @Test
     public void testEqualsSameObj()
@@ -112,6 +112,45 @@
 
 
     /**
+    * Tests the same object reference for equal hashCode
+    */
+   @Test
+   public void testHashCodeSameObj()
+   {
+       ModifyDnRequestImpl req = new ModifyDnRequestImpl( 5 );
+       assertTrue( req.hashCode() == req.hashCode() );
+   }
+
+
+   /**
+    * Tests for equal hashCode using exact copies.
+    */
+   @Test
+   public void testHashCodeExactCopy0()
+   {
+       ModifyDnRequestImpl req0 = getRequest();
+       ModifyDnRequestImpl req1 = getRequest();
+
+       assertTrue( req0.hashCode() == req1.hashCode() );
+   }
+
+
+   /**
+    * Tests for equal hashCode using exact copies.
+    */
+   @Test
+   public void testHashCodeExactCopy1()
+   {
+       ModifyDnRequestImpl req0 = getRequest();
+       req0.setNewSuperior( null );
+       ModifyDnRequestImpl req1 = getRequest();
+       req1.setNewSuperior( null );
+
+       assertTrue( req0.hashCode() == req1.hashCode() );
+   }
+
+
+    /**
      * Test for inequality when only the IDs are different.
      */
     @Test
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ModifyRequestImplTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ModifyRequestImplTest.java
index b772f4a..4067836 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ModifyRequestImplTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ModifyRequestImplTest.java
@@ -95,7 +95,7 @@
 
 
     /**
-     * Tests the same object referrence for equality.
+     * Tests the same object reference for equality.
      */
     @Test
     public void testEqualsSameObj()
@@ -118,6 +118,29 @@
 
 
     /**
+     * Tests the same object reference for equal hashCode.
+     */
+    @Test
+    public void testHashCodeSameObj()
+    {
+        ModifyRequestImpl req = getRequest();
+        assertTrue( req.hashCode() == req.hashCode() );
+    }
+
+
+    /**
+     * Tests for equal hashCode using exact copies.
+     */
+    @Test
+    public void testHashCodeExactCopy()
+    {
+        ModifyRequestImpl req0 = getRequest();
+        ModifyRequestImpl req1 = getRequest();
+        assertTrue( req0.hashCode() == req1.hashCode() );
+    }
+
+
+    /**
      * Test for inequality when only the IDs are different.
      */
     @Test
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ReferralImplTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ReferralImplTest.java
index 2452887..3e23700 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/ReferralImplTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/ReferralImplTest.java
@@ -92,6 +92,57 @@
 
 
     /**
+     * Tests to make sure to get equal hashCode for the same exact object.
+     */
+    @Test
+    public void testHashCodeSameObject()
+    {
+        ReferralImpl refs = new ReferralImpl();
+        assertTrue( refs.hashCode() == refs.hashCode() );
+    }
+
+
+    /**
+     * Tests to make sure to get equal hashCode for two objects that are the
+     * same exact copy of one another.
+     */
+    @Test
+    public void testHashCodeExactCopy()
+    {
+        ReferralImpl refs0 = new ReferralImpl();
+        refs0.addLdapUrl( "ldap://blah0" );
+        refs0.addLdapUrl( "ldap://blah1" );
+        refs0.addLdapUrl( "ldap://blah2" );
+        ReferralImpl refs1 = new ReferralImpl();
+        refs1.addLdapUrl( "ldap://blah0" );
+        refs1.addLdapUrl( "ldap://blah1" );
+        refs1.addLdapUrl( "ldap://blah2" );
+        assertTrue( refs0.hashCode() == refs1.hashCode() );
+    }
+
+
+    /**
+     * Tests to make sure to get equal hashCode for two objects that are the
+     * same exact copy of one another but there are redundant entries.
+     */
+    @Test
+    public void testHashCodeExactCopyWithRedundancy()
+    {
+        ReferralImpl refs0 = new ReferralImpl();
+        refs0.addLdapUrl( "ldap://blah0" );
+        refs0.addLdapUrl( "ldap://blah1" );
+        refs0.addLdapUrl( "ldap://blah2" );
+        refs0.addLdapUrl( "ldap://blah2" );
+        ReferralImpl refs1 = new ReferralImpl();
+        refs1.addLdapUrl( "ldap://blah0" );
+        refs1.addLdapUrl( "ldap://blah1" );
+        refs1.addLdapUrl( "ldap://blah2" );
+        refs1.addLdapUrl( "ldap://blah2" );
+        assertTrue( refs0.hashCode() == refs1.hashCode() );
+    }
+
+
+    /**
      * Tests to make sure the equals method works for two objects that are the
      * not exact copies of one another but have the same number of URLs.
      */
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseDoneImplTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseDoneImplTest.java
index c51bfad..3b3eb88 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseDoneImplTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseDoneImplTest.java
@@ -188,6 +188,29 @@
 
 
     /**
+     * Tests for equal hashCode using the same object.
+     */
+    @Test
+    public void testHashCodeSameObj()
+    {
+        SearchResponseDoneImpl resp = createStub();
+        assertTrue( resp.hashCode() == resp.hashCode() );
+    }
+
+
+    /**
+     * Tests for equal hashCode using an exact copy.
+     */
+    @Test
+    public void testHashCodeExactCopy()
+    {
+        SearchResponseDoneImpl resp0 = createStub();
+        SearchResponseDoneImpl resp1 = createStub();
+        assertTrue( resp0.hashCode() == resp1.hashCode() );
+    }
+
+
+    /**
      * Tests inequality when messageIds are different.
      */
     @Test
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseEntryImplTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseEntryImplTest.java
index e90800e..0ba505e 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseEntryImplTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseEntryImplTest.java
@@ -73,7 +73,7 @@
 
 
     /**
-     * Tests for equality when the same object referrence is used.
+     * Tests for equality when the same object reference is used.
      */
     @Test
     public void testEqualsSameObject()
@@ -103,6 +103,35 @@
 
 
     /**
+     * Tests for equal hashCode when the same object reference is used.
+     */
+    @Test
+    public void testHashCodeSameObject()
+    {
+        SearchResponseEntryImpl resp = new SearchResponseEntryImpl( 5 );
+        assertTrue( resp.hashCode() == resp.hashCode() );
+    }
+
+
+    /**
+     * Tests for equal hashCode when an exact copy is compared.
+     */
+    @Test
+    public void testHashCodeExactCopy() throws LdapException
+    {
+        SearchResponseEntryImpl resp0 = new SearchResponseEntryImpl( 5 );
+        resp0.setEntry( getEntry() );
+        resp0.setObjectName( new DN( "dc=example,dc=com" ) );
+
+        SearchResponseEntryImpl resp1 = new SearchResponseEntryImpl( 5 );
+        resp1.setEntry( getEntry() );
+        resp1.setObjectName( new DN( "dc=example,dc=com" ) );
+
+        assertTrue( resp0.hashCode() == resp1.hashCode() );
+    }
+
+
+    /**
      * Tests for inequality when the objectName dn is not the same.
      */
     @Test
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseReferenceImplTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseReferenceImplTest.java
index c8a2984..4efd01b 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseReferenceImplTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/message/SearchResponseReferenceImplTest.java
@@ -63,7 +63,7 @@
 
 
     /**
-     * Tests for equality when the same object referrence is used.
+     * Tests for equality when the same object reference is used.
      */
     @Test
     public void testEqualsSameObject()
@@ -169,6 +169,33 @@
 
 
     /**
+     * Tests for equal hashCode when the same object reference is used.
+     */
+    @Test
+    public void testHashCodeSameObject()
+    {
+        SearchResponseReferenceImpl resp = new SearchResponseReferenceImpl( 5 );
+        getReferral( resp );
+        assertTrue( resp.hashCode() == resp.hashCode() );
+    }
+
+
+    /**
+     * Tests for equal hashCode when an exact copy is compared.
+     */
+    @Test
+    public void testHashCodeExactCopy()
+    {
+        SearchResponseReferenceImpl resp0 = new SearchResponseReferenceImpl( 5 );
+        getReferral( resp0 );
+        SearchResponseReferenceImpl resp1 = new SearchResponseReferenceImpl( 5 );
+        getReferral( resp1 );
+
+        assertTrue( resp0.hashCode() == resp1.hashCode() );
+    }
+
+
+    /**
      * Tests for inequality when the urls are not the same.
      */
     @Test
diff --git a/ldap/src/test/java/org/apache/directory/shared/ldap/util/StringToolsTest.java b/ldap/src/test/java/org/apache/directory/shared/ldap/util/StringToolsTest.java
index 162df90..e3199f9 100644
--- a/ldap/src/test/java/org/apache/directory/shared/ldap/util/StringToolsTest.java
+++ b/ldap/src/test/java/org/apache/directory/shared/ldap/util/StringToolsTest.java
@@ -47,29 +47,6 @@
 public class StringToolsTest
 {
     @Test
-    public void testDecodeEscapedHex() throws Exception
-    {
-        assertEquals( "Ferry", StringTools.decodeEscapedHex( "\\46\\65\\72\\72\\79" ) );
-        assertEquals( "Ferry", StringTools.decodeEscapedHex( "Fe\\72\\72\\79" ) );
-        assertEquals( "Ferry", StringTools.decodeEscapedHex( "Fe\\72\\72y" ) );
-        assertEquals( "Ferry", StringTools.decodeEscapedHex( "Fe\\72ry" ) );
-
-        assertEquals( "<DC", StringTools.decodeEscapedHex( "\\<DC" ) );
-        assertEquals( ">DC", StringTools.decodeEscapedHex( "\\>DC" ) );
-        assertEquals( "\"DC", StringTools.decodeEscapedHex( "\\\"DC" ) );
-        assertEquals( "+DC", StringTools.decodeEscapedHex( "\\+DC" ) );
-        assertEquals( ",DC", StringTools.decodeEscapedHex( "\\,DC" ) );
-        assertEquals( ";DC", StringTools.decodeEscapedHex( "\\;DC" ) );
-        assertEquals( "=DC", StringTools.decodeEscapedHex( "\\=DC" ) );
-        assertEquals( " DC", StringTools.decodeEscapedHex( "\\ DC" ) );
-        assertEquals( "#DC", StringTools.decodeEscapedHex( "\\#DC" ) );
-
-        // test a corner case: ESC ESC HEX HEX
-        assertEquals( "\\DC", StringTools.decodeEscapedHex( "\\5CDC" ) );
-        assertEquals( "\\DC", StringTools.decodeEscapedHex( "\\\\DC" ) );
-    }
-    
-    @Test
     public void testDecodeHexString() throws Exception
     {
         // weird stuff - corner cases
