[maven-release-plugin]  copy for tag 2.0.0-M7

git-svn-id: https://svn.apache.org/repos/asf/directory/apacheds/tags/2.0.0-M7@1334731 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/pom.xml b/core/pom.xml
index 6193192..d22ecd0 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -224,4 +224,4 @@
       </resource>
     </resources>
   </build>
-</project>
\ No newline at end of file
+</project>
diff --git a/ldap-client-test/src/test/resources/log4j.properties b/ldap-client-test/src/test/resources/log4j.properties
index 6692ee2..f2cc7f8 100644
--- a/ldap-client-test/src/test/resources/log4j.properties
+++ b/ldap-client-test/src/test/resources/log4j.properties
@@ -14,14 +14,29 @@
 #    See the License for the specific language governing permissions and
 #    limitations under the License.
 #############################################################################
-log4j.rootCategory=OFF, stdout
+#log4j.rootCategory=OFF, stdout
 
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %p [%c] - %m%n
+#log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+#log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+#log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %p [%c] - %m%n
 
-#log4j.logger.org.apache.directory.shared.client.api=DEBUG
-log4j.logger.org.apache.directory.shared.asn1.ber=FATAL
-log4j.logger.org.apache.directory.ldap.client.api=FATAL
-log4j.logger.org.apache.directory.ldap.client.api.protocol.LdapProtocolDecoder=FATAL
-log4j.logger.org.apache.directory.ldap.client.api.LdapConnection=FATAL
+log4j.rootCategory=DEBUG, rollingFile
+
+log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
+log4j.appender.rollingFile.File=/tmp/cursor-ldap-api.log
+log4j.appender.rollingFile.MaxFileSize=1MB
+log4j.appender.rollingFile.MaxBackupIndex=5
+log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
+log4j.appender.rollingFile.layout.ConversionPattern=%m%n
+
+log4j.logger.org=FATAL
+log4j.logger.JdbmTable=FATAL
+log4j.logger.JdbmIndex=FATAL
+log4j.logger.BaseRecordManager=FATAL
+log4j.logger.LOG_CHANGES=FATAL
+log4j.logger.net=FATAL
+log4j.logger.aci-logger=FATAL
+log4j.logger.DupsCursor=FATAL
+log4j.logger.PROVIDER_LOG=FATAL
+log4j.logger.CONSUMER_LOG=FATAL
+log4j.logger.CURSOR=DEBUG
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/add/AddAliasIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/add/AddAliasIT.java
index a42d158..04b33ff 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/add/AddAliasIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/add/AddAliasIT.java
@@ -26,6 +26,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -35,6 +36,7 @@
 import org.apache.directory.shared.ldap.model.cursor.EntryCursor;
 import org.apache.directory.shared.ldap.model.entry.DefaultEntry;
 import org.apache.directory.shared.ldap.model.message.SearchScope;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -52,6 +54,8 @@
     { @CreateTransport(protocol = "LDAP") })
 public class AddAliasIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private LdapConnection conn;
 
 
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/add/AddingEntriesWithSpecialCharactersInRDNIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/add/AddingEntriesWithSpecialCharactersInRDNIT.java
index d419c15..a8ffdba 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/add/AddingEntriesWithSpecialCharactersInRDNIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/add/AddingEntriesWithSpecialCharactersInRDNIT.java
@@ -25,6 +25,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -38,6 +39,7 @@
 import org.apache.directory.shared.ldap.model.exception.LdapException;
 import org.apache.directory.shared.ldap.model.message.SearchScope;
 import org.apache.directory.shared.ldap.model.name.Dn;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import static org.apache.directory.server.integ.ServerIntegrationUtils.getAdminConnection;
@@ -54,6 +56,8 @@
     { @CreateTransport(protocol = "LDAP") })
 public class AddingEntriesWithSpecialCharactersInRDNIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private Entry getPersonEntry( String sn, String cn ) throws LdapException
     {
         Entry entry = new DefaultEntry();
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/bind/DelegatedAuthIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/bind/DelegatedAuthIT.java
index 10e09b8..510990f 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/bind/DelegatedAuthIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/bind/DelegatedAuthIT.java
@@ -24,6 +24,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.LdapNetworkConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
@@ -38,6 +39,7 @@
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.apache.directory.shared.ldap.model.exception.LdapAuthenticationException;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -67,6 +69,8 @@
     })
 public class DelegatedAuthIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
 
     /**
      * Test with bindDn which is not even found under any namingContext of the
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/compare/CompareIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/compare/CompareIT.java
index 5d1b1a5..b1d7975 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/compare/CompareIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/compare/CompareIT.java
@@ -34,6 +34,7 @@
 import javax.naming.directory.SearchResult;
 import javax.naming.ldap.LdapContext;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.LdapNetworkConnection;
 import org.apache.directory.ldap.client.api.exception.InvalidConnectionException;
@@ -51,6 +52,7 @@
 import org.apache.directory.shared.ldap.model.message.controls.ManageDsaIT;
 import org.apache.directory.shared.ldap.model.message.controls.ManageDsaITImpl;
 import org.apache.directory.shared.ldap.model.name.Dn;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
@@ -93,11 +95,14 @@
         "ref: ldap://bar:10389/uid=akarasulu,ou=users,ou=system" })
 public class CompareIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+
     private static final Logger LOG = LoggerFactory.getLogger( CompareIT.class );
 
 
     /**
-     * Tests normal compare operation on normal non-referral entries without 
+     * Tests normal compare operation on normal non-referral entries without
      * the ManageDsaIT control.
      */
     @Test
@@ -119,7 +124,7 @@
 
 
     /**
-     * Tests normal compare operation on normal non-referral entries without 
+     * Tests normal compare operation on normal non-referral entries without
      * the ManageDsaIT control using an attribute that does not exist in the
      * entry.
      */
@@ -174,7 +179,7 @@
 
 
     /**
-     * Tests compare operation on normal and referral entries without the 
+     * Tests compare operation on normal and referral entries without the
      * ManageDsaIT control. Referrals are sent back to the client with a
      * non-success result code.
      */
@@ -216,8 +221,8 @@
 
 
     /**
-     * Tests compare operation on normal and referral entries without the 
-     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals 
+     * Tests compare operation on normal and referral entries without the
+     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals
      * are sent back to the client with a non-success result code.
      */
     @Test
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/compare/MatchingRuleCompareIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/compare/MatchingRuleCompareIT.java
index c036ba8..e04259e 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/compare/MatchingRuleCompareIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/compare/MatchingRuleCompareIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.compare;
 
@@ -27,6 +27,7 @@
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
@@ -34,6 +35,7 @@
 import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.apache.directory.server.integ.ServerIntegrationUtils;
 import org.apache.directory.shared.util.Strings;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -70,90 +72,92 @@
 })
 public class MatchingRuleCompareIT extends AbstractLdapTestUnit
 {
-public static final String PERSON_CN = "Tori Amos";
-public static final String PERSON_SN = "Amos";
-public static final String PERSON_RDN = "cn=" + PERSON_CN;
-public static final String PERSON_TELEPHONE = "1234567890";
-public static final String PERSON_PWD = "Secret1!";
-
-public static final String GROUP_CN = "Artists";
-public static final String GROUP_RDN = "cn=" + GROUP_CN;
-
-
-/**
- * Compare with caseIgnoreMatch matching rule.
- * 
- * @throws org.apache.directory.shared.ldap.model.exception.LdapException
- */
-@Test
-public void testCaseIgnoreMatch() throws Exception
-{
-    DirContext ctx = ( DirContext ) ServerIntegrationUtils.getWiredContext( getLdapServer() ).lookup( "ou=system" );
-
-    // Setting up search controls for compare op
-    SearchControls ctls = new SearchControls();
-    ctls.setReturningAttributes( new String[]
-        {} ); // no attributes
-    ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
-
-    String[] values =
-        { PERSON_SN, PERSON_SN.toUpperCase(), Strings.toLowerCase( PERSON_SN ), PERSON_SN + "X" };
-    boolean[] expected =
-        { true, true, true, false };
-
-    for ( int i = 0; i < values.length; i++ )
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    public static final String PERSON_CN = "Tori Amos";
+    public static final String PERSON_SN = "Amos";
+    public static final String PERSON_RDN = "cn=" + PERSON_CN;
+    public static final String PERSON_TELEPHONE = "1234567890";
+    public static final String PERSON_PWD = "Secret1!";
+    
+    public static final String GROUP_CN = "Artists";
+    public static final String GROUP_RDN = "cn=" + GROUP_CN;
+    
+    
+    /**
+     * Compare with caseIgnoreMatch matching rule.
+     * 
+     * @throws org.apache.directory.shared.ldap.model.exception.LdapException
+     */
+    @Test
+    public void testCaseIgnoreMatch() throws Exception
     {
-        String value = values[i];
-
-        NamingEnumeration<SearchResult> enumeration = ctx.search( PERSON_RDN, "sn={0}", new String[]
-            { value }, ctls );
-        boolean result = enumeration.hasMore();
-
-        assertEquals( "compare sn value '" + PERSON_SN + "' with '" + value + "'", expected[i], result );
-
-        enumeration.close();
+        DirContext ctx = ( DirContext ) ServerIntegrationUtils.getWiredContext( getLdapServer() ).lookup( "ou=system" );
+    
+        // Setting up search controls for compare op
+        SearchControls ctls = new SearchControls();
+        ctls.setReturningAttributes( new String[]
+            {} ); // no attributes
+        ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+    
+        String[] values =
+            { PERSON_SN, PERSON_SN.toUpperCase(), Strings.toLowerCase( PERSON_SN ), PERSON_SN + "X" };
+        boolean[] expected =
+            { true, true, true, false };
+    
+        for ( int i = 0; i < values.length; i++ )
+        {
+            String value = values[i];
+    
+            NamingEnumeration<SearchResult> enumeration = ctx.search( PERSON_RDN, "sn={0}", new String[]
+                { value }, ctls );
+            boolean result = enumeration.hasMore();
+    
+            assertEquals( "compare sn value '" + PERSON_SN + "' with '" + value + "'", expected[i], result );
+    
+            enumeration.close();
+        }
     }
-}
-
-
-//
-
-/**
- * Compare with distinguishedNameMatch matching rule.
- * 
- * @throws org.apache.directory.shared.ldap.model.exception.LdapException
- */
-@Test
-public void testDistinguishedNameMatch() throws Exception
-{
-    DirContext ctx = ( DirContext ) ServerIntegrationUtils.getWiredContext( getLdapServer() ).lookup( "ou=system" );
-
-    // determine member Dn of person
-    DirContext member = ( DirContext ) ctx.lookup( PERSON_RDN );
-    String memberDN = member.getNameInNamespace();
-
-    // Setting up search controls for compare op
-    SearchControls ctls = new SearchControls();
-    ctls.setReturningAttributes( new String[]
-        {} ); // no attributes
-    ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
-
-    String[] values =
-        { "", memberDN, "cn=nobody", memberDN, PERSON_RDN + " , " + ctx.getNameInNamespace() };
-    boolean[] expected =
-        { false, true, false, true, true };
-
-    for ( int i = 0; i < values.length; i++ )
+    
+    
+    //
+    
+    /**
+     * Compare with distinguishedNameMatch matching rule.
+     * 
+     * @throws org.apache.directory.shared.ldap.model.exception.LdapException
+     */
+    @Test
+    public void testDistinguishedNameMatch() throws Exception
     {
-        String value = values[i];
-
-        NamingEnumeration<SearchResult> enumeration = ctx.search( GROUP_RDN, "member={0}", new Object[]
-            { value }, ctls );
-        boolean result = enumeration.hasMore();
-
-        assertEquals( "compare '" + memberDN + "' with '" + value + "'", expected[i], result );
-
-        enumeration.close();
+        DirContext ctx = ( DirContext ) ServerIntegrationUtils.getWiredContext( getLdapServer() ).lookup( "ou=system" );
+    
+        // determine member Dn of person
+        DirContext member = ( DirContext ) ctx.lookup( PERSON_RDN );
+        String memberDN = member.getNameInNamespace();
+    
+        // Setting up search controls for compare op
+        SearchControls ctls = new SearchControls();
+        ctls.setReturningAttributes( new String[]
+            {} ); // no attributes
+        ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+    
+        String[] values =
+            { "", memberDN, "cn=nobody", memberDN, PERSON_RDN + " , " + ctx.getNameInNamespace() };
+        boolean[] expected =
+            { false, true, false, true, true };
+    
+        for ( int i = 0; i < values.length; i++ )
+        {
+            String value = values[i];
+    
+            NamingEnumeration<SearchResult> enumeration = ctx.search( GROUP_RDN, "member={0}", new Object[]
+                { value }, ctls );
+            boolean result = enumeration.hasMore();
+    
+            assertEquals( "compare '" + memberDN + "' with '" + value + "'", expected[i], result );
+    
+            enumeration.close();
+        }
     }
 }
-}
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/delete/DeleteAliasIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/delete/DeleteAliasIT.java
index 56cd6b2..49b016d 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/delete/DeleteAliasIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/delete/DeleteAliasIT.java
@@ -24,6 +24,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -32,6 +33,7 @@
 import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.apache.directory.shared.ldap.model.entry.DefaultEntry;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -49,6 +51,8 @@
     { @CreateTransport(protocol = "LDAP") })
 public class DeleteAliasIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private LdapConnection conn;
 
 
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/delete/DeleteIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/delete/DeleteIT.java
index c5df840..d11a510 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/delete/DeleteIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/delete/DeleteIT.java
@@ -32,6 +32,7 @@
 import javax.naming.ReferralException;
 import javax.naming.ldap.LdapContext;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -48,6 +49,7 @@
 import org.apache.directory.shared.ldap.model.message.controls.ManageDsaIT;
 import org.apache.directory.shared.ldap.model.message.controls.ManageDsaITImpl;
 import org.apache.directory.shared.ldap.model.name.Dn;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
@@ -92,6 +94,8 @@
         "ref: ldap://bar:10389/uid=akarasulu,ou=users,ou=system" })
 public class DeleteIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private static final Logger LOG = LoggerFactory.getLogger( DeleteIT.class );
 
 
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/extended/ExtendedIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/extended/ExtendedIT.java
index 4fd1e05..ac42af6 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/extended/ExtendedIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/extended/ExtendedIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.extended;
 
@@ -29,10 +29,12 @@
 import javax.naming.ldap.ExtendedResponse;
 import javax.naming.ldap.LdapContext;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -50,13 +52,16 @@
     })
 public class ExtendedIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+
     /**
      * Calls an extended exception, which does not exist. Expected behaviour is
      * a CommunicationException.
      * Check the behaviour of the server for an unknown extended operation. Created
      * to demonstrate DIREVE-256 ("Extended operation causes client to hang.").
      * 
-     * @throws NamingException 
+     * @throws NamingException
      */
     @Test
     public void testUnknownExtendedOperation() throws Exception
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java
index a5093bd..bac8f11 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.extended;
 
@@ -32,6 +32,7 @@
 import javax.naming.ldap.InitialLdapContext;
 import javax.naming.ldap.LdapContext;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.annotations.SaslMechanism;
@@ -48,6 +49,7 @@
 import org.apache.directory.shared.ldap.model.schema.normalizers.OidNormalizer;
 import org.apache.directory.shared.ldap.sp.JavaStoredProcUtils;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.Ignore;
@@ -68,6 +70,8 @@
     { StoredProcedureExtendedOperationHandler.class })
 public class StoredProcedureIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private LdapContext ctx;
     private LdapContext spCtx;
     private Map<String, OidNormalizer> oids;
@@ -132,7 +136,7 @@
             "ou: People\n" +
             "objectclass: organizationalUnit\n" +
             "objectclass: top\n" +
-            "\n" + 
+            "\n" +
             "dn: cn=John,ou=People,ou=system\n" +
             "objectclass: person\n" +
             "objectclass: top\n" +
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/AddIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/AddIT.java
index 8484d36..ebdcaaf 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/AddIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/AddIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.ldapsdk;
 
@@ -62,6 +62,7 @@
 import netscape.ldap.LDAPResponseListener;
 import netscape.ldap.LDAPSearchConstraints;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.LdapNetworkConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
@@ -97,6 +98,7 @@
 import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.model.name.Dn;
 import org.apache.directory.shared.util.Strings;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
@@ -180,6 +182,8 @@
         "ref: ldap://bar:10389/uid=akarasulu,ou=users,ou=system" })
 public class AddIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private static final Logger LOG = LoggerFactory.getLogger( AddIT.class );
     private static final String RDN = "cn=The Person";
 
@@ -518,7 +522,7 @@
         String rdnAlias = "ou=bestFruit";
         containerCtx.createSubcontext( rdnAlias, alias );
 
-        // search one level scope for alias 
+        // search one level scope for alias
         SearchControls controls = new SearchControls();
         controls.setDerefLinkFlag( true );
         controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
@@ -822,7 +826,7 @@
 
 
     /**
-     * Tests add operation on normal and referral entries without the 
+     * Tests add operation on normal and referral entries without the
      * ManageDsaIT control. Referrals are sent back to the client with a
      * non-success result code.
      */
@@ -858,8 +862,8 @@
 
 
     /**
-     * Tests add operation on normal and referral entries without the 
-     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals 
+     * Tests add operation on normal and referral entries without the
+     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals
      * are sent back to the client with a non-success result code.
      */
     @Test
@@ -1089,9 +1093,9 @@
 
     /**
      * Test that if we inject a PDU above the max allowed size,
-     * the connection is closed. 
+     * the connection is closed.
      * 
-     * @throws NamingException 
+     * @throws NamingException
      */
     @Test
     public void testAddPDUExceedingMaxSizeJNDI() throws Exception
@@ -1158,9 +1162,9 @@
 
     /**
      * Test that if we inject a PDU above the max allowed size,
-     * the connection is closed. 
+     * the connection is closed.
      * 
-     * @throws NamingException 
+     * @throws NamingException
      */
     @Test
     public void testAddPDUExceedingMaxSizeLdapApi() throws Exception
@@ -1239,7 +1243,7 @@
         binary.put( "userPassword", "test" );
         /*
          * Note that the Rdn attribute is different to the userPassword specified
-         * in the entry. This creates a second cn attribute "userPassword:#414243". 
+         * in the entry. This creates a second cn attribute "userPassword:#414243".
          * This is a JNDI hack:
          * If no other userPassword is available in the entry, JNDI adds the Rdn
          * attribute to the entry before sending the request to the server.
@@ -1347,7 +1351,7 @@
      *        |--cn=alias  <--alias, pointing to the real entry
      * </pre>
      * 
-     * @throws NamingException 
+     * @throws NamingException
      */
     @Test
     @CreateDS(
@@ -1392,7 +1396,7 @@
     /**
      * Adding an entry with a non existing attribute type.
      * 
-     * @throws Exception 
+     * @throws Exception
      */
     @Test
     public void testAddEntryNonExistingAT() throws Exception
@@ -1428,7 +1432,7 @@
     /**
      * Adding an entry with a non existing attribute type.
      * 
-     * @throws Exception 
+     * @throws Exception
      */
     @Test(expected = LdapOperationException.class)
     public void testAddEntryNonExistingOC() throws Exception
@@ -1450,7 +1454,7 @@
     /**
      * Adding an entry with a 100K attribute's value.
      * 
-     * @throws Exception 
+     * @throws Exception
      */
     @Test(expected = LdapException.class)
     public void testAddEntry100KData() throws Exception
@@ -1478,7 +1482,7 @@
 
         connection.add( personEntry );
 
-        // Check that the entry has been stored 
+        // Check that the entry has been stored
         Entry entry = connection.lookup( dn, "description", "cn", "sn" );
 
         String description = entry.get( "description" ).getString();
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/CompareIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/CompareIT.java
index ec9ab5f..b79a970 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/CompareIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/CompareIT.java
@@ -42,6 +42,7 @@
 import netscape.ldap.LDAPResponse;
 import netscape.ldap.LDAPResponseListener;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -49,6 +50,7 @@
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
@@ -91,11 +93,13 @@
         "ref: ldap://bar:10389/uid=akarasulu,ou=users,ou=system" })
 public class CompareIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private static final Logger LOG = LoggerFactory.getLogger( CompareIT.class );
 
 
     /**
-     * Tests normal compare operation on normal non-referral entries without 
+     * Tests normal compare operation on normal non-referral entries without
      * the ManageDsaIT control.
      */
     @Test
@@ -117,7 +121,7 @@
 
 
     /**
-     * Tests normal compare operation on normal non-referral entries without 
+     * Tests normal compare operation on normal non-referral entries without
      * the ManageDsaIT control using an attribute that does not exist in the
      * entry.
      */
@@ -172,7 +176,7 @@
 
 
     /**
-     * Tests compare operation on normal and referral entries without the 
+     * Tests compare operation on normal and referral entries without the
      * ManageDsaIT control. Referrals are sent back to the client with a
      * non-success result code.
      */
@@ -206,8 +210,8 @@
 
 
     /**
-     * Tests compare operation on normal and referral entries without the 
-     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals 
+     * Tests compare operation on normal and referral entries without the
+     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals
      * are sent back to the client with a non-success result code.
      */
     @Test
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/DeleteIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/DeleteIT.java
index 442fd97..1191c86 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/DeleteIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/DeleteIT.java
@@ -39,6 +39,7 @@
 import netscape.ldap.LDAPResponseListener;
 import netscape.ldap.LDAPSearchConstraints;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -48,6 +49,7 @@
 import org.apache.directory.shared.ldap.model.exception.LdapContextNotEmptyException;
 import org.apache.directory.shared.ldap.model.exception.LdapNoSuchObjectException;
 import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
@@ -92,11 +94,13 @@
         "ref: ldap://bar:10389/uid=akarasulu,ou=users,ou=system" })
 public class DeleteIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private static final Logger LOG = LoggerFactory.getLogger( DeleteIT.class );
 
 
     /**
-     * Tests normal delete operation on normal non-referral entries without 
+     * Tests normal delete operation on normal non-referral entries without
      * the ManageDsaIT control.
      */
     @Test
@@ -121,7 +125,7 @@
 
 
     /**
-     * Tests normal delete operation on normal non-referral entries without 
+     * Tests normal delete operation on normal non-referral entries without
      * the ManageDsaIT control.
      */
     @Test
@@ -149,7 +153,7 @@
 
 
     /**
-     * Tests normal delete operation on non-existent entries without 
+     * Tests normal delete operation on non-existent entries without
      * the ManageDsaIT control.
      */
     @Test
@@ -203,7 +207,7 @@
 
 
     /**
-     * Tests delete operation on normal and referral entries without the 
+     * Tests delete operation on normal and referral entries without the
      * ManageDsaIT control. Referrals are sent back to the client with a
      * non-success result code.
      */
@@ -232,8 +236,8 @@
 
 
     /**
-     * Tests delete operation on normal and referral entries without the 
-     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals 
+     * Tests delete operation on normal and referral entries without the
+     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals
      * are sent back to the client with a non-success result code.
      */
     @Test
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/IllegalModificationIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/IllegalModificationIT.java
index 9c1bf67..29f01b8 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/IllegalModificationIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/IllegalModificationIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.ldapsdk;
 
@@ -30,6 +30,7 @@
 import netscape.ldap.LDAPException;
 import netscape.ldap.LDAPModification;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -46,11 +47,11 @@
 import org.junit.runner.RunWith;
 
 
-/** 
- * A test taken from DIRSERVER-630: If one tries to add an attribute to an 
- * entry, and does not provide a value, it is assumed that the server does 
- * not modify the entry. We have a situation here using Sun ONE Directory 
- * SDK for Java, where adding a description attribute without value to a 
+/**
+ * A test taken from DIRSERVER-630: If one tries to add an attribute to an
+ * entry, and does not provide a value, it is assumed that the server does
+ * not modify the entry. We have a situation here using Sun ONE Directory
+ * SDK for Java, where adding a description attribute without value to a
  * person entry like this,
  * <code>
  * dn: cn=Kate Bush,dc=example,dc=com
@@ -58,11 +59,11 @@
  * objectclass: top
  * sn: Bush
  * cn: Kate Bush
- * </code> 
- * does not fail (modify call does not result in an exception). Instead, a 
- * description attribute is created within the entry. At least the new 
- * attribute is readable with Netscape SDK (it is not visible to most UIs, 
- * because it is invalid ...). 
+ * </code>
+ * does not fail (modify call does not result in an exception). Instead, a
+ * description attribute is created within the entry. At least the new
+ * attribute is readable with Netscape SDK (it is not visible to most UIs,
+ * because it is invalid ...).
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
@@ -80,6 +81,7 @@
         "sn: Bush" })
 public class IllegalModificationIT extends AbstractLdapTestUnit
 {
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private static final String DN = "cn=Kate Bush,ou=system";
 
 
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/ModifyDnReferralIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/ModifyDnReferralIT.java
index 8ab7a86..7039d99 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/ModifyDnReferralIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/ModifyDnReferralIT.java
@@ -38,12 +38,14 @@
 import netscape.ldap.LDAPResponseListener;
 import netscape.ldap.LDAPSearchConstraints;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
@@ -101,194 +103,196 @@
 })
 public class ModifyDnReferralIT extends AbstractLdapTestUnit
 {
-private static final Logger LOG = LoggerFactory.getLogger( ModifyDnReferralIT.class );
-
-
-/**
- * Tests ModifyDN operation on referral entry with the ManageDsaIT control.
- */
-@Test
-public void testOnReferralWithManageDsaITControl() throws Exception
-{
-    LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
-    LDAPConstraints constraints = new LDAPSearchConstraints();
-    constraints.setClientControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
-    constraints.setServerControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
-    conn.setConstraints( constraints );
-
-    // ModifyDN success
-    conn.rename( "uid=akarasuluref,ou=users,ou=system", "uid=ref", true, constraints );
-    LDAPEntry entry = conn.read( "uid=ref,ou=users,ou=system", ( LDAPSearchConstraints ) constraints );
-    assertNotNull( entry );
-    assertEquals( "uid=ref,ou=users,ou=system", entry.getDN() );
-
-    conn.disconnect();
-}
-
-
-/**
- * Tests ModifyDN operation with newSuperior on referral entry with the 
- * ManageDsaIT control.
- */
-@Test
-public void testNewSuperiorOnReferralWithManageDsaITControl() throws Exception
-{
-    LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
-    LDAPConstraints constraints = new LDAPSearchConstraints();
-    constraints.setClientControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
-    constraints.setServerControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
-    conn.setConstraints( constraints );
-
-    // ModifyDN success
-    try
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    private static final Logger LOG = LoggerFactory.getLogger( ModifyDnReferralIT.class );
+    
+    
+    /**
+     * Tests ModifyDN operation on referral entry with the ManageDsaIT control.
+     */
+    @Test
+    public void testOnReferralWithManageDsaITControl() throws Exception
     {
-        conn.rename( "uid=elecharny,ou=users,ou=system", "uid=newuser",
-            "uid=akarasuluref,ou=users,ou=system", true, constraints );
+        LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
+        LDAPConstraints constraints = new LDAPSearchConstraints();
+        constraints.setClientControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
+        constraints.setServerControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
+        conn.setConstraints( constraints );
+    
+        // ModifyDN success
+        conn.rename( "uid=akarasuluref,ou=users,ou=system", "uid=ref", true, constraints );
+        LDAPEntry entry = conn.read( "uid=ref,ou=users,ou=system", ( LDAPSearchConstraints ) constraints );
+        assertNotNull( entry );
+        assertEquals( "uid=ref,ou=users,ou=system", entry.getDN() );
+    
+        conn.disconnect();
     }
-    catch ( LDAPException le )
+    
+    
+    /**
+     * Tests ModifyDN operation with newSuperior on referral entry with the
+     * ManageDsaIT control.
+     */
+    @Test
+    public void testNewSuperiorOnReferralWithManageDsaITControl() throws Exception
     {
-        assertEquals( LDAPException.AFFECTS_MULTIPLE_DSAS, le.getLDAPResultCode() );
+        LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
+        LDAPConstraints constraints = new LDAPSearchConstraints();
+        constraints.setClientControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
+        constraints.setServerControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
+        conn.setConstraints( constraints );
+    
+        // ModifyDN success
+        try
+        {
+            conn.rename( "uid=elecharny,ou=users,ou=system", "uid=newuser",
+                "uid=akarasuluref,ou=users,ou=system", true, constraints );
+        }
+        catch ( LDAPException le )
+        {
+            assertEquals( LDAPException.AFFECTS_MULTIPLE_DSAS, le.getLDAPResultCode() );
+        }
+    
+        conn.disconnect();
     }
-
-    conn.disconnect();
-}
-
-
-/**
- * Tests ModifyDN operation on normal and referral entries without the 
- * ManageDsaIT control. Referrals are sent back to the client with a
- * non-success result code.
- */
-@Test
-public void testOnReferral() throws Exception
-{
-    LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
-    LDAPConstraints constraints = new LDAPConstraints();
-    constraints.setReferrals( false );
-    conn.setConstraints( constraints );
-
-    // referrals failure
-    LDAPResponseListener listener = null;
-    LDAPResponse response = null;
-
-    listener = conn.rename( "uid=akarasuluref,ou=users,ou=system", "uid=ref", true, null, constraints );
-    response = listener.getResponse();
-    assertEquals( ResultCodeEnum.REFERRAL.getValue(), response.getResultCode() );
-
-    assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[0] );
-    assertEquals( "ldap://foo:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[1] );
-    assertEquals( "ldap://bar:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[2] );
-
-    conn.disconnect();
-}
-
-
-/**
- * Tests ModifyDN operation on normal and referral entries without the 
- * ManageDsaIT control. Referrals are sent back to the client with a
- * non-success result code.
- */
-@Test
-public void testNewSupierorOnReferral() throws Exception
-{
-    LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
-    LDAPConstraints constraints = new LDAPConstraints();
-    constraints.setReferrals( false );
-    conn.setConstraints( constraints );
-
-    // referrals failure
-    try
+    
+    
+    /**
+     * Tests ModifyDN operation on normal and referral entries without the
+     * ManageDsaIT control. Referrals are sent back to the client with a
+     * non-success result code.
+     */
+    @Test
+    public void testOnReferral() throws Exception
     {
-        conn.rename( "uid=elecharny,ou=users,ou=system", "uid=ref",
-            "uid=akarasuluref,ou=users,ou=system", true, constraints );
+        LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
+        LDAPConstraints constraints = new LDAPConstraints();
+        constraints.setReferrals( false );
+        conn.setConstraints( constraints );
+    
+        // referrals failure
+        LDAPResponseListener listener = null;
+        LDAPResponse response = null;
+    
+        listener = conn.rename( "uid=akarasuluref,ou=users,ou=system", "uid=ref", true, null, constraints );
+        response = listener.getResponse();
+        assertEquals( ResultCodeEnum.REFERRAL.getValue(), response.getResultCode() );
+    
+        assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[0] );
+        assertEquals( "ldap://foo:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[1] );
+        assertEquals( "ldap://bar:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[2] );
+    
+        conn.disconnect();
     }
-    catch ( LDAPException e )
+    
+    
+    /**
+     * Tests ModifyDN operation on normal and referral entries without the
+     * ManageDsaIT control. Referrals are sent back to the client with a
+     * non-success result code.
+     */
+    @Test
+    public void testNewSupierorOnReferral() throws Exception
     {
-        assertEquals( LDAPException.AFFECTS_MULTIPLE_DSAS, e.getLDAPResultCode() );
+        LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
+        LDAPConstraints constraints = new LDAPConstraints();
+        constraints.setReferrals( false );
+        conn.setConstraints( constraints );
+    
+        // referrals failure
+        try
+        {
+            conn.rename( "uid=elecharny,ou=users,ou=system", "uid=ref",
+                "uid=akarasuluref,ou=users,ou=system", true, constraints );
+        }
+        catch ( LDAPException e )
+        {
+            assertEquals( LDAPException.AFFECTS_MULTIPLE_DSAS, e.getLDAPResultCode() );
+        }
+    
+        conn.disconnect();
     }
-
-    conn.disconnect();
-}
-
-
-/**
- * Tests ModifyDN operation on normal and referral entries without the 
- * ManageDsaIT control using JNDI instead of the Netscape API. Referrals 
- * are sent back to the client with a non-success result code.
- */
-@Test
-public void testThrowOnReferralWithJndi() throws Exception
-{
-    LdapContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
-
-    // ModifyDN referrals failure
-    try
+    
+    
+    /**
+     * Tests ModifyDN operation on normal and referral entries without the
+     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals
+     * are sent back to the client with a non-success result code.
+     */
+    @Test
+    public void testThrowOnReferralWithJndi() throws Exception
     {
-        ctx.rename( "uid=akarasuluref,ou=users,ou=system", "uid=ref,ou=users,ou=system" );
-        fail( "Should never get here due to ModifyDN failure on ReferralException" );
+        LdapContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
+    
+        // ModifyDN referrals failure
+        try
+        {
+            ctx.rename( "uid=akarasuluref,ou=users,ou=system", "uid=ref,ou=users,ou=system" );
+            fail( "Should never get here due to ModifyDN failure on ReferralException" );
+        }
+        catch ( ReferralException e )
+        {
+            // seems JNDI only returns the first referral URL and not all so we test for it
+            assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", e.getReferralInfo() );
+        }
+    
+        ctx.close();
     }
-    catch ( ReferralException e )
+    
+    
+    /**
+     * Tests referral handling when an ancestor is a referral.
+     */
+    @Test
+    public void testAncestorReferral() throws Exception
     {
-        // seems JNDI only returns the first referral URL and not all so we test for it
-        assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", e.getReferralInfo() );
+        LOG.debug( "" );
+    
+        LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
+        LDAPConstraints constraints = new LDAPConstraints();
+        conn.setConstraints( constraints );
+    
+        // referrals failure
+        LDAPResponseListener listener = null;
+        LDAPResponse response = null;
+    
+        listener = conn.rename( "ou=Computers,uid=akarasuluref,ou=users,ou=system", "ou=Machines", true, null, constraints );
+        response = listener.getResponse();
+        assertEquals( ResultCodeEnum.REFERRAL.getValue(), response.getResultCode() );
+    
+        assertEquals( "ldap://localhost:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[0] );
+        assertEquals( "ldap://foo:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[1] );
+        assertEquals( "ldap://bar:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[2] );
+    
+        conn.disconnect();
     }
-
-    ctx.close();
-}
-
-
-/**
- * Tests referral handling when an ancestor is a referral.
- */
-@Test
-public void testAncestorReferral() throws Exception
-{
-    LOG.debug( "" );
-
-    LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
-    LDAPConstraints constraints = new LDAPConstraints();
-    conn.setConstraints( constraints );
-
-    // referrals failure
-    LDAPResponseListener listener = null;
-    LDAPResponse response = null;
-
-    listener = conn.rename( "ou=Computers,uid=akarasuluref,ou=users,ou=system", "ou=Machines", true, null, constraints );
-    response = listener.getResponse();
-    assertEquals( ResultCodeEnum.REFERRAL.getValue(), response.getResultCode() );
-
-    assertEquals( "ldap://localhost:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[0] );
-    assertEquals( "ldap://foo:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[1] );
-    assertEquals( "ldap://bar:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[2] );
-
-    conn.disconnect();
-}
-
-
-/**
- * Tests referral handling when an ancestor is a referral.
- */
-@Test
-public void testNewSuperiorAncestorReferral() throws Exception
-{
-    LOG.debug( "" );
-
-    LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
-    LDAPConstraints constraints = new LDAPConstraints();
-    conn.setConstraints( constraints );
-
-    // referrals failure
-    try
+    
+    
+    /**
+     * Tests referral handling when an ancestor is a referral.
+     */
+    @Test
+    public void testNewSuperiorAncestorReferral() throws Exception
     {
-        conn.rename( "uid=elecharny,ou=users,ou=system", "ou=Machines",
-            "ou=Computers,uid=akarasuluref,ou=users,ou=system", true, constraints );
-        fail( "Should never get here to affectsMultipleDSA error result code" );
+        LOG.debug( "" );
+    
+        LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
+        LDAPConstraints constraints = new LDAPConstraints();
+        conn.setConstraints( constraints );
+    
+        // referrals failure
+        try
+        {
+            conn.rename( "uid=elecharny,ou=users,ou=system", "ou=Machines",
+                "ou=Computers,uid=akarasuluref,ou=users,ou=system", true, constraints );
+            fail( "Should never get here to affectsMultipleDSA error result code" );
+        }
+        catch ( LDAPException e )
+        {
+            assertEquals( LDAPException.AFFECTS_MULTIPLE_DSAS, e.getLDAPResultCode() );
+        }
+    
+        conn.disconnect();
     }
-    catch ( LDAPException e )
-    {
-        assertEquals( LDAPException.AFFECTS_MULTIPLE_DSAS, e.getLDAPResultCode() );
-    }
-
-    conn.disconnect();
-}
 }
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/ModifyReferralIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/ModifyReferralIT.java
index c8c9062..629d071 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/ModifyReferralIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/ldapsdk/ModifyReferralIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.ldapsdk;
 
@@ -40,6 +40,7 @@
 import netscape.ldap.LDAPResponse;
 import netscape.ldap.LDAPResponseListener;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
@@ -47,17 +48,18 @@
 import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.apache.directory.server.operations.compare.CompareIT;
 import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 
-/** 
- * A test taken from DIRSERVER-630: If one tries to add an attribute to an 
- * entry, and does not provide a value, it is assumed that the server does 
- * not modify the entry. We have a situation here using Sun ONE Directory 
- * SDK for Java, where adding a description attribute without value to a 
+/**
+ * A test taken from DIRSERVER-630: If one tries to add an attribute to an
+ * entry, and does not provide a value, it is assumed that the server does
+ * not modify the entry. We have a situation here using Sun ONE Directory
+ * SDK for Java, where adding a description attribute without value to a
  * person entry like this,
  * <code>
  * dn: cn=Kate Bush,dc=example,dc=com
@@ -65,11 +67,11 @@
  * objectclass: top
  * sn: Bush
  * cn: Kate Bush
- * </code> 
- * does not fail (modify call does not result in an exception). Instead, a 
- * description attribute is created within the entry. At least the new 
- * attribute is readable with Netscape SDK (it is not visible to most UIs, 
- * because it is invalid ...). 
+ * </code>
+ * does not fail (modify call does not result in an exception). Instead, a
+ * description attribute is created within the entry. At least the new
+ * attribute is readable with Netscape SDK (it is not visible to most UIs,
+ * because it is invalid ...).
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
@@ -109,117 +111,119 @@
 })
 public class ModifyReferralIT extends AbstractLdapTestUnit
 {
-private static final Logger LOG = LoggerFactory.getLogger( CompareIT.class );
-
-
-/**
- * Tests modify operation on referral entry with the ManageDsaIT control.
- */
-@Test
-public void testOnReferralWithManageDsaITControl() throws Exception
-{
-    LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
-    LDAPConstraints constraints = new LDAPConstraints();
-    constraints.setClientControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
-    constraints.setServerControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
-    conn.setConstraints( constraints );
-
-    // modify success
-    LDAPAttribute attribute = new LDAPAttribute( "description", "referral to akarasulu" );
-    LDAPModification mod = new LDAPModification( LDAPModification.ADD, attribute );
-    conn.modify( "uid=akarasuluref,ou=users,ou=system", mod, constraints );
-
-    assertTrue( conn.compare( "uid=akarasuluref,ou=users,ou=system", attribute, constraints ) );
-
-    conn.disconnect();
-}
-
-
-/**
- * Tests modify operation on referral entries without the 
- * ManageDsaIT control. Referrals are sent back to the client with a
- * non-success result code.
- */
-@Test
-public void testOnReferral() throws Exception
-{
-    LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
-    LDAPConstraints constraints = new LDAPConstraints();
-    constraints.setReferrals( false );
-    conn.setConstraints( constraints );
-
-    // referrals failure
-    // modify success
-    LDAPAttribute attribute = new LDAPAttribute( "description", "referral to akarasulu" );
-    LDAPModification mod = new LDAPModification( LDAPModification.ADD, attribute );
-    LDAPResponseListener listener = conn.modify( "uid=akarasuluref,ou=users,ou=system", mod, null, constraints );
-    LDAPResponse response = listener.getResponse();
-
-    assertEquals( ResultCodeEnum.REFERRAL.getValue(), response.getResultCode() );
-
-    assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[0] );
-    assertEquals( "ldap://foo:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[1] );
-    assertEquals( "ldap://bar:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[2] );
-
-    conn.disconnect();
-}
-
-
-/**
- * Tests modify operation on normal and referral entries without the 
- * ManageDsaIT control using JNDI instead of the Netscape API. Referrals 
- * are sent back to the client with a non-success result code.
- */
-@Test
-public void testThrowOnReferralWithJndi() throws Exception
-{
-    LdapContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
-
-    // modify failure
-    Attribute attr = new BasicAttribute( "description", "referral to akarasulu" );
-    ModificationItem mod = new ModificationItem( DirContext.ADD_ATTRIBUTE, attr );
-
-    try
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    private static final Logger LOG = LoggerFactory.getLogger( CompareIT.class );
+    
+    
+    /**
+     * Tests modify operation on referral entry with the ManageDsaIT control.
+     */
+    @Test
+    public void testOnReferralWithManageDsaITControl() throws Exception
     {
-        ctx.modifyAttributes( "uid=akarasuluref,ou=users,ou=system", new ModificationItem[]
-            { mod } );
+        LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
+        LDAPConstraints constraints = new LDAPConstraints();
+        constraints.setClientControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
+        constraints.setServerControls( new LDAPControl( LDAPControl.MANAGEDSAIT, true, new byte[0] ) );
+        conn.setConstraints( constraints );
+    
+        // modify success
+        LDAPAttribute attribute = new LDAPAttribute( "description", "referral to akarasulu" );
+        LDAPModification mod = new LDAPModification( LDAPModification.ADD, attribute );
+        conn.modify( "uid=akarasuluref,ou=users,ou=system", mod, constraints );
+    
+        assertTrue( conn.compare( "uid=akarasuluref,ou=users,ou=system", attribute, constraints ) );
+    
+        conn.disconnect();
     }
-    catch ( ReferralException e )
+    
+    
+    /**
+     * Tests modify operation on referral entries without the
+     * ManageDsaIT control. Referrals are sent back to the client with a
+     * non-success result code.
+     */
+    @Test
+    public void testOnReferral() throws Exception
     {
-        // seems JNDI only returns the first referral URL and not all so we test for it
-        assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", e.getReferralInfo() );
+        LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
+        LDAPConstraints constraints = new LDAPConstraints();
+        constraints.setReferrals( false );
+        conn.setConstraints( constraints );
+    
+        // referrals failure
+        // modify success
+        LDAPAttribute attribute = new LDAPAttribute( "description", "referral to akarasulu" );
+        LDAPModification mod = new LDAPModification( LDAPModification.ADD, attribute );
+        LDAPResponseListener listener = conn.modify( "uid=akarasuluref,ou=users,ou=system", mod, null, constraints );
+        LDAPResponse response = listener.getResponse();
+    
+        assertEquals( ResultCodeEnum.REFERRAL.getValue(), response.getResultCode() );
+    
+        assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[0] );
+        assertEquals( "ldap://foo:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[1] );
+        assertEquals( "ldap://bar:10389/uid=akarasulu,ou=users,ou=system", response.getReferrals()[2] );
+    
+        conn.disconnect();
     }
-
-    ctx.close();
-}
-
-
-/**
- * Tests referral handling when an ancestor is a referral.
- */
-@Test
-public void testAncestorReferral() throws Exception
-{
-    LOG.debug( "" );
-
-    LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
-    LDAPConstraints constraints = new LDAPConstraints();
-    conn.setConstraints( constraints );
-
-    // referrals failure
-    LDAPAttribute attribute = new LDAPAttribute( "ou", "Machines" );
-    LDAPModification mod = new LDAPModification( LDAPModification.ADD, attribute );
-    LDAPResponseListener listener = null;
-    LDAPResponse response = null;
-
-    listener = conn.modify( "ou=Computers,uid=akarasuluref,ou=users,ou=system", mod, null, constraints );
-    response = listener.getResponse();
-    assertEquals( ResultCodeEnum.REFERRAL.getValue(), response.getResultCode() );
-
-    assertEquals( "ldap://localhost:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[0] );
-    assertEquals( "ldap://foo:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[1] );
-    assertEquals( "ldap://bar:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[2] );
-
-    conn.disconnect();
-}
+    
+    
+    /**
+     * Tests modify operation on normal and referral entries without the
+     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals
+     * are sent back to the client with a non-success result code.
+     */
+    @Test
+    public void testThrowOnReferralWithJndi() throws Exception
+    {
+        LdapContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
+    
+        // modify failure
+        Attribute attr = new BasicAttribute( "description", "referral to akarasulu" );
+        ModificationItem mod = new ModificationItem( DirContext.ADD_ATTRIBUTE, attr );
+    
+        try
+        {
+            ctx.modifyAttributes( "uid=akarasuluref,ou=users,ou=system", new ModificationItem[]
+                { mod } );
+        }
+        catch ( ReferralException e )
+        {
+            // seems JNDI only returns the first referral URL and not all so we test for it
+            assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", e.getReferralInfo() );
+        }
+    
+        ctx.close();
+    }
+    
+    
+    /**
+     * Tests referral handling when an ancestor is a referral.
+     */
+    @Test
+    public void testAncestorReferral() throws Exception
+    {
+        LOG.debug( "" );
+    
+        LDAPConnection conn = getNsdkWiredConnection( getLdapServer() );
+        LDAPConstraints constraints = new LDAPConstraints();
+        conn.setConstraints( constraints );
+    
+        // referrals failure
+        LDAPAttribute attribute = new LDAPAttribute( "ou", "Machines" );
+        LDAPModification mod = new LDAPModification( LDAPModification.ADD, attribute );
+        LDAPResponseListener listener = null;
+        LDAPResponse response = null;
+    
+        listener = conn.modify( "ou=Computers,uid=akarasuluref,ou=users,ou=system", mod, null, constraints );
+        response = listener.getResponse();
+        assertEquals( ResultCodeEnum.REFERRAL.getValue(), response.getResultCode() );
+    
+        assertEquals( "ldap://localhost:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[0] );
+        assertEquals( "ldap://foo:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[1] );
+        assertEquals( "ldap://bar:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[2] );
+    
+        conn.disconnect();
+    }
 }
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/lookup/LookupIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/lookup/LookupIT.java
index 54f8b9e..7a640cd 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/lookup/LookupIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/lookup/LookupIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.lookup;
 
@@ -24,6 +24,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -31,6 +32,7 @@
 import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.apache.directory.server.integ.ServerIntegrationUtils;
 import org.apache.directory.shared.ldap.model.entry.Entry;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -45,6 +47,9 @@
     { @CreateTransport(protocol = "LDAP") })
 public class LookupIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+
     /**
      * Evaluate the lookup operation when using a inherited Attribute
      */
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/lookup/LookupPerfIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/lookup/LookupPerfIT.java
index f5095b6..5e5cfef 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/lookup/LookupPerfIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/lookup/LookupPerfIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.lookup;
 
@@ -29,6 +29,7 @@
 import javax.naming.ldap.InitialLdapContext;
 import javax.naming.ldap.LdapContext;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -41,6 +42,7 @@
 import org.apache.directory.shared.ldap.model.message.Control;
 import org.apache.directory.shared.ldap.util.JndiUtils;
 import org.junit.Ignore;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -55,6 +57,8 @@
     { @CreateTransport(protocol = "LDAP") })
 public class LookupPerfIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     /**
      * Evaluate the lookup operation performances
      */
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/modify/IllegalModificationIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/modify/IllegalModificationIT.java
index f90c0f0..ac5e37f 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/modify/IllegalModificationIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/modify/IllegalModificationIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.modify;
 
@@ -25,6 +25,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -41,15 +42,16 @@
 import org.apache.directory.shared.ldap.model.message.ModifyResponse;
 import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.model.name.Dn;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 
-/** 
- * A test taken from DIRSERVER-630: If one tries to add an attribute to an 
- * entry, and does not provide a value, it is assumed that the server does 
- * not modify the entry. We have a situation here using Sun ONE Directory 
- * SDK for Java, where adding a description attribute without value to a 
+/**
+ * A test taken from DIRSERVER-630: If one tries to add an attribute to an
+ * entry, and does not provide a value, it is assumed that the server does
+ * not modify the entry. We have a situation here using Sun ONE Directory
+ * SDK for Java, where adding a description attribute without value to a
  * person entry like this,
  * <code>
  * dn: cn=Kate Bush,dc=example,dc=com
@@ -57,11 +59,11 @@
  * objectclass: top
  * sn: Bush
  * cn: Kate Bush
- * </code> 
- * does not fail (modify call does not result in an exception). Instead, a 
- * description attribute is created within the entry. At least the new 
- * attribute is readable with Netscape SDK (it is not visible to most UIs, 
- * because it is invalid ...). 
+ * </code>
+ * does not fail (modify call does not result in an exception). Instead, a
+ * description attribute is created within the entry. At least the new
+ * attribute is readable with Netscape SDK (it is not visible to most UIs,
+ * because it is invalid ...).
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
@@ -79,6 +81,8 @@
         "sn: Bush" })
 public class IllegalModificationIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private static final String DN = "cn=Kate Bush,ou=system";
 
 
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyAddIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyAddIT.java
index a79db92..fb43e7f 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyAddIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyAddIT.java
@@ -45,6 +45,7 @@
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
@@ -52,6 +53,7 @@
 import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.apache.directory.shared.ldap.model.exception.LdapException;
 import org.apache.directory.shared.ldap.model.ldif.LdifUtils;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -92,567 +94,505 @@
 })
 public class ModifyAddIT extends AbstractLdapTestUnit
 {
-private static final String BASE = "ou=system";
-private static final String RDN_TORI_AMOS = "cn=Tori Amos";
-private static final String PERSON_DESCRIPTION = "an American singer-songwriter";
-private static final String RDN_DEBBIE_HARRY = "cn=Debbie Harry";
-
-
-/**
- * Creation of required attributes of a person entry.
- */
-protected Attributes getPersonAttributes( String sn, String cn ) throws LdapException
-{
-    Attributes attributes = LdifUtils.createJndiAttributes(
-        "objectClass: top",
-        "objectClass: person",
-        "objectClass: organizationalperson",
-        "objectClass: inetorgperson",
-        "cn", cn,
-        "sn", sn );
-
-    return attributes;
-}
-
-
-/**
- * Add a new attribute to a person entry.
- */
-@Test
-public void testAddNewAttributeValue() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Add telephoneNumber attribute
-    String newValue = "1234567890";
-    Attributes attrs = new BasicAttributes( "telephoneNumber", newValue, true );
-    ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
-
-    // Verify, that
-    // - case of attribute description is correct
-    // - attribute value is added
-    attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    Attribute attr = attrs.get( "telephoneNumber" );
-    assertNotNull( attr );
-    assertEquals( "telephoneNumber", attr.getID() );
-    assertTrue( attr.contains( newValue ) );
-    assertEquals( 1, attr.size() );
-}
-
-
-/**
- * Add a new attribute with two values.
- */
-@Test
-public void testAddNewAttributeValues() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Add telephoneNumber attribute
-    String[] newValues =
-        { "1234567890", "999999999" };
-    Attribute attr = new BasicAttribute( "telephoneNumber" );
-    attr.add( newValues[0] );
-    attr.add( newValues[1] );
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( attr );
-    ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
-
-    // Verify, that
-    // - case of attribute description is correct
-    // - attribute values are present
-    attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    attr = attrs.get( "telephoneNumber" );
-    assertNotNull( attr );
-    assertEquals( "telephoneNumber", attr.getID() );
-    assertTrue( attr.contains( newValues[0] ) );
-    assertTrue( attr.contains( newValues[1] ) );
-    assertEquals( newValues.length, attr.size() );
-}
-
-
-/**
- * Add an additional value.
- */
-@Test
-public void testAddAdditionalAttributeValue() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // A new description attribute value
-    String newValue = "A new description for this person";
-    assertFalse( newValue.equals( PERSON_DESCRIPTION ) );
-    Attributes attrs = new BasicAttributes( "description", newValue, true );
-
-    ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
-
-    // Verify, that attribute value is added
-    attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    Attribute attr = attrs.get( "description" );
-    assertNotNull( attr );
-    assertTrue( attr.contains( newValue ) );
-    assertTrue( attr.contains( PERSON_DESCRIPTION ) );
-    assertEquals( 2, attr.size() );
-}
-
-
-/**
- * Try to add an already existing attribute value.
- *
- * Expected behaviour: Modify operation fails with an
- * AttributeInUseException. Original LDAP Error code: 20 (Indicates that the
- * attribute value specified in a modify or add operation already exists as
- * a value for that attribute).
- */
-@Test
-public void testAddExistingAttributeValue() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Change description attribute
-    Attributes attrs = new BasicAttributes( "description", PERSON_DESCRIPTION, true );
-
-    try
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    private static final String BASE = "ou=system";
+    private static final String RDN_TORI_AMOS = "cn=Tori Amos";
+    private static final String PERSON_DESCRIPTION = "an American singer-songwriter";
+    private static final String RDN_DEBBIE_HARRY = "cn=Debbie Harry";
+    
+    
+    /**
+     * Creation of required attributes of a person entry.
+     */
+    protected Attributes getPersonAttributes( String sn, String cn ) throws LdapException
     {
+        Attributes attributes = LdifUtils.createJndiAttributes(
+            "objectClass: top",
+            "objectClass: person",
+            "objectClass: organizationalperson",
+            "objectClass: inetorgperson",
+            "cn", cn,
+            "sn", sn );
+    
+        return attributes;
+    }
+    
+    
+    /**
+     * Add a new attribute to a person entry.
+     */
+    @Test
+    public void testAddNewAttributeValue() throws Exception
+    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Add telephoneNumber attribute
+        String newValue = "1234567890";
+        Attributes attrs = new BasicAttributes( "telephoneNumber", newValue, true );
         ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
-        fail( "Adding an already existing atribute value should fail." );
+    
+        // Verify, that
+        // - case of attribute description is correct
+        // - attribute value is added
+        attrs = ctx.getAttributes( RDN_TORI_AMOS );
+        Attribute attr = attrs.get( "telephoneNumber" );
+        assertNotNull( attr );
+        assertEquals( "telephoneNumber", attr.getID() );
+        assertTrue( attr.contains( newValue ) );
+        assertEquals( 1, attr.size() );
     }
-    catch ( AttributeInUseException e )
+    
+    
+    /**
+     * Add a new attribute with two values.
+     */
+    @Test
+    public void testAddNewAttributeValues() throws Exception
     {
-        // expected behaviour
-    }
-
-    // Verify, that attribute is still there, and is the only one
-    attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    Attribute attr = attrs.get( "description" );
-    assertNotNull( attr );
-    assertTrue( attr.contains( PERSON_DESCRIPTION ) );
-    assertEquals( 1, attr.size() );
-}
-
-
-/**
- * Try to add an already existing attribute value.
- *
- * Expected behaviour: Modify operation fails with an
- * AttributeInUseException. Original LDAP Error code: 20 (Indicates that the
- * attribute value specified in a modify or add operation already exists as
- * a value for that attribute).
- *
- * Check for bug DIR_SERVER664
- */
-@Test
-public void testAddExistingNthAttributesDirServer664() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Change description attribute
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( new BasicAttribute( "telephoneNumber", "1" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "2" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "3" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "4" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "5" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "6" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "7" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "8" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "9" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "10" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "11" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "12" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "13" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber", "14" ) );
-
-    Attribute attr = new BasicAttribute( "description", PERSON_DESCRIPTION );
-
-    attrs.put( attr );
-
-    try
-    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Add telephoneNumber attribute
+        String[] newValues =
+            { "1234567890", "999999999" };
+        Attribute attr = new BasicAttribute( "telephoneNumber" );
+        attr.add( newValues[0] );
+        attr.add( newValues[1] );
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( attr );
         ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
-        fail( "Adding an already existing atribute value should fail." );
+    
+        // Verify, that
+        // - case of attribute description is correct
+        // - attribute values are present
+        attrs = ctx.getAttributes( RDN_TORI_AMOS );
+        attr = attrs.get( "telephoneNumber" );
+        assertNotNull( attr );
+        assertEquals( "telephoneNumber", attr.getID() );
+        assertTrue( attr.contains( newValues[0] ) );
+        assertTrue( attr.contains( newValues[1] ) );
+        assertEquals( newValues.length, attr.size() );
     }
-    catch ( AttributeInUseException e )
+    
+    
+    /**
+     * Add an additional value.
+     */
+    @Test
+    public void testAddAdditionalAttributeValue() throws Exception
     {
-        // expected behaviour
-    }
-
-    // Verify, that attribute is still there, and is the only one
-    attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    attr = attrs.get( "description" );
-    assertNotNull( attr );
-    assertTrue( attr.contains( PERSON_DESCRIPTION ) );
-    assertEquals( 1, attr.size() );
-}
-
-
-/**
- * Check for DIR_SERVER_643
- */
-@Test
-public void testTwoDescriptionDirServer643() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Change description attribute
-    Attributes attrs = new BasicAttributes( true );
-    Attribute attr = new BasicAttribute( "description",
-        "a British singer-songwriter with an expressive four-octave voice" );
-    attr.add( "one of the most influential female artists of the twentieth century" );
-    attrs.put( attr );
-
-    ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
-
-    // Verify, that attribute is still there, and is the only one
-    attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    attr = attrs.get( "description" );
-    assertNotNull( attr );
-    assertEquals( 3, attr.size() );
-    assertTrue( attr.contains( "a British singer-songwriter with an expressive four-octave voice" ) );
-    assertTrue( attr.contains( "one of the most influential female artists of the twentieth century" ) );
-    assertTrue( attr.contains( PERSON_DESCRIPTION ) );
-}
-
-
-/**
- * Try to add a duplicate attribute value to an entry, where this attribute
- * is already present (objectclass in this case). Expected behaviour is that
- * the modify operation causes an error (error code 20, "Attribute or value
- * exists").
- */
-@Test
-public void testAddDuplicateValueToExistingAttribute() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // modify object classes, add a new value twice
-    Attribute ocls = new BasicAttribute( "objectClass", "organizationalPerson" );
-    ModificationItem[] modItems = new ModificationItem[2];
-    modItems[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, ocls );
-    modItems[1] = new ModificationItem( DirContext.ADD_ATTRIBUTE, ocls );
-    try
-    {
-        ctx.modifyAttributes( RDN_TORI_AMOS, modItems );
-        fail( "Adding a duplicate attribute value should cause an error." );
-    }
-    catch ( AttributeInUseException ex )
-    {
-    }
-
-    // Check, whether attribute objectClass is unchanged
-    Attributes attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    ocls = attrs.get( "objectClass" );
-    assertEquals( ocls.size(), 4 );
-    assertTrue( ocls.contains( "top" ) );
-    assertTrue( ocls.contains( "person" ) );
-}
-
-
-/**
- * Try to add a duplicate attribute value to an entry, where this attribute
- * is not present. Expected behaviour is that the modify operation causes an
- * error (error code 20, "Attribute or value exists").
- */
-@Test
-public void testAddDuplicateValueToNewAttribute() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // add the same description value twice
-    Attribute desc = new BasicAttribute( "description", "another description value besides songwriter" );
-    ModificationItem[] modItems = new ModificationItem[2];
-    modItems[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, desc );
-    modItems[1] = new ModificationItem( DirContext.ADD_ATTRIBUTE, desc );
-    try
-    {
-        ctx.modifyAttributes( RDN_TORI_AMOS, modItems );
-        fail( "Adding a duplicate attribute value should cause an error." );
-    }
-    catch ( AttributeInUseException ex )
-    {
-    }
-
-    // Check, whether attribute description is still not present
-    Attributes attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    assertEquals( 1, attrs.get( "description" ).size() );
-}
-
-
-/**
- * Modify the entry with a bad attribute : this should fail
- */
-@Test
-public void testSearchBadAttribute() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Add a not existing attribute
-    String newValue = "unbelievable";
-    Attributes attrs = new BasicAttributes( "voice", newValue, true );
-
-    try
-    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // A new description attribute value
+        String newValue = "A new description for this person";
+        assertFalse( newValue.equals( PERSON_DESCRIPTION ) );
+        Attributes attrs = new BasicAttributes( "description", newValue, true );
+    
         ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
+    
+        // Verify, that attribute value is added
+        attrs = ctx.getAttributes( RDN_TORI_AMOS );
+        Attribute attr = attrs.get( "description" );
+        assertNotNull( attr );
+        assertTrue( attr.contains( newValue ) );
+        assertTrue( attr.contains( PERSON_DESCRIPTION ) );
+        assertEquals( 2, attr.size() );
     }
-    catch ( NoSuchAttributeException nsae )
+    
+    
+    /**
+     * Try to add an already existing attribute value.
+     *
+     * Expected behaviour: Modify operation fails with an
+     * AttributeInUseException. Original LDAP Error code: 20 (Indicates that the
+     * attribute value specified in a modify or add operation already exists as
+     * a value for that attribute).
+     */
+    @Test
+    public void testAddExistingAttributeValue() throws Exception
     {
-        // We have a failure : the attribute is unknown in the schema
-        assertTrue( true );
-        return;
-    }
-
-    fail( "Cannot reach this point" );
-}
-
-
-/**
- * Create a person entry and perform a modify op, in which
- * we modify an attribute two times.
- */
-@Test
-public void testAttributeValueMultiMofificationDIRSERVER_636() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Create a person entry
-    Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
-    String rdn = "cn=Kate Bush";
-    ctx.createSubcontext( rdn, attrs );
-
-    // Add a description with two values
-    String[] descriptions =
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Change description attribute
+        Attributes attrs = new BasicAttributes( "description", PERSON_DESCRIPTION, true );
+    
+        try
         {
-            "Kate Bush is a British singer-songwriter.",
-            "She has become one of the most influential female artists of the twentieth century." };
-    Attribute desc1 = new BasicAttribute( "description" );
-    desc1.add( descriptions[0] );
-    desc1.add( descriptions[1] );
-
-    ModificationItem addModOp = new ModificationItem(
-        DirContext.ADD_ATTRIBUTE, desc1 );
-
-    Attribute desc2 = new BasicAttribute( "description" );
-    desc2.add( descriptions[1] );
-    ModificationItem delModOp = new ModificationItem(
-        DirContext.REMOVE_ATTRIBUTE, desc2 );
-
-    ctx.modifyAttributes( rdn, new ModificationItem[]
-        { addModOp,
-            delModOp } );
-
-    SearchControls sctls = new SearchControls();
-    sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-    String filter = "(cn=*Bush)";
-    String base = "";
-
-    // Check entry
-    NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
-    assertTrue( enm.hasMore() );
-
-    while ( enm.hasMore() )
-    {
-        SearchResult sr = enm.next();
-        attrs = sr.getAttributes();
-        Attribute desc = sr.getAttributes().get( "description" );
-        assertEquals( 1, desc.size() );
-        assertTrue( desc.contains( descriptions[0] ) );
+            ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
+            fail( "Adding an already existing atribute value should fail." );
+        }
+        catch ( AttributeInUseException e )
+        {
+            // expected behaviour
+        }
+    
+        // Verify, that attribute is still there, and is the only one
+        attrs = ctx.getAttributes( RDN_TORI_AMOS );
+        Attribute attr = attrs.get( "description" );
+        assertNotNull( attr );
+        assertTrue( attr.contains( PERSON_DESCRIPTION ) );
+        assertEquals( 1, attr.size() );
     }
-
-    // Remove the person entry
-    ctx.destroySubcontext( rdn );
-}
-
-
-/**
- * Try to add subschemaSubentry attribute to an entry
- */
-@Test
-public void testModifyOperationalAttributeAdd() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    ModificationItem modifyOp = new ModificationItem( DirContext.ADD_ATTRIBUTE, new BasicAttribute(
-        "subschemaSubentry", "cn=anotherSchema" ) );
-
-    try
+    
+    
+    /**
+     * Try to add an already existing attribute value.
+     *
+     * Expected behaviour: Modify operation fails with an
+     * AttributeInUseException. Original LDAP Error code: 20 (Indicates that the
+     * attribute value specified in a modify or add operation already exists as
+     * a value for that attribute).
+     *
+     * Check for bug DIR_SERVER664
+     */
+    @Test
+    public void testAddExistingNthAttributesDirServer664() throws Exception
     {
-        ctx.modifyAttributes( RDN_DEBBIE_HARRY, new ModificationItem[]
-            { modifyOp } );
-
-        fail( "modification of entry should fail" );
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Change description attribute
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( new BasicAttribute( "telephoneNumber", "1" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "2" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "3" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "4" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "5" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "6" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "7" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "8" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "9" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "10" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "11" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "12" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "13" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber", "14" ) );
+    
+        Attribute attr = new BasicAttribute( "description", PERSON_DESCRIPTION );
+    
+        attrs.put( attr );
+    
+        try
+        {
+            ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
+            fail( "Adding an already existing atribute value should fail." );
+        }
+        catch ( AttributeInUseException e )
+        {
+            // expected behaviour
+        }
+    
+        // Verify, that attribute is still there, and is the only one
+        attrs = ctx.getAttributes( RDN_TORI_AMOS );
+        attr = attrs.get( "description" );
+        assertNotNull( attr );
+        assertTrue( attr.contains( PERSON_DESCRIPTION ) );
+        assertEquals( 1, attr.size() );
     }
-    catch ( InvalidAttributeValueException e )
+    
+    
+    /**
+     * Check for DIR_SERVER_643
+     */
+    @Test
+    public void testTwoDescriptionDirServer643() throws Exception
     {
-        // Expected result
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Change description attribute
+        Attributes attrs = new BasicAttributes( true );
+        Attribute attr = new BasicAttribute( "description",
+            "a British singer-songwriter with an expressive four-octave voice" );
+        attr.add( "one of the most influential female artists of the twentieth century" );
+        attrs.put( attr );
+    
+        ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
+    
+        // Verify, that attribute is still there, and is the only one
+        attrs = ctx.getAttributes( RDN_TORI_AMOS );
+        attr = attrs.get( "description" );
+        assertNotNull( attr );
+        assertEquals( 3, attr.size() );
+        assertTrue( attr.contains( "a British singer-songwriter with an expressive four-octave voice" ) );
+        assertTrue( attr.contains( "one of the most influential female artists of the twentieth century" ) );
+        assertTrue( attr.contains( PERSON_DESCRIPTION ) );
     }
-    catch ( NoPermissionException e )
+    
+    
+    /**
+     * Try to add a duplicate attribute value to an entry, where this attribute
+     * is already present (objectclass in this case). Expected behaviour is that
+     * the modify operation causes an error (error code 20, "Attribute or value
+     * exists").
+     */
+    @Test
+    public void testAddDuplicateValueToExistingAttribute() throws Exception
     {
-        // Expected result
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // modify object classes, add a new value twice
+        Attribute ocls = new BasicAttribute( "objectClass", "organizationalPerson" );
+        ModificationItem[] modItems = new ModificationItem[2];
+        modItems[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, ocls );
+        modItems[1] = new ModificationItem( DirContext.ADD_ATTRIBUTE, ocls );
+        try
+        {
+            ctx.modifyAttributes( RDN_TORI_AMOS, modItems );
+            fail( "Adding a duplicate attribute value should cause an error." );
+        }
+        catch ( AttributeInUseException ex )
+        {
+        }
+    
+        // Check, whether attribute objectClass is unchanged
+        Attributes attrs = ctx.getAttributes( RDN_TORI_AMOS );
+        ocls = attrs.get( "objectClass" );
+        assertEquals( ocls.size(), 4 );
+        assertTrue( ocls.contains( "top" ) );
+        assertTrue( ocls.contains( "person" ) );
     }
-}
-
-
-/**
- * Create a person entry and perform a modify op on an
- * attribute which is part of the Dn. This is not allowed.
- *
- * A JIRA has been created for this bug : DIRSERVER_687
- */
-@Test
-public void testDNAttributeMemberModificationDIRSERVER_687() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Create a person entry
-    Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
-    String rdn = "cn=Kate Bush";
-    ctx.createSubcontext( rdn, attrs );
-
-    // Try to modify the cn attribute
-    Attribute desc1 = new BasicAttribute( "cn", "Georges Bush" );
-
-    ModificationItem addModOp = new ModificationItem(
-        DirContext.REPLACE_ATTRIBUTE, desc1 );
-
-    try
+    
+    
+    /**
+     * Try to add a duplicate attribute value to an entry, where this attribute
+     * is not present. Expected behaviour is that the modify operation causes an
+     * error (error code 20, "Attribute or value exists").
+     */
+    @Test
+    public void testAddDuplicateValueToNewAttribute() throws Exception
     {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // add the same description value twice
+        Attribute desc = new BasicAttribute( "description", "another description value besides songwriter" );
+        ModificationItem[] modItems = new ModificationItem[2];
+        modItems[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, desc );
+        modItems[1] = new ModificationItem( DirContext.ADD_ATTRIBUTE, desc );
+        try
+        {
+            ctx.modifyAttributes( RDN_TORI_AMOS, modItems );
+            fail( "Adding a duplicate attribute value should cause an error." );
+        }
+        catch ( AttributeInUseException ex )
+        {
+        }
+    
+        // Check, whether attribute description is still not present
+        Attributes attrs = ctx.getAttributes( RDN_TORI_AMOS );
+        assertEquals( 1, attrs.get( "description" ).size() );
+    }
+    
+    
+    /**
+     * Modify the entry with a bad attribute : this should fail
+     */
+    @Test
+    public void testSearchBadAttribute() throws Exception
+    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Add a not existing attribute
+        String newValue = "unbelievable";
+        Attributes attrs = new BasicAttributes( "voice", newValue, true );
+    
+        try
+        {
+            ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
+        }
+        catch ( NoSuchAttributeException nsae )
+        {
+            // We have a failure : the attribute is unknown in the schema
+            assertTrue( true );
+            return;
+        }
+    
+        fail( "Cannot reach this point" );
+    }
+    
+    
+    /**
+     * Create a person entry and perform a modify op, in which
+     * we modify an attribute two times.
+     */
+    @Test
+    public void testAttributeValueMultiMofificationDIRSERVER_636() throws Exception
+    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Create a person entry
+        Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
+        String rdn = "cn=Kate Bush";
+        ctx.createSubcontext( rdn, attrs );
+    
+        // Add a description with two values
+        String[] descriptions =
+            {
+                "Kate Bush is a British singer-songwriter.",
+                "She has become one of the most influential female artists of the twentieth century." };
+        Attribute desc1 = new BasicAttribute( "description" );
+        desc1.add( descriptions[0] );
+        desc1.add( descriptions[1] );
+    
+        ModificationItem addModOp = new ModificationItem(
+            DirContext.ADD_ATTRIBUTE, desc1 );
+    
+        Attribute desc2 = new BasicAttribute( "description" );
+        desc2.add( descriptions[1] );
+        ModificationItem delModOp = new ModificationItem(
+            DirContext.REMOVE_ATTRIBUTE, desc2 );
+    
         ctx.modifyAttributes( rdn, new ModificationItem[]
-            { addModOp } );
-        fail();
-    }
-    catch ( AttributeModificationException ame )
-    {
-        assertTrue( true );
+            { addModOp,
+                delModOp } );
+    
+        SearchControls sctls = new SearchControls();
+        sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+        String filter = "(cn=*Bush)";
+        String base = "";
+    
+        // Check entry
+        NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
+        assertTrue( enm.hasMore() );
+    
+        while ( enm.hasMore() )
+        {
+            SearchResult sr = enm.next();
+            attrs = sr.getAttributes();
+            Attribute desc = sr.getAttributes().get( "description" );
+            assertEquals( 1, desc.size() );
+            assertTrue( desc.contains( descriptions[0] ) );
+        }
+    
         // Remove the person entry
         ctx.destroySubcontext( rdn );
     }
-    catch ( NamingException ne )
+    
+    
+    /**
+     * Try to add subschemaSubentry attribute to an entry
+     */
+    @Test
+    public void testModifyOperationalAttributeAdd() throws Exception
     {
-        assertTrue( true );
-        // Remove the person entry
-        ctx.destroySubcontext( rdn );
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        ModificationItem modifyOp = new ModificationItem( DirContext.ADD_ATTRIBUTE, new BasicAttribute(
+            "subschemaSubentry", "cn=anotherSchema" ) );
+    
+        try
+        {
+            ctx.modifyAttributes( RDN_DEBBIE_HARRY, new ModificationItem[]
+                { modifyOp } );
+    
+            fail( "modification of entry should fail" );
+        }
+        catch ( InvalidAttributeValueException e )
+        {
+            // Expected result
+        }
+        catch ( NoPermissionException e )
+        {
+            // Expected result
+        }
     }
-}
-
-
-/**
- * Try to modify an entry adding invalid number of values for a single-valued atribute
- *
- * @see <a href="http://issues.apache.org/jira/browse/DIRSERVER-614">DIRSERVER-614</a>
- */
-@Test
-public void testModifyAddWithInvalidNumberOfAttributeValues() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    Attributes attrs = new BasicAttributes( true );
-    Attribute ocls = new BasicAttribute( "objectClass" );
-    ocls.add( "top" );
-    ocls.add( "inetOrgPerson" );
-    attrs.put( ocls );
-    attrs.put( "cn", "Fiona Apple" );
-    attrs.put( "sn", "Apple" );
-    ctx.createSubcontext( "cn=Fiona Apple", attrs );
-
-    // add two displayNames to an inetOrgPerson
-    attrs = new BasicAttributes( true );
-    Attribute displayName = new BasicAttribute( "displayName" );
-    displayName.add( "Fiona" );
-    displayName.add( "Fiona A." );
-    attrs.put( displayName );
-
-    try
+    
+    
+    /**
+     * Create a person entry and perform a modify op on an
+     * attribute which is part of the Dn. This is not allowed.
+     *
+     * A JIRA has been created for this bug : DIRSERVER_687
+     */
+    @Test
+    public void testDNAttributeMemberModificationDIRSERVER_687() throws Exception
     {
-        ctx.modifyAttributes( "cn=Fiona Apple", DirContext.ADD_ATTRIBUTE, attrs );
-        fail( "modification of entry should fail" );
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Create a person entry
+        Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
+        String rdn = "cn=Kate Bush";
+        ctx.createSubcontext( rdn, attrs );
+    
+        // Try to modify the cn attribute
+        Attribute desc1 = new BasicAttribute( "cn", "Georges Bush" );
+    
+        ModificationItem addModOp = new ModificationItem(
+            DirContext.REPLACE_ATTRIBUTE, desc1 );
+    
+        try
+        {
+            ctx.modifyAttributes( rdn, new ModificationItem[]
+                { addModOp } );
+            fail();
+        }
+        catch ( AttributeModificationException ame )
+        {
+            assertTrue( true );
+            // Remove the person entry
+            ctx.destroySubcontext( rdn );
+        }
+        catch ( NamingException ne )
+        {
+            assertTrue( true );
+            // Remove the person entry
+            ctx.destroySubcontext( rdn );
+        }
     }
-    catch ( InvalidAttributeValueException e )
+    
+    
+    /**
+     * Try to modify an entry adding invalid number of values for a single-valued atribute
+     *
+     * @see <a href="http://issues.apache.org/jira/browse/DIRSERVER-614">DIRSERVER-614</a>
+     */
+    @Test
+    public void testModifyAddWithInvalidNumberOfAttributeValues() throws Exception
     {
-
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        Attributes attrs = new BasicAttributes( true );
+        Attribute ocls = new BasicAttribute( "objectClass" );
+        ocls.add( "top" );
+        ocls.add( "inetOrgPerson" );
+        attrs.put( ocls );
+        attrs.put( "cn", "Fiona Apple" );
+        attrs.put( "sn", "Apple" );
+        ctx.createSubcontext( "cn=Fiona Apple", attrs );
+    
+        // add two displayNames to an inetOrgPerson
+        attrs = new BasicAttributes( true );
+        Attribute displayName = new BasicAttribute( "displayName" );
+        displayName.add( "Fiona" );
+        displayName.add( "Fiona A." );
+        attrs.put( displayName );
+    
+        try
+        {
+            ctx.modifyAttributes( "cn=Fiona Apple", DirContext.ADD_ATTRIBUTE, attrs );
+            fail( "modification of entry should fail" );
+        }
+        catch ( InvalidAttributeValueException e )
+        {
+    
+        }
     }
-}
-
-
-/**
- * Add a new binary attribute to a person entry.
- */
-@Test
-public void testAddNewBinaryAttributeValue() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Add a binary attribute
-    byte[] newValue = new byte[]
-        { 0x00, 0x01, 0x02, 0x03 };
-    Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue, true );
-    ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
-
-    // Verify, that attribute value is added
-    attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    Attribute attr = attrs.get( "userCertificate" );
-    assertNotNull( attr );
-    assertTrue( attr.contains( newValue ) );
-    byte[] certificate = ( byte[] ) attr.get();
-    assertTrue( Arrays.equals( newValue, certificate ) );
-    assertEquals( 1, attr.size() );
-}
-
-
-/**
- * Add a new attribute to a person entry.
- */
-@Test
-public void testAddNewBinaryAttributeValueAbove0x80() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Add a binary attribute
-    byte[] newValue = new byte[]
-        { ( byte ) 0x80, ( byte ) 0x81, ( byte ) 0x82, ( byte ) 0x83 };
-    Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue, true );
-    ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
-
-    // Verify, that attribute value is added
-    attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    Attribute attr = attrs.get( "userCertificate" );
-    assertNotNull( attr );
-    assertTrue( attr.contains( newValue ) );
-    byte[] certificate = ( byte[] ) attr.get();
-    assertTrue( Arrays.equals( newValue, certificate ) );
-    assertEquals( 1, attr.size() );
-}
-
-
-/**
- * Add a new binary attribute to a person entry.
- */
-@Test
-public void testRetrieveEntryWithBinaryAttributeValue() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Add a ;binary attribute
-    byte[] newValue = new byte[]
-        { 0x00, 0x01, 0x02, 0x03 };
-    Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue );
-    ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
-
-    // Search entry an request ;binary attribute
-    SearchControls sctls = new SearchControls();
-    sctls.setSearchScope( SearchControls.OBJECT_SCOPE );
-    sctls.setReturningAttributes( new String[]
-        { "userCertificate;binary" } );
-    String filter = "(objectClass=*)";
-    String base = RDN_TORI_AMOS;
-
-    // Test that ;binary attribute is present
-    NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
-    assertTrue( enm.hasMore() );
-
-    while ( enm.hasMore() )
+    
+    
+    /**
+     * Add a new binary attribute to a person entry.
+     */
+    @Test
+    public void testAddNewBinaryAttributeValue() throws Exception
     {
-        SearchResult sr = enm.next();
-        attrs = sr.getAttributes();
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Add a binary attribute
+        byte[] newValue = new byte[]
+            { 0x00, 0x01, 0x02, 0x03 };
+        Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue, true );
+        ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
+    
+        // Verify, that attribute value is added
+        attrs = ctx.getAttributes( RDN_TORI_AMOS );
         Attribute attr = attrs.get( "userCertificate" );
         assertNotNull( attr );
         assertTrue( attr.contains( newValue ) );
@@ -660,34 +600,98 @@
         assertTrue( Arrays.equals( newValue, certificate ) );
         assertEquals( 1, attr.size() );
     }
-
-}
-
-
-/**
- * Add a new ;binary attribute with bytes greater than 0x80
- * to a person entry.
- * Test for DIRSERVER-1146
- *
- * @throws NamingException
- */
-public void testAddNewBinaryAttributeValue0x80() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Add a ;binary attribute with high-bytes
-    byte[] newValue = new byte[]
-        { ( byte ) 0x80, ( byte ) 0x81, ( byte ) 0x82, ( byte ) 0x83 };
-    Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue );
-    ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
-
-    // Verify, that attribute value is added
-    attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    Attribute attr = attrs.get( "userCertificate" );
-    assertNotNull( attr );
-    assertTrue( attr.contains( newValue ) );
-    byte[] certificate = ( byte[] ) attr.get();
-    assertTrue( Arrays.equals( newValue, certificate ) );
-    assertEquals( 1, attr.size() );
-}
+    
+    
+    /**
+     * Add a new attribute to a person entry.
+     */
+    @Test
+    public void testAddNewBinaryAttributeValueAbove0x80() throws Exception
+    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Add a binary attribute
+        byte[] newValue = new byte[]
+            { ( byte ) 0x80, ( byte ) 0x81, ( byte ) 0x82, ( byte ) 0x83 };
+        Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue, true );
+        ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
+    
+        // Verify, that attribute value is added
+        attrs = ctx.getAttributes( RDN_TORI_AMOS );
+        Attribute attr = attrs.get( "userCertificate" );
+        assertNotNull( attr );
+        assertTrue( attr.contains( newValue ) );
+        byte[] certificate = ( byte[] ) attr.get();
+        assertTrue( Arrays.equals( newValue, certificate ) );
+        assertEquals( 1, attr.size() );
+    }
+    
+    
+    /**
+     * Add a new binary attribute to a person entry.
+     */
+    @Test
+    public void testRetrieveEntryWithBinaryAttributeValue() throws Exception
+    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Add a ;binary attribute
+        byte[] newValue = new byte[]
+            { 0x00, 0x01, 0x02, 0x03 };
+        Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue );
+        ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
+    
+        // Search entry an request ;binary attribute
+        SearchControls sctls = new SearchControls();
+        sctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+        sctls.setReturningAttributes( new String[]
+            { "userCertificate;binary" } );
+        String filter = "(objectClass=*)";
+        String base = RDN_TORI_AMOS;
+    
+        // Test that ;binary attribute is present
+        NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
+        assertTrue( enm.hasMore() );
+    
+        while ( enm.hasMore() )
+        {
+            SearchResult sr = enm.next();
+            attrs = sr.getAttributes();
+            Attribute attr = attrs.get( "userCertificate" );
+            assertNotNull( attr );
+            assertTrue( attr.contains( newValue ) );
+            byte[] certificate = ( byte[] ) attr.get();
+            assertTrue( Arrays.equals( newValue, certificate ) );
+            assertEquals( 1, attr.size() );
+        }
+    
+    }
+    
+    
+    /**
+     * Add a new ;binary attribute with bytes greater than 0x80
+     * to a person entry.
+     * Test for DIRSERVER-1146
+     *
+     * @throws NamingException
+     */
+    public void testAddNewBinaryAttributeValue0x80() throws Exception
+    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Add a ;binary attribute with high-bytes
+        byte[] newValue = new byte[]
+            { ( byte ) 0x80, ( byte ) 0x81, ( byte ) 0x82, ( byte ) 0x83 };
+        Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue );
+        ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
+    
+        // Verify, that attribute value is added
+        attrs = ctx.getAttributes( RDN_TORI_AMOS );
+        Attribute attr = attrs.get( "userCertificate" );
+        assertNotNull( attr );
+        assertTrue( attr.contains( newValue ) );
+        byte[] certificate = ( byte[] ) attr.get();
+        assertTrue( Arrays.equals( newValue, certificate ) );
+        assertEquals( 1, attr.size() );
+    }
 }
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyMultipleChangesIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyMultipleChangesIT.java
index 19dba41..607989c 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyMultipleChangesIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyMultipleChangesIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.modify;
 
@@ -35,11 +35,13 @@
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -78,114 +80,116 @@
 })
 public class ModifyMultipleChangesIT extends AbstractLdapTestUnit
 {
-private static final String BASE = "ou=system";
-private static final String RDN_TORI_AMOS = "cn=Tori Amos";
-
-
-/**
- * Creation of required attributes of a person entry.
- */
-protected Attributes getPersonAttributes( String sn, String cn )
-{
-    Attributes attributes = new BasicAttributes( true );
-    Attribute attribute = new BasicAttribute( "objectClass" );
-    attribute.add( "top" );
-    attribute.add( "person" );
-    attribute.add( "organizationalperson" );
-    attribute.add( "inetorgperson" );
-    attributes.put( attribute );
-    attributes.put( "cn", cn );
-    attributes.put( "sn", sn );
-
-    return attributes;
-}
-
-
-/**
- * Add a new attribute with two values.
- */
-@Test
-public void testAddNewAttributeValues() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Add telephoneNumber attribute
-    String[] newValues =
-        { "1234567890", "999999999" };
-    Attribute attr = new BasicAttribute( "telephoneNumber" );
-    attr.add( newValues[0] );
-    attr.add( newValues[1] );
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( attr );
-    ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
-
-    // Verify, that
-    // - case of attribute description is correct
-    // - attribute values are present
-    attrs = ctx.getAttributes( RDN_TORI_AMOS );
-    attr = attrs.get( "telephoneNumber" );
-    assertNotNull( attr );
-    assertEquals( "telephoneNumber", attr.getID() );
-    assertTrue( attr.contains( newValues[0] ) );
-    assertTrue( attr.contains( newValues[1] ) );
-    assertEquals( newValues.length, attr.size() );
-}
-
-
-/**
- * Create a person entry and perform a modify op, in which
- * we modify an attribute two times.
- */
-@Test
-public void testAttributeValueMultiMofificationDIRSERVER_636() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Create a person entry
-    Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
-    String rdn = "cn=Kate Bush";
-    ctx.createSubcontext( rdn, attrs );
-
-    // Add a description with two values
-    String[] descriptions =
-        {
-            "Kate Bush is a British singer-songwriter.",
-            "She has become one of the most influential female artists of the twentieth century." };
-    Attribute desc1 = new BasicAttribute( "description" );
-    desc1.add( descriptions[0] );
-    desc1.add( descriptions[1] );
-
-    ModificationItem addModOp = new ModificationItem(
-        DirContext.ADD_ATTRIBUTE, desc1 );
-
-    Attribute desc2 = new BasicAttribute( "description" );
-    desc2.add( descriptions[1] );
-    ModificationItem delModOp = new ModificationItem(
-        DirContext.REMOVE_ATTRIBUTE, desc2 );
-
-    ctx.modifyAttributes( rdn, new ModificationItem[]
-        { addModOp,
-            delModOp } );
-
-    SearchControls sctls = new SearchControls();
-    sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-    String filter = "(cn=*Bush)";
-    String base = "";
-
-    // Check entry
-    NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
-    assertTrue( enm.hasMore() );
-
-    while ( enm.hasMore() )
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    private static final String BASE = "ou=system";
+    private static final String RDN_TORI_AMOS = "cn=Tori Amos";
+    
+    
+    /**
+     * Creation of required attributes of a person entry.
+     */
+    protected Attributes getPersonAttributes( String sn, String cn )
     {
-        SearchResult sr = enm.next();
-        attrs = sr.getAttributes();
-        Attribute desc = sr.getAttributes().get( "description" );
-        assertEquals( 1, desc.size() );
-        assertTrue( desc.contains( descriptions[0] ) );
+        Attributes attributes = new BasicAttributes( true );
+        Attribute attribute = new BasicAttribute( "objectClass" );
+        attribute.add( "top" );
+        attribute.add( "person" );
+        attribute.add( "organizationalperson" );
+        attribute.add( "inetorgperson" );
+        attributes.put( attribute );
+        attributes.put( "cn", cn );
+        attributes.put( "sn", sn );
+    
+        return attributes;
     }
-
-    // Remove the person entry
-    ctx.destroySubcontext( rdn );
-}
+    
+    
+    /**
+     * Add a new attribute with two values.
+     */
+    @Test
+    public void testAddNewAttributeValues() throws Exception
+    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Add telephoneNumber attribute
+        String[] newValues =
+            { "1234567890", "999999999" };
+        Attribute attr = new BasicAttribute( "telephoneNumber" );
+        attr.add( newValues[0] );
+        attr.add( newValues[1] );
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( attr );
+        ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );
+    
+        // Verify, that
+        // - case of attribute description is correct
+        // - attribute values are present
+        attrs = ctx.getAttributes( RDN_TORI_AMOS );
+        attr = attrs.get( "telephoneNumber" );
+        assertNotNull( attr );
+        assertEquals( "telephoneNumber", attr.getID() );
+        assertTrue( attr.contains( newValues[0] ) );
+        assertTrue( attr.contains( newValues[1] ) );
+        assertEquals( newValues.length, attr.size() );
+    }
+    
+    
+    /**
+     * Create a person entry and perform a modify op, in which
+     * we modify an attribute two times.
+     */
+    @Test
+    public void testAttributeValueMultiMofificationDIRSERVER_636() throws Exception
+    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Create a person entry
+        Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
+        String rdn = "cn=Kate Bush";
+        ctx.createSubcontext( rdn, attrs );
+    
+        // Add a description with two values
+        String[] descriptions =
+            {
+                "Kate Bush is a British singer-songwriter.",
+                "She has become one of the most influential female artists of the twentieth century." };
+        Attribute desc1 = new BasicAttribute( "description" );
+        desc1.add( descriptions[0] );
+        desc1.add( descriptions[1] );
+    
+        ModificationItem addModOp = new ModificationItem(
+            DirContext.ADD_ATTRIBUTE, desc1 );
+    
+        Attribute desc2 = new BasicAttribute( "description" );
+        desc2.add( descriptions[1] );
+        ModificationItem delModOp = new ModificationItem(
+            DirContext.REMOVE_ATTRIBUTE, desc2 );
+    
+        ctx.modifyAttributes( rdn, new ModificationItem[]
+            { addModOp,
+                delModOp } );
+    
+        SearchControls sctls = new SearchControls();
+        sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+        String filter = "(cn=*Bush)";
+        String base = "";
+    
+        // Check entry
+        NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
+        assertTrue( enm.hasMore() );
+    
+        while ( enm.hasMore() )
+        {
+            SearchResult sr = enm.next();
+            attrs = sr.getAttributes();
+            Attribute desc = sr.getAttributes().get( "description" );
+            assertEquals( 1, desc.size() );
+            assertTrue( desc.contains( descriptions[0] ) );
+        }
+    
+        // Remove the person entry
+        ctx.destroySubcontext( rdn );
+    }
 }
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyReferralIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyReferralIT.java
index a966382..8e5e2fa 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyReferralIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyReferralIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.modify;
 
@@ -32,6 +32,7 @@
 import javax.naming.directory.ModificationItem;
 import javax.naming.ldap.LdapContext;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -46,17 +47,18 @@
 import org.apache.directory.shared.ldap.model.message.controls.ManageDsaIT;
 import org.apache.directory.shared.ldap.model.message.controls.ManageDsaITImpl;
 import org.apache.directory.shared.ldap.model.name.Dn;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 
-/** 
- * A test taken from DIRSERVER-630: If one tries to add an attribute to an 
- * entry, and does not provide a value, it is assumed that the server does 
- * not modify the entry. We have a situation here using Sun ONE Directory 
- * SDK for Java, where adding a description attribute without value to a 
+/**
+ * A test taken from DIRSERVER-630: If one tries to add an attribute to an
+ * entry, and does not provide a value, it is assumed that the server does
+ * not modify the entry. We have a situation here using Sun ONE Directory
+ * SDK for Java, where adding a description attribute without value to a
  * person entry like this,
  * <code>
  * dn: cn=Kate Bush,dc=example,dc=com
@@ -64,11 +66,11 @@
  * objectclass: top
  * sn: Bush
  * cn: Kate Bush
- * </code> 
- * does not fail (modify call does not result in an exception). Instead, a 
- * description attribute is created within the entry. At least the new 
- * attribute is readable with Netscape SDK (it is not visible to most UIs, 
- * because it is invalid ...). 
+ * </code>
+ * does not fail (modify call does not result in an exception). Instead, a
+ * description attribute is created within the entry. At least the new
+ * attribute is readable with Netscape SDK (it is not visible to most UIs,
+ * because it is invalid ...).
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
@@ -108,120 +110,122 @@
 })
 public class ModifyReferralIT extends AbstractLdapTestUnit
 {
-private static final Logger LOG = LoggerFactory.getLogger( CompareIT.class );
-
-
-/**
- * Tests modify operation on referral entry with the ManageDsaIT control.
- */
-@Test
-public void testOnReferralWithManageDsaITControl() throws Exception
-{
-    LdapConnection conn = getWiredConnection( getLdapServer() );
-
-    ManageDsaIT manageDSAIT = new ManageDsaITImpl();
-    manageDSAIT.setCritical( true );
-
-    // modify success
-    ModifyRequest modifyRequest = new ModifyRequestImpl();
-    modifyRequest.setName( new Dn( "uid=akarasuluref,ou=users,ou=system" ) );
-    modifyRequest.add( "description", "referral to akarasulu" );
-    modifyRequest.addControl( manageDSAIT );
-
-    conn.modify( modifyRequest );
-
-    assertTrue( conn.compare( "uid=akarasuluref,ou=users,ou=system", "description", "referral to akarasulu" ) );
-
-    conn.close();
-}
-
-
-/**
- * Tests modify operation on referral entries without the 
- * ManageDsaIT control. Referrals are sent back to the client with a
- * non-success result code.
- */
-@Test
-public void testOnReferral() throws Exception
-{
-    LdapConnection conn = getWiredConnection( getLdapServer() );
-
-    // referrals failure
-    // modify success
-    ModifyRequest modifyRequest = new ModifyRequestImpl();
-    modifyRequest.setName( new Dn( "uid=akarasuluref,ou=users,ou=system" ) );
-    modifyRequest.add( "description", "referral to akarasulu" );
-
-    ModifyResponse modifyResponse = conn.modify( modifyRequest );
-
-    assertEquals( ResultCodeEnum.REFERRAL, modifyResponse.getLdapResult().getResultCode() );
-
-    assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system" ) );
-    assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://foo:10389/uid=akarasulu,ou=users,ou=system" ) );
-    assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://bar:10389/uid=akarasulu,ou=users,ou=system" ) );
-
-    conn.close();
-}
-
-
-/**
- * Tests modify operation on normal and referral entries without the 
- * ManageDsaIT control using JNDI instead of the Netscape API. Referrals 
- * are sent back to the client with a non-success result code.
- */
-@Test
-public void testThrowOnReferralWithJndi() throws Exception
-{
-    LdapContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
-
-    // modify failure
-    Attribute attr = new BasicAttribute( "description", "referral to akarasulu" );
-    ModificationItem mod = new ModificationItem( DirContext.ADD_ATTRIBUTE, attr );
-
-    try
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    private static final Logger LOG = LoggerFactory.getLogger( CompareIT.class );
+    
+    
+    /**
+     * Tests modify operation on referral entry with the ManageDsaIT control.
+     */
+    @Test
+    public void testOnReferralWithManageDsaITControl() throws Exception
     {
-        ctx.modifyAttributes( "uid=akarasuluref,ou=users,ou=system", new ModificationItem[]
-            { mod } );
+        LdapConnection conn = getWiredConnection( getLdapServer() );
+    
+        ManageDsaIT manageDSAIT = new ManageDsaITImpl();
+        manageDSAIT.setCritical( true );
+    
+        // modify success
+        ModifyRequest modifyRequest = new ModifyRequestImpl();
+        modifyRequest.setName( new Dn( "uid=akarasuluref,ou=users,ou=system" ) );
+        modifyRequest.add( "description", "referral to akarasulu" );
+        modifyRequest.addControl( manageDSAIT );
+    
+        conn.modify( modifyRequest );
+    
+        assertTrue( conn.compare( "uid=akarasuluref,ou=users,ou=system", "description", "referral to akarasulu" ) );
+    
+        conn.close();
     }
-    catch ( ReferralException e )
+    
+    
+    /**
+     * Tests modify operation on referral entries without the
+     * ManageDsaIT control. Referrals are sent back to the client with a
+     * non-success result code.
+     */
+    @Test
+    public void testOnReferral() throws Exception
     {
-        // seems JNDI only returns the first referral URL and not all so we test for it
-        assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", e.getReferralInfo() );
+        LdapConnection conn = getWiredConnection( getLdapServer() );
+    
+        // referrals failure
+        // modify success
+        ModifyRequest modifyRequest = new ModifyRequestImpl();
+        modifyRequest.setName( new Dn( "uid=akarasuluref,ou=users,ou=system" ) );
+        modifyRequest.add( "description", "referral to akarasulu" );
+    
+        ModifyResponse modifyResponse = conn.modify( modifyRequest );
+    
+        assertEquals( ResultCodeEnum.REFERRAL, modifyResponse.getLdapResult().getResultCode() );
+    
+        assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system" ) );
+        assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://foo:10389/uid=akarasulu,ou=users,ou=system" ) );
+        assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://bar:10389/uid=akarasulu,ou=users,ou=system" ) );
+    
+        conn.close();
     }
-
-    ctx.close();
-}
-
-
-/**
- * Tests referral handling when an ancestor is a referral.
- */
-@Test
-public void testAncestorReferral() throws Exception
-{
-    LOG.debug( "" );
-
-    LdapConnection conn = getWiredConnection( getLdapServer() );
-
-    // referrals failure
-    ModifyRequest modifyRequest = new ModifyRequestImpl();
-    modifyRequest.setName( new Dn( "ou=Computers,uid=akarasuluref,ou=users,ou=system" ) );
-    modifyRequest.add( "ou", "Machines" );
-
-    ModifyResponse modifyResponse = conn.modify( modifyRequest );
-
-    assertEquals( ResultCodeEnum.REFERRAL, modifyResponse.getLdapResult().getResultCode() );
-
-    assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://localhost:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
-    assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://foo:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
-    assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://bar:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
-
-    conn.close();
-}
+    
+    
+    /**
+     * Tests modify operation on normal and referral entries without the
+     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals
+     * are sent back to the client with a non-success result code.
+     */
+    @Test
+    public void testThrowOnReferralWithJndi() throws Exception
+    {
+        LdapContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
+    
+        // modify failure
+        Attribute attr = new BasicAttribute( "description", "referral to akarasulu" );
+        ModificationItem mod = new ModificationItem( DirContext.ADD_ATTRIBUTE, attr );
+    
+        try
+        {
+            ctx.modifyAttributes( "uid=akarasuluref,ou=users,ou=system", new ModificationItem[]
+                { mod } );
+        }
+        catch ( ReferralException e )
+        {
+            // seems JNDI only returns the first referral URL and not all so we test for it
+            assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", e.getReferralInfo() );
+        }
+    
+        ctx.close();
+    }
+    
+    
+    /**
+     * Tests referral handling when an ancestor is a referral.
+     */
+    @Test
+    public void testAncestorReferral() throws Exception
+    {
+        LOG.debug( "" );
+    
+        LdapConnection conn = getWiredConnection( getLdapServer() );
+    
+        // referrals failure
+        ModifyRequest modifyRequest = new ModifyRequestImpl();
+        modifyRequest.setName( new Dn( "ou=Computers,uid=akarasuluref,ou=users,ou=system" ) );
+        modifyRequest.add( "ou", "Machines" );
+    
+        ModifyResponse modifyResponse = conn.modify( modifyRequest );
+    
+        assertEquals( ResultCodeEnum.REFERRAL, modifyResponse.getLdapResult().getResultCode() );
+    
+        assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://localhost:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
+        assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://foo:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
+        assertTrue( modifyResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://bar:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
+    
+        conn.close();
+    }
 }
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyRemoveIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyRemoveIT.java
index 579fa6f..829b3d4 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyRemoveIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyRemoveIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.modify;
 
@@ -42,12 +42,14 @@
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -77,621 +79,623 @@
 })
 public class ModifyRemoveIT extends AbstractLdapTestUnit
 {
-private static final String BASE = "ou=system";
-private static final String RDN = "cn=Tori Amos";
-
-
-/**
- * Enable the krb5kdc schema.
- */
-@Before
-public void setUp() throws Exception
-{
-    DirContext schemaRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( "ou=schema" );
-
-    // -------------------------------------------------------------------
-    // Enable the krb5kdc schema
-    // -------------------------------------------------------------------
-
-    // check if krb5kdc is disabled
-    Attributes krb5kdcAttrs = schemaRoot.getAttributes( "cn=Krb5kdc" );
-    boolean isKrb5KdcDisabled = false;
-
-    if ( krb5kdcAttrs.get( "m-disabled" ) != null )
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    private static final String BASE = "ou=system";
+    private static final String RDN = "cn=Tori Amos";
+    
+    
+    /**
+     * Enable the krb5kdc schema.
+     */
+    @Before
+    public void setUp() throws Exception
     {
-        isKrb5KdcDisabled = ( ( String ) krb5kdcAttrs.get( "m-disabled" ).get() ).equalsIgnoreCase( "TRUE" );
+        DirContext schemaRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( "ou=schema" );
+    
+        // -------------------------------------------------------------------
+        // Enable the krb5kdc schema
+        // -------------------------------------------------------------------
+    
+        // check if krb5kdc is disabled
+        Attributes krb5kdcAttrs = schemaRoot.getAttributes( "cn=Krb5kdc" );
+        boolean isKrb5KdcDisabled = false;
+    
+        if ( krb5kdcAttrs.get( "m-disabled" ) != null )
+        {
+            isKrb5KdcDisabled = ( ( String ) krb5kdcAttrs.get( "m-disabled" ).get() ).equalsIgnoreCase( "TRUE" );
+        }
+    
+        // if krb5kdc is disabled then enable it
+        if ( isKrb5KdcDisabled )
+        {
+            Attribute disabled = new BasicAttribute( "m-disabled" );
+            ModificationItem[] mods = new ModificationItem[]
+                { new ModificationItem( DirContext.REMOVE_ATTRIBUTE, disabled ) };
+            schemaRoot.modifyAttributes( "cn=Krb5kdc", mods );
+        }
     }
-
-    // if krb5kdc is disabled then enable it
-    if ( isKrb5KdcDisabled )
+    
+    
+    /**
+     * Creation of required attributes of a person entry.
+     */
+    protected Attributes getPersonAttributes( String sn, String cn )
     {
-        Attribute disabled = new BasicAttribute( "m-disabled" );
-        ModificationItem[] mods = new ModificationItem[]
-            { new ModificationItem( DirContext.REMOVE_ATTRIBUTE, disabled ) };
-        schemaRoot.modifyAttributes( "cn=Krb5kdc", mods );
+        Attributes attributes = new BasicAttributes( true );
+        Attribute attribute = new BasicAttribute( "objectClass" );
+        attribute.add( "top" );
+        attribute.add( "person" );
+        attributes.put( attribute );
+        attributes.put( "cn", cn );
+        attributes.put( "sn", sn );
+    
+        return attributes;
     }
-}
-
-
-/**
- * Creation of required attributes of a person entry.
- */
-protected Attributes getPersonAttributes( String sn, String cn )
-{
-    Attributes attributes = new BasicAttributes( true );
-    Attribute attribute = new BasicAttribute( "objectClass" );
-    attribute.add( "top" );
-    attribute.add( "person" );
-    attributes.put( attribute );
-    attributes.put( "cn", cn );
-    attributes.put( "sn", sn );
-
-    return attributes;
-}
-
-
-/**
- * Creation of required attributes of an inetOrgPerson entry.
- */
-protected Attributes getInetOrgPersonAttributes( String sn, String cn )
-{
-    Attributes attrs = new BasicAttributes( true );
-    Attribute ocls = new BasicAttribute( "objectClass" );
-    ocls.add( "top" );
-    ocls.add( "person" );
-    ocls.add( "organizationalPerson" );
-    ocls.add( "inetOrgPerson" );
-    attrs.put( ocls );
-    attrs.put( "cn", cn );
-    attrs.put( "sn", sn );
-
-    return attrs;
-}
-
-
-/**
- * Remove a value which does not exist in an attribute making sure  
- * it does not remove other values in that attribute.  Tests if the 
- * following JIRA issue is still valid:
- * 
- *    https://issues.apache.org/jira/browse/DIRSERVER-1149
- */
-@Test
-public void testRemoveAttemptWithoutChange() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Get the attributes and check the contents
-    Attributes tori = ctx.getAttributes( RDN );
-    assertNotNull( tori.get( "objectClass" ) );
-    assertNotNull( tori.get( "cn" ) );
-    assertEquals( 1, tori.get( "cn" ).size() );
-    assertEquals( "Tori Amos", tori.get( "cn" ).get() );
-    assertNotNull( tori.get( "sn" ) );
-
-    // Test an add operation first
-    ModificationItem mod = new ModificationItem( DirContext.ADD_ATTRIBUTE, new BasicAttribute( "cn", "foo" ) );
-    ctx.modifyAttributes( RDN, new ModificationItem[]
-        { mod } );
-    tori = ctx.getAttributes( RDN );
-    assertNotNull( tori.get( "objectClass" ) );
-    assertNotNull( tori.get( "cn" ) );
-    assertEquals( 2, tori.get( "cn" ).size() );
-    assertEquals( "Tori Amos", tori.get( "cn" ).get( 0 ) );
-    assertEquals( "foo", tori.get( "cn" ).get( 1 ) );
-    assertNotNull( tori.get( "sn" ) );
-
-    // Now test remove of value ( bar ) that does not exist in cn
-    mod = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, new BasicAttribute( "cn", "bar" ) );
-    try
+    
+    
+    /**
+     * Creation of required attributes of an inetOrgPerson entry.
+     */
+    protected Attributes getInetOrgPersonAttributes( String sn, String cn )
     {
+        Attributes attrs = new BasicAttributes( true );
+        Attribute ocls = new BasicAttribute( "objectClass" );
+        ocls.add( "top" );
+        ocls.add( "person" );
+        ocls.add( "organizationalPerson" );
+        ocls.add( "inetOrgPerson" );
+        attrs.put( ocls );
+        attrs.put( "cn", cn );
+        attrs.put( "sn", sn );
+    
+        return attrs;
+    }
+    
+    
+    /**
+     * Remove a value which does not exist in an attribute making sure
+     * it does not remove other values in that attribute.  Tests if the
+     * following JIRA issue is still valid:
+     * 
+     *    https://issues.apache.org/jira/browse/DIRSERVER-1149
+     */
+    @Test
+    public void testRemoveAttemptWithoutChange() throws Exception
+    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Get the attributes and check the contents
+        Attributes tori = ctx.getAttributes( RDN );
+        assertNotNull( tori.get( "objectClass" ) );
+        assertNotNull( tori.get( "cn" ) );
+        assertEquals( 1, tori.get( "cn" ).size() );
+        assertEquals( "Tori Amos", tori.get( "cn" ).get() );
+        assertNotNull( tori.get( "sn" ) );
+    
+        // Test an add operation first
+        ModificationItem mod = new ModificationItem( DirContext.ADD_ATTRIBUTE, new BasicAttribute( "cn", "foo" ) );
         ctx.modifyAttributes( RDN, new ModificationItem[]
             { mod } );
-        fail();
+        tori = ctx.getAttributes( RDN );
+        assertNotNull( tori.get( "objectClass" ) );
+        assertNotNull( tori.get( "cn" ) );
+        assertEquals( 2, tori.get( "cn" ).size() );
+        assertEquals( "Tori Amos", tori.get( "cn" ).get( 0 ) );
+        assertEquals( "foo", tori.get( "cn" ).get( 1 ) );
+        assertNotNull( tori.get( "sn" ) );
+    
+        // Now test remove of value ( bar ) that does not exist in cn
+        mod = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, new BasicAttribute( "cn", "bar" ) );
+        try
+        {
+            ctx.modifyAttributes( RDN, new ModificationItem[]
+                { mod } );
+            fail();
+        }
+        catch ( NoSuchAttributeException nsae )
+        {
+            assertTrue( true );
+        }
+    
+        tori = ctx.getAttributes( RDN );
+        assertNotNull( tori.get( "objectClass" ) );
+        assertNotNull( tori.get( "cn" ) );
+        assertEquals( 2, tori.get( "cn" ).size() );
+        assertEquals( "Tori Amos", tori.get( "cn" ).get( 0 ) );
+        assertEquals( "foo", tori.get( "cn" ).get( 1 ) );
+        assertNotNull( tori.get( "sn" ) );
     }
-    catch ( NoSuchAttributeException nsae )
+    
+    
+    /**
+     * Remove an attribute, which is not required.
+     * 
+     * Expected result: After successful deletion, attribute is not present in
+     * entry.
+     */
+    @Test
+    public void testRemoveNotRequiredAttribute() throws Exception
     {
-        assertTrue( true );
-    }
-
-    tori = ctx.getAttributes( RDN );
-    assertNotNull( tori.get( "objectClass" ) );
-    assertNotNull( tori.get( "cn" ) );
-    assertEquals( 2, tori.get( "cn" ).size() );
-    assertEquals( "Tori Amos", tori.get( "cn" ).get( 0 ) );
-    assertEquals( "foo", tori.get( "cn" ).get( 1 ) );
-    assertNotNull( tori.get( "sn" ) );
-}
-
-
-/**
- * Remove an attribute, which is not required.
- * 
- * Expected result: After successful deletion, attribute is not present in
- * entry.
- */
-@Test
-public void testRemoveNotRequiredAttribute() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Remove description Attribute
-    Attribute attr = new BasicAttribute( "description" );
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( attr );
-    ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
-
-    // Verify, that attribute is deleted
-    attrs = ctx.getAttributes( RDN );
-    attr = attrs.get( "description" );
-    assertNull( attr );
-}
-
-
-/**
- * Remove two not required attributes.
- * 
- * Expected result: After successful deletion, both attributes ar not
- * present in entry.
- */
-@Test
-public void testRemoveTwoNotRequiredAttributes() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // add telephoneNumber to entry
-    Attributes tn = new BasicAttributes( "telephoneNumber", "12345678", true );
-    ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, tn );
-
-    // Remove description and telephoneNumber to Attribute
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( new BasicAttribute( "description" ) );
-    attrs.put( new BasicAttribute( "telephoneNumber" ) );
-    ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
-
-    // Verify, that attributes are deleted
-    attrs = ctx.getAttributes( RDN );
-    assertNull( attrs.get( "description" ) );
-    assertNull( attrs.get( "telephoneNumber" ) );
-    assertNotNull( attrs.get( "cn" ) );
-    assertNotNull( attrs.get( "sn" ) );
-}
-
-
-/**
- * Remove a required attribute. The sn attribute of the person entry is used
- * here.
- * 
- * Expected Result: Deletion fails with NamingException (Schema Violation).
- */
-@Test
-public void testRemoveRequiredAttribute() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Remove sn attribute
-    Attribute attr = new BasicAttribute( "sn" );
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( attr );
-
-    try
-    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Remove description Attribute
+        Attribute attr = new BasicAttribute( "description" );
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( attr );
         ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
-        fail( "Deletion of required attribute should fail." );
+    
+        // Verify, that attribute is deleted
+        attrs = ctx.getAttributes( RDN );
+        attr = attrs.get( "description" );
+        assertNull( attr );
     }
-    catch ( SchemaViolationException e )
+    
+    
+    /**
+     * Remove two not required attributes.
+     * 
+     * Expected result: After successful deletion, both attributes ar not
+     * present in entry.
+     */
+    @Test
+    public void testRemoveTwoNotRequiredAttributes() throws Exception
     {
-        // expected behaviour
-    }
-}
-
-
-/**
- * Remove a required attribute from Rdn.
- * 
- * Expected Result: Deletion fails with SchemaViolationException.
- */
-@Test
-public void testRemovePartOfRdn() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Remove sn attribute
-    Attribute attr = new BasicAttribute( "cn" );
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( attr );
-
-    try
-    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // add telephoneNumber to entry
+        Attributes tn = new BasicAttributes( "telephoneNumber", "12345678", true );
+        ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, tn );
+    
+        // Remove description and telephoneNumber to Attribute
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( new BasicAttribute( "description" ) );
+        attrs.put( new BasicAttribute( "telephoneNumber" ) );
         ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
-        fail( "Deletion of Rdn attribute should fail." );
+    
+        // Verify, that attributes are deleted
+        attrs = ctx.getAttributes( RDN );
+        assertNull( attrs.get( "description" ) );
+        assertNull( attrs.get( "telephoneNumber" ) );
+        assertNotNull( attrs.get( "cn" ) );
+        assertNotNull( attrs.get( "sn" ) );
     }
-    catch ( SchemaViolationException e )
+    
+    
+    /**
+     * Remove a required attribute. The sn attribute of the person entry is used
+     * here.
+     * 
+     * Expected Result: Deletion fails with NamingException (Schema Violation).
+     */
+    @Test
+    public void testRemoveRequiredAttribute() throws Exception
     {
-        // expected behaviour
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Remove sn attribute
+        Attribute attr = new BasicAttribute( "sn" );
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( attr );
+    
+        try
+        {
+            ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
+            fail( "Deletion of required attribute should fail." );
+        }
+        catch ( SchemaViolationException e )
+        {
+            // expected behaviour
+        }
     }
-}
-
-
-/**
- * Remove a not required attribute from Rdn.
- * 
- * Expected Result: Deletion fails with SchemaViolationException.
- */
-@Test
-public void testRemovePartOfRdnNotRequired() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Change Rdn to another attribute
-    String newRdn = "description=an American singer-songwriter";
-    ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
-    ctx.rename( RDN, newRdn );
-
-    // Remove description, which is now Rdn attribute
-    Attribute attr = new BasicAttribute( "description" );
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( attr );
-
-    try
+    
+    
+    /**
+     * Remove a required attribute from Rdn.
+     * 
+     * Expected Result: Deletion fails with SchemaViolationException.
+     */
+    @Test
+    public void testRemovePartOfRdn() throws Exception
     {
-        ctx.modifyAttributes( newRdn, DirContext.REMOVE_ATTRIBUTE, attrs );
-        fail( "Deletion of Rdn attribute should fail." );
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Remove sn attribute
+        Attribute attr = new BasicAttribute( "cn" );
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( attr );
+    
+        try
+        {
+            ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
+            fail( "Deletion of Rdn attribute should fail." );
+        }
+        catch ( SchemaViolationException e )
+        {
+            // expected behaviour
+        }
     }
-    catch ( SchemaViolationException e )
+    
+    
+    /**
+     * Remove a not required attribute from Rdn.
+     * 
+     * Expected Result: Deletion fails with SchemaViolationException.
+     */
+    @Test
+    public void testRemovePartOfRdnNotRequired() throws Exception
     {
-        // expected behaviour
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Change Rdn to another attribute
+        String newRdn = "description=an American singer-songwriter";
+        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
+        ctx.rename( RDN, newRdn );
+    
+        // Remove description, which is now Rdn attribute
+        Attribute attr = new BasicAttribute( "description" );
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( attr );
+    
+        try
+        {
+            ctx.modifyAttributes( newRdn, DirContext.REMOVE_ATTRIBUTE, attrs );
+            fail( "Deletion of Rdn attribute should fail." );
+        }
+        catch ( SchemaViolationException e )
+        {
+            // expected behaviour
+        }
+    
+        // Change Rdn back to original
+        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
+        ctx.rename( newRdn, RDN );
     }
-
-    // Change Rdn back to original
-    ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
-    ctx.rename( newRdn, RDN );
-}
-
-
-/**
- * Remove a an attribute which is not present on the entry, but in the
- * schema.
- * 
- * Expected result: Deletion fails with NoSuchAttributeException
- */
-@Test
-public void testRemoveAttributeNotPresent() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Remove telephoneNumber Attribute
-    Attribute attr = new BasicAttribute( "telephoneNumber" );
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( attr );
-
-    try
+    
+    
+    /**
+     * Remove a an attribute which is not present on the entry, but in the
+     * schema.
+     * 
+     * Expected result: Deletion fails with NoSuchAttributeException
+     */
+    @Test
+    public void testRemoveAttributeNotPresent() throws Exception
     {
-        ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
-        fail( "Deletion of attribute, which is not present in the entry, should fail." );
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Remove telephoneNumber Attribute
+        Attribute attr = new BasicAttribute( "telephoneNumber" );
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( attr );
+    
+        try
+        {
+            ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
+            fail( "Deletion of attribute, which is not present in the entry, should fail." );
+        }
+        catch ( NoSuchAttributeException e )
+        {
+            assertTrue( true );
+            // expected behaviour
+        }
     }
-    catch ( NoSuchAttributeException e )
+    
+    
+    /**
+     * Remove a an attribute value which is not present in the entry
+     * 
+     * Expected result: Deletion fails with NoSuchAttributeException
+     */
+    @Test
+    public void testRemoveAttributeValueNotPresent() throws Exception
     {
-        assertTrue( true );
-        // expected behaviour
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Remove telephoneNumber Attribute
+        Attribute attr = new BasicAttribute( "telephoneNumber", "12345" );
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( attr );
+    
+        // Inject the new attribute
+        ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, attrs );
+    
+        // Now try to remove a value which is not present
+        Attribute attr2 = new BasicAttribute( "telephoneNumber", "7890" );
+        Attributes attrs2 = new BasicAttributes( true );
+        attrs2.put( attr2 );
+    
+        try
+        {
+            ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs2 );
+            // We should get an exception
+            fail();
+        }
+        catch ( NoSuchAttributeException nsae )
+        {
+            assertTrue( true );
+        }
     }
-}
-
-
-/**
- * Remove a an attribute value which is not present in the entry
- * 
- * Expected result: Deletion fails with NoSuchAttributeException
- */
-@Test
-public void testRemoveAttributeValueNotPresent() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Remove telephoneNumber Attribute
-    Attribute attr = new BasicAttribute( "telephoneNumber", "12345" );
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( attr );
-
-    // Inject the new attribute
-    ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, attrs );
-
-    // Now try to remove a value which is not present
-    Attribute attr2 = new BasicAttribute( "telephoneNumber", "7890" );
-    Attributes attrs2 = new BasicAttributes( true );
-    attrs2.put( attr2 );
-
-    try
+    
+    
+    /**
+     * Remove a an attribute which is not present in the schema.
+     * 
+     * Expected result: Deletion fails with NoSuchAttributeException
+     */
+    @Test
+    public void testRemoveAttributeNotValid() throws Exception
     {
-        ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs2 );
-        // We should get an exception
-        fail();
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Remove phantasy attribute
+        Attribute attr = new BasicAttribute( "XXX" );
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( attr );
+    
+        try
+        {
+            ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
+            fail( "Deletion of an invalid attribute should fail." );
+        }
+        catch ( NoSuchAttributeException e )
+        {
+            // expected behaviour
+        }
+        catch ( InvalidAttributeIdentifierException e )
+        {
+            // expected behaviour
+        }
     }
-    catch ( NoSuchAttributeException nsae )
+    
+    
+    /**
+     * Create a person entry and try to remove an attribute value
+     */
+    @Test
+    public void testReplaceNonExistingAttribute() throws Exception
     {
-        assertTrue( true );
-    }
-}
-
-
-/**
- * Remove a an attribute which is not present in the schema.
- * 
- * Expected result: Deletion fails with NoSuchAttributeException
- */
-@Test
-public void testRemoveAttributeNotValid() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Remove phantasy attribute
-    Attribute attr = new BasicAttribute( "XXX" );
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( attr );
-
-    try
-    {
-        ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
-        fail( "Deletion of an invalid attribute should fail." );
-    }
-    catch ( NoSuchAttributeException e )
-    {
-        // expected behaviour
-    }
-    catch ( InvalidAttributeIdentifierException e )
-    {
-        // expected behaviour
-    }
-}
-
-
-/**
- * Create a person entry and try to remove an attribute value
- */
-@Test
-public void testReplaceNonExistingAttribute() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Create an entry
-    Attributes attrs = getInetOrgPersonAttributes( "Bush", "Kate Bush" );
-    attrs.put( "givenname", "Kate" );
-    String rdn = "cn=Kate Bush";
-    ctx.createSubcontext( rdn, attrs );
-
-    // replace attribute givenName with empty value (=> deletion)
-    Attribute attr = new BasicAttribute( "givenname" );
-    ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
-    ctx.modifyAttributes( rdn, new ModificationItem[]
-        { item } );
-
-    SearchControls sctls = new SearchControls();
-    sctls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
-    String filter = "(cn=Kate Bush)";
-    String base = "";
-    NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
-    if ( enm.hasMore() )
-    {
-        SearchResult sr = enm.next();
-        attrs = sr.getAttributes();
-        Attribute cn = sr.getAttributes().get( "cn" );
-        assertNotNull( cn );
-        assertTrue( cn.contains( "Kate Bush" ) );
-
-        // Check whether attribute has been removed
-        Attribute givenName = sr.getAttributes().get( "givenname" );
-        assertNull( givenName );
-    }
-    else
-    {
-        fail( "entry not found" );
-    }
-
-    ctx.destroySubcontext( rdn );
-}
-
-
-/**
- * Create a person entry and try to remove an attribute value from the Rdn
- * by Replacement
- */
-@Test
-public void testReplaceRdnByEmptyValueAttribute() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Create an entry
-    Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
-    String rdn = "cn=Kate Bush";
-    ctx.createSubcontext( rdn, attrs );
-
-    // replace attribute cn with empty value (=> deletion)
-    Attribute attr = new BasicAttribute( "cn" );
-    ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
-
-    try
-    {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Create an entry
+        Attributes attrs = getInetOrgPersonAttributes( "Bush", "Kate Bush" );
+        attrs.put( "givenname", "Kate" );
+        String rdn = "cn=Kate Bush";
+        ctx.createSubcontext( rdn, attrs );
+    
+        // replace attribute givenName with empty value (=> deletion)
+        Attribute attr = new BasicAttribute( "givenname" );
+        ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
         ctx.modifyAttributes( rdn, new ModificationItem[]
             { item } );
-        fail( "modify should fail" );
+    
+        SearchControls sctls = new SearchControls();
+        sctls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+        String filter = "(cn=Kate Bush)";
+        String base = "";
+        NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
+        if ( enm.hasMore() )
+        {
+            SearchResult sr = enm.next();
+            attrs = sr.getAttributes();
+            Attribute cn = sr.getAttributes().get( "cn" );
+            assertNotNull( cn );
+            assertTrue( cn.contains( "Kate Bush" ) );
+    
+            // Check whether attribute has been removed
+            Attribute givenName = sr.getAttributes().get( "givenname" );
+            assertNull( givenName );
+        }
+        else
+        {
+            fail( "entry not found" );
+        }
+    
+        ctx.destroySubcontext( rdn );
     }
-    catch ( SchemaViolationException e )
+    
+    
+    /**
+     * Create a person entry and try to remove an attribute value from the Rdn
+     * by Replacement
+     */
+    @Test
+    public void testReplaceRdnByEmptyValueAttribute() throws Exception
     {
-        // Expected behaviour
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Create an entry
+        Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
+        String rdn = "cn=Kate Bush";
+        ctx.createSubcontext( rdn, attrs );
+    
+        // replace attribute cn with empty value (=> deletion)
+        Attribute attr = new BasicAttribute( "cn" );
+        ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
+    
+        try
+        {
+            ctx.modifyAttributes( rdn, new ModificationItem[]
+                { item } );
+            fail( "modify should fail" );
+        }
+        catch ( SchemaViolationException e )
+        {
+            // Expected behaviour
+        }
+    
+        ctx.destroySubcontext( rdn );
     }
-
-    ctx.destroySubcontext( rdn );
-}
-
-
-/**
- * Create a person entry and try to remove an attribute from the Rdn
- */
-@Test
-public void testRemoveRdnAttribute() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Create an entry
-    Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
-    String rdn = "cn=Kate Bush";
-    ctx.createSubcontext( rdn, attrs );
-
-    // replace attribute cn with empty value (=> deletion)
-    Attribute attr = new BasicAttribute( "cn" );
-    ModificationItem item = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, attr );
-
-    try
+    
+    
+    /**
+     * Create a person entry and try to remove an attribute from the Rdn
+     */
+    @Test
+    public void testRemoveRdnAttribute() throws Exception
     {
-        ctx.modifyAttributes( rdn, new ModificationItem[]
-            { item } );
-        fail( "modify should fail" );
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Create an entry
+        Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
+        String rdn = "cn=Kate Bush";
+        ctx.createSubcontext( rdn, attrs );
+    
+        // replace attribute cn with empty value (=> deletion)
+        Attribute attr = new BasicAttribute( "cn" );
+        ModificationItem item = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, attr );
+    
+        try
+        {
+            ctx.modifyAttributes( rdn, new ModificationItem[]
+                { item } );
+            fail( "modify should fail" );
+        }
+        catch ( SchemaViolationException e )
+        {
+            // Expected behaviour
+        }
+    
+        ctx.destroySubcontext( rdn );
     }
-    catch ( SchemaViolationException e )
+    
+    
+    /**
+     * Create a person entry and try to remove an attribute from the Rdn
+     */
+    @Test
+    public void testRemoveRdnAttributeValue() throws Exception
     {
-        // Expected behaviour
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Create an entry
+        Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
+        String rdn = "cn=Kate Bush";
+        ctx.createSubcontext( rdn, attrs );
+    
+        // replace attribute cn with empty value (=> deletion)
+        Attribute attr = new BasicAttribute( "cn", "Kate Bush" );
+        ModificationItem item = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, attr );
+    
+        try
+        {
+            ctx.modifyAttributes( rdn, new ModificationItem[]
+                { item } );
+            fail( "modify should fail" );
+        }
+        catch ( SchemaViolationException e )
+        {
+            // Expected behaviour
+        }
+    
+        ctx.destroySubcontext( rdn );
     }
-
-    ctx.destroySubcontext( rdn );
-}
-
-
-/**
- * Create a person entry and try to remove an attribute from the Rdn
- */
-@Test
-public void testRemoveRdnAttributeValue() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Create an entry
-    Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
-    String rdn = "cn=Kate Bush";
-    ctx.createSubcontext( rdn, attrs );
-
-    // replace attribute cn with empty value (=> deletion)
-    Attribute attr = new BasicAttribute( "cn", "Kate Bush" );
-    ModificationItem item = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, attr );
-
-    try
+    
+    
+    /**
+     * Create a person entry and try to remove objectClass attribute
+     */
+    @Test
+    public void testDeleteOclAttrWithTopPersonOrganizationalpersonInetorgperson() throws Exception
     {
-        ctx.modifyAttributes( rdn, new ModificationItem[]
-            { item } );
-        fail( "modify should fail" );
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Create an entry
+        Attributes attrs = getInetOrgPersonAttributes( "Bush", "Kate Bush" );
+        String rdn = "cn=Kate Bush";
+        ctx.createSubcontext( rdn, attrs );
+    
+        ModificationItem delModOp = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, new BasicAttribute( "objectclass",
+            "" ) );
+    
+        try
+        {
+            ctx.modifyAttributes( rdn, new ModificationItem[]
+                { delModOp } );
+            fail( "deletion of objectclass should fail" );
+        }
+        catch ( SchemaViolationException e )
+        {
+            // expected
+        }
+        catch ( NoSuchAttributeException e )
+        {
+            // expected
+        }
+        catch ( InvalidAttributeValueException e )
+        {
+            // expected
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+        }
+    
+        ctx.destroySubcontext( rdn );
     }
-    catch ( SchemaViolationException e )
+    
+    
+    /**
+     * Create a person entry and try to remove objectClass attribute. A variant
+     * which works.
+     */
+    @Test
+    public void testDeleteOclAttrWithTopPersonOrganizationalpersonInetorgpersonVariant() throws Exception
     {
-        // Expected behaviour
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // Create an entry
+        Attributes attrs = getInetOrgPersonAttributes( "Bush", "Kate Bush" );
+        String rdn = "cn=Kate Bush";
+        ctx.createSubcontext( rdn, attrs );
+    
+        ModificationItem delModOp = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, new BasicAttribute( "objectclass" ) );
+    
+        try
+        {
+            ctx.modifyAttributes( rdn, new ModificationItem[]
+                { delModOp } );
+            fail( "deletion of objectclass should fail" );
+        }
+        catch ( SchemaViolationException e )
+        {
+            // expected
+        }
+    
+        ctx.destroySubcontext( rdn );
     }
-
-    ctx.destroySubcontext( rdn );
-}
-
-
-/**
- * Create a person entry and try to remove objectClass attribute
- */
-@Test
-public void testDeleteOclAttrWithTopPersonOrganizationalpersonInetorgperson() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Create an entry
-    Attributes attrs = getInetOrgPersonAttributes( "Bush", "Kate Bush" );
-    String rdn = "cn=Kate Bush";
-    ctx.createSubcontext( rdn, attrs );
-
-    ModificationItem delModOp = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, new BasicAttribute( "objectclass",
-        "" ) );
-
-    try
+    
+    
+    /**
+     * Test for DIRSERVER-1308:
+     * Remove an objectClass and a mandatory attribute.
+     * 
+     * Expected result: After successful deletion, both the objectClass
+     * and the attribute are not present in entry.
+     */
+    @Test
+    public void testRemoveObjectClassAndMandatoryAttribute() throws Exception
     {
-        ctx.modifyAttributes( rdn, new ModificationItem[]
-            { delModOp } );
-        fail( "deletion of objectclass should fail" );
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        // add objectClass:krb5Principal and krb5PrincipalName:test to entry
+        Attributes tn = new BasicAttributes( true );
+        tn.put( new BasicAttribute( "objectClass", "krb5Principal", true ) );
+        tn.put( new BasicAttribute( "krb5PrincipalName", "test", true ) );
+        ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, tn );
+    
+        // remove objectClass:krb5Principal and krb5PrincipalName
+        Attributes attrs = new BasicAttributes( true );
+        attrs.put( new BasicAttribute( "objectClass", "krb5Principal", true ) );
+        attrs.put( new BasicAttribute( "krb5PrincipalName" ) );
+        ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
+    
+        // Verify, that attributes are deleted
+        attrs = ctx.getAttributes( RDN );
+        assertNotNull( attrs.get( "objectClass" ) );
+        assertFalse( attrs.get( "objectClass" ).contains( "krb5Principal" ) );
+        assertNull( attrs.get( "krb5PrincipalName" ) );
+        assertNotNull( attrs.get( "cn" ) );
+        assertNotNull( attrs.get( "sn" ) );
     }
-    catch ( SchemaViolationException e )
-    {
-        // expected
-    }
-    catch ( NoSuchAttributeException e )
-    {
-        // expected
-    }
-    catch ( InvalidAttributeValueException e )
-    {
-        // expected
-    }
-    catch ( Exception e )
-    {
-        e.printStackTrace();
-    }
-
-    ctx.destroySubcontext( rdn );
-}
-
-
-/**
- * Create a person entry and try to remove objectClass attribute. A variant
- * which works.
- */
-@Test
-public void testDeleteOclAttrWithTopPersonOrganizationalpersonInetorgpersonVariant() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // Create an entry
-    Attributes attrs = getInetOrgPersonAttributes( "Bush", "Kate Bush" );
-    String rdn = "cn=Kate Bush";
-    ctx.createSubcontext( rdn, attrs );
-
-    ModificationItem delModOp = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, new BasicAttribute( "objectclass" ) );
-
-    try
-    {
-        ctx.modifyAttributes( rdn, new ModificationItem[]
-            { delModOp } );
-        fail( "deletion of objectclass should fail" );
-    }
-    catch ( SchemaViolationException e )
-    {
-        // expected
-    }
-
-    ctx.destroySubcontext( rdn );
-}
-
-
-/**
- * Test for DIRSERVER-1308:
- * Remove an objectClass and a mandatory attribute.
- * 
- * Expected result: After successful deletion, both the objectClass
- * and the attribute are not present in entry.
- */
-@Test
-public void testRemoveObjectClassAndMandatoryAttribute() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    // add objectClass:krb5Principal and krb5PrincipalName:test to entry
-    Attributes tn = new BasicAttributes( true );
-    tn.put( new BasicAttribute( "objectClass", "krb5Principal", true ) );
-    tn.put( new BasicAttribute( "krb5PrincipalName", "test", true ) );
-    ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, tn );
-
-    // remove objectClass:krb5Principal and krb5PrincipalName
-    Attributes attrs = new BasicAttributes( true );
-    attrs.put( new BasicAttribute( "objectClass", "krb5Principal", true ) );
-    attrs.put( new BasicAttribute( "krb5PrincipalName" ) );
-    ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, attrs );
-
-    // Verify, that attributes are deleted
-    attrs = ctx.getAttributes( RDN );
-    assertNotNull( attrs.get( "objectClass" ) );
-    assertFalse( attrs.get( "objectClass" ).contains( "krb5Principal" ) );
-    assertNull( attrs.get( "krb5PrincipalName" ) );
-    assertNotNull( attrs.get( "cn" ) );
-    assertNotNull( attrs.get( "sn" ) );
-}
 }
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyReplaceIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyReplaceIT.java
index 28a7dbf..067bbee 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyReplaceIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyReplaceIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.modify;
 
@@ -39,12 +39,14 @@
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
 import org.apache.directory.server.core.annotations.CreateDS;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -83,245 +85,247 @@
 })
 public class ModifyReplaceIT extends AbstractLdapTestUnit
 {
-private static final String BASE = "ou=system";
-
-
-/**
- * Create a person entry and try to remove a not present attribute
- */
-@Test
-public void testReplaceToRemoveNotPresentAttribute() throws Exception
-{
-    DirContext sysRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    String rdn = "cn=Kate Bush";
-
-    Attribute attr = new BasicAttribute( "description" );
-    ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
-
-    sysRoot.modifyAttributes( rdn, new ModificationItem[]
-        { item } );
-
-    SearchControls sctls = new SearchControls();
-    sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-    String filter = "(sn=Bush)";
-    String base = "";
-
-    NamingEnumeration<SearchResult> enm = sysRoot.search( base, filter, sctls );
-
-    while ( enm.hasMore() )
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    private static final String BASE = "ou=system";
+    
+    
+    /**
+     * Create a person entry and try to remove a not present attribute
+     */
+    @Test
+    public void testReplaceToRemoveNotPresentAttribute() throws Exception
     {
-        SearchResult sr = ( SearchResult ) enm.next();
-        Attribute cn = sr.getAttributes().get( "cn" );
-        assertNotNull( cn );
-        assertTrue( cn.contains( "Kate Bush" ) );
-        Attribute desc = sr.getAttributes().get( "description" );
-        assertNull( desc );
-    }
-}
-
-
-/**
- * Create a person entry and try to add a not present attribute via a REPLACE
- */
-@Test
-public void testReplaceToAddNotPresentAttribute() throws Exception
-{
-    DirContext sysRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    String rdn = "cn=Kate Bush";
-
-    Attribute attr = new BasicAttribute( "description", "added description" );
-    ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
-
-    sysRoot.modifyAttributes( rdn, new ModificationItem[]
-        { item } );
-
-    SearchControls sctls = new SearchControls();
-    sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-    String filter = "(sn=Bush)";
-    String base = "";
-
-    NamingEnumeration<SearchResult> enm = sysRoot.search( base, filter, sctls );
-
-    while ( enm.hasMore() )
-    {
-        SearchResult sr = ( SearchResult ) enm.next();
-        Attribute cn = sr.getAttributes().get( "cn" );
-        assertNotNull( cn );
-        assertTrue( cn.contains( "Kate Bush" ) );
-        Attribute desc = sr.getAttributes().get( "description" );
-        assertNotNull( desc );
-        assertTrue( desc.contains( "added description" ) );
-        assertEquals( 1, desc.size() );
-    }
-}
-
-
-/**
- * Create a person entry and try to remove a non existing attribute
- */
-@Test
-public void testReplaceNonExistingAttribute() throws Exception
-{
-    DirContext sysRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    String rdn = "cn=Kate Bush";
-
-    Attribute attr = new BasicAttribute( "numberOfOctaves" );
-    ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
-
-    try
-    {
+        DirContext sysRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        String rdn = "cn=Kate Bush";
+    
+        Attribute attr = new BasicAttribute( "description" );
+        ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
+    
         sysRoot.modifyAttributes( rdn, new ModificationItem[]
             { item } );
-        fail();
+    
+        SearchControls sctls = new SearchControls();
+        sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+        String filter = "(sn=Bush)";
+        String base = "";
+    
+        NamingEnumeration<SearchResult> enm = sysRoot.search( base, filter, sctls );
+    
+        while ( enm.hasMore() )
+        {
+            SearchResult sr = enm.next();
+            Attribute cn = sr.getAttributes().get( "cn" );
+            assertNotNull( cn );
+            assertTrue( cn.contains( "Kate Bush" ) );
+            Attribute desc = sr.getAttributes().get( "description" );
+            assertNull( desc );
+        }
     }
-    catch ( InvalidAttributeIdentifierException iaie )
+    
+    
+    /**
+     * Create a person entry and try to add a not present attribute via a REPLACE
+     */
+    @Test
+    public void testReplaceToAddNotPresentAttribute() throws Exception
     {
-        assertTrue( true );
-    }
-
-    SearchControls sctls = new SearchControls();
-    sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-    String filter = "(sn=Bush)";
-    String base = "";
-
-    NamingEnumeration<SearchResult> enm = sysRoot.search( base, filter, sctls );
-
-    while ( enm.hasMore() )
-    {
-        SearchResult sr = enm.next();
-        Attribute cn = sr.getAttributes().get( "cn" );
-        assertNotNull( cn );
-        assertTrue( cn.contains( "Kate Bush" ) );
-    }
-}
-
-
-/**
- * Create a person entry and try to remove a non existing attribute
- */
-@Test
-public void testReplaceNonExistingAttributeManyMods() throws Exception
-{
-    DirContext sysRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    String rdn = "cn=Kate Bush";
-
-    Attribute attr = new BasicAttribute( "numberOfOctaves" );
-    ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
-    Attribute attr2 = new BasicAttribute( "description", "blah blah blah" );
-    ModificationItem item2 = new ModificationItem( DirContext.ADD_ATTRIBUTE, attr2 );
-
-    try
-    {
+        DirContext sysRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        String rdn = "cn=Kate Bush";
+    
+        Attribute attr = new BasicAttribute( "description", "added description" );
+        ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
+    
         sysRoot.modifyAttributes( rdn, new ModificationItem[]
-            { item, item2 } );
-        fail();
+            { item } );
+    
+        SearchControls sctls = new SearchControls();
+        sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+        String filter = "(sn=Bush)";
+        String base = "";
+    
+        NamingEnumeration<SearchResult> enm = sysRoot.search( base, filter, sctls );
+    
+        while ( enm.hasMore() )
+        {
+            SearchResult sr = enm.next();
+            Attribute cn = sr.getAttributes().get( "cn" );
+            assertNotNull( cn );
+            assertTrue( cn.contains( "Kate Bush" ) );
+            Attribute desc = sr.getAttributes().get( "description" );
+            assertNotNull( desc );
+            assertTrue( desc.contains( "added description" ) );
+            assertEquals( 1, desc.size() );
+        }
     }
-    catch ( InvalidAttributeIdentifierException iaie )
+    
+    
+    /**
+     * Create a person entry and try to remove a non existing attribute
+     */
+    @Test
+    public void testReplaceNonExistingAttribute() throws Exception
     {
-        assertTrue( true );
+        DirContext sysRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        String rdn = "cn=Kate Bush";
+    
+        Attribute attr = new BasicAttribute( "numberOfOctaves" );
+        ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
+    
+        try
+        {
+            sysRoot.modifyAttributes( rdn, new ModificationItem[]
+                { item } );
+            fail();
+        }
+        catch ( InvalidAttributeIdentifierException iaie )
+        {
+            assertTrue( true );
+        }
+    
+        SearchControls sctls = new SearchControls();
+        sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+        String filter = "(sn=Bush)";
+        String base = "";
+    
+        NamingEnumeration<SearchResult> enm = sysRoot.search( base, filter, sctls );
+    
+        while ( enm.hasMore() )
+        {
+            SearchResult sr = enm.next();
+            Attribute cn = sr.getAttributes().get( "cn" );
+            assertNotNull( cn );
+            assertTrue( cn.contains( "Kate Bush" ) );
+        }
     }
-
-    SearchControls sctls = new SearchControls();
-    sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-    String filter = "(sn=Bush)";
-    String base = "";
-
-    NamingEnumeration<SearchResult> enm = sysRoot.search( base, filter, sctls );
-    while ( enm.hasMore() )
+    
+    
+    /**
+     * Create a person entry and try to remove a non existing attribute
+     */
+    @Test
+    public void testReplaceNonExistingAttributeManyMods() throws Exception
     {
-        SearchResult sr = enm.next();
-        Attribute cn = sr.getAttributes().get( "cn" );
-        assertNotNull( cn );
-        assertTrue( cn.contains( "Kate Bush" ) );
+        DirContext sysRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        String rdn = "cn=Kate Bush";
+    
+        Attribute attr = new BasicAttribute( "numberOfOctaves" );
+        ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
+        Attribute attr2 = new BasicAttribute( "description", "blah blah blah" );
+        ModificationItem item2 = new ModificationItem( DirContext.ADD_ATTRIBUTE, attr2 );
+    
+        try
+        {
+            sysRoot.modifyAttributes( rdn, new ModificationItem[]
+                { item, item2 } );
+            fail();
+        }
+        catch ( InvalidAttributeIdentifierException iaie )
+        {
+            assertTrue( true );
+        }
+    
+        SearchControls sctls = new SearchControls();
+        sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+        String filter = "(sn=Bush)";
+        String base = "";
+    
+        NamingEnumeration<SearchResult> enm = sysRoot.search( base, filter, sctls );
+        while ( enm.hasMore() )
+        {
+            SearchResult sr = enm.next();
+            Attribute cn = sr.getAttributes().get( "cn" );
+            assertNotNull( cn );
+            assertTrue( cn.contains( "Kate Bush" ) );
+        }
     }
-}
-
-
-/**
- * Create a person entry and try to replace a non existing indexed attribute
- */
-@Test
-public void testReplaceNonExistingIndexedAttribute() throws Exception
-{
-    DirContext sysRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-
-    String rdn = "cn=Kim Wilde";
-
-    Attribute attr = new BasicAttribute( "ou", "test" );
-    ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
-
-    sysRoot.modifyAttributes( rdn, new ModificationItem[]
-        { item } );
-
-    SearchControls sctls = new SearchControls();
-    sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-    String filter = "(sn=Wilde)";
-    String base = "";
-
-    NamingEnumeration<SearchResult> enm = sysRoot.search( base, filter, sctls );
-
-    while ( enm.hasMore() )
+    
+    
+    /**
+     * Create a person entry and try to replace a non existing indexed attribute
+     */
+    @Test
+    public void testReplaceNonExistingIndexedAttribute() throws Exception
     {
-        SearchResult sr = enm.next();
-        Attribute ou = sr.getAttributes().get( "ou" );
-        assertNotNull( ou );
-        assertTrue( ou.contains( "test" ) );
+        DirContext sysRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+    
+        String rdn = "cn=Kim Wilde";
+    
+        Attribute attr = new BasicAttribute( "ou", "test" );
+        ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
+    
+        sysRoot.modifyAttributes( rdn, new ModificationItem[]
+            { item } );
+    
+        SearchControls sctls = new SearchControls();
+        sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+        String filter = "(sn=Wilde)";
+        String base = "";
+    
+        NamingEnumeration<SearchResult> enm = sysRoot.search( base, filter, sctls );
+    
+        while ( enm.hasMore() )
+        {
+            SearchResult sr = enm.next();
+            Attribute ou = sr.getAttributes().get( "ou" );
+            assertNotNull( ou );
+            assertTrue( ou.contains( "test" ) );
+        }
     }
-}
-
-
-/**
- * Create a person entry, replace telephoneNumber, verify the 
- * case of the attribute description attribute.
- */
-@Test
-public void testReplaceCaseOfAttributeDescription() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-    String rdn = "cn=Kate Bush";
-
-    // Replace telephoneNumber
-    String newValue = "2345678901";
-    Attributes attrs = new BasicAttributes( "telephoneNumber", newValue, false );
-    ctx.modifyAttributes( rdn, DirContext.REPLACE_ATTRIBUTE, attrs );
-
-    // Verify, that
-    // - case of attribute description is correct
-    // - attribute value is added 
-    attrs = ctx.getAttributes( rdn );
-    Attribute attr = attrs.get( "telephoneNumber" );
-    assertNotNull( attr );
-    assertEquals( "telephoneNumber", attr.getID() );
-    assertTrue( attr.contains( newValue ) );
-    assertEquals( 1, attr.size() );
-}
-
-
-/**
- * Create a person entry, replace an attribute not present in the ObjectClasses
- */
-@Test
-public void testReplaceAttributeNotInOC() throws Exception
-{
-    DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-    String rdn = "cn=Kate Bush";
-
-    // Replace ou
-    String newValue = "Test";
-    Attributes attrs = new BasicAttributes( "ou", newValue, false );
-
-    try
+    
+    
+    /**
+     * Create a person entry, replace telephoneNumber, verify the
+     * case of the attribute description attribute.
+     */
+    @Test
+    public void testReplaceCaseOfAttributeDescription() throws Exception
     {
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+        String rdn = "cn=Kate Bush";
+    
+        // Replace telephoneNumber
+        String newValue = "2345678901";
+        Attributes attrs = new BasicAttributes( "telephoneNumber", newValue, false );
         ctx.modifyAttributes( rdn, DirContext.REPLACE_ATTRIBUTE, attrs );
-        fail( "Should get a SchemaViolationException" );
+    
+        // Verify, that
+        // - case of attribute description is correct
+        // - attribute value is added
+        attrs = ctx.getAttributes( rdn );
+        Attribute attr = attrs.get( "telephoneNumber" );
+        assertNotNull( attr );
+        assertEquals( "telephoneNumber", attr.getID() );
+        assertTrue( attr.contains( newValue ) );
+        assertEquals( 1, attr.size() );
     }
-    catch ( SchemaViolationException sve )
+    
+    
+    /**
+     * Create a person entry, replace an attribute not present in the ObjectClasses
+     */
+    @Test
+    public void testReplaceAttributeNotInOC() throws Exception
     {
-        assertTrue( true );
+        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+        String rdn = "cn=Kate Bush";
+    
+        // Replace ou
+        String newValue = "Test";
+        Attributes attrs = new BasicAttributes( "ou", newValue, false );
+    
+        try
+        {
+            ctx.modifyAttributes( rdn, DirContext.REPLACE_ATTRIBUTE, attrs );
+            fail( "Should get a SchemaViolationException" );
+        }
+        catch ( SchemaViolationException sve )
+        {
+            assertTrue( true );
+        }
     }
 }
-}
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyDnReferralIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyDnReferralIT.java
index 3bc5a9f..f59479c 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyDnReferralIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyDnReferralIT.java
@@ -30,6 +30,7 @@
 import javax.naming.ReferralException;
 import javax.naming.ldap.LdapContext;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -47,6 +48,7 @@
 import org.apache.directory.shared.ldap.model.message.controls.ManageDsaITImpl;
 import org.apache.directory.shared.ldap.model.name.Dn;
 import org.apache.directory.shared.ldap.model.name.Rdn;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
@@ -104,204 +106,206 @@
 })
 public class ModifyDnReferralIT extends AbstractLdapTestUnit
 {
-private static final Logger LOG = LoggerFactory.getLogger( ModifyDnReferralIT.class );
-
-
-/**
- * Tests ModifyDN operation on referral entry with the ManageDsaIT control.
- */
-@Test
-public void testOnReferralWithManageDsaITControl() throws Exception
-{
-    LdapConnection conn = getWiredConnection( getLdapServer() );
-
-    ManageDsaIT manageDSAIT = new ManageDsaITImpl();
-    manageDSAIT.setCritical( true );
-
-    // ModifyDN success
-    ModifyDnRequest modifyDnRequest = new ModifyDnRequestImpl();
-    modifyDnRequest.setName( new Dn( "uid=akarasuluref,ou=users,ou=system" ) );
-    modifyDnRequest.setNewRdn( new Rdn( "uid=ref" ) );
-    modifyDnRequest.setDeleteOldRdn( true );
-    modifyDnRequest.addControl( manageDSAIT );
-
-    conn.modifyDn( modifyDnRequest );
-    Entry entry = conn.lookup( "uid=ref,ou=users,ou=system", new Control[]
-        { manageDSAIT } );
-    assertNotNull( entry );
-    assertEquals( "uid=ref,ou=users,ou=system", entry.getDn().getName() );
-
-    conn.close();
-}
-
-
-/**
- * Tests ModifyDN operation with newSuperior on referral entry with the 
- * ManageDsaIT control.
- */
-@Test
-public void testNewSuperiorOnReferralWithManageDsaITControl() throws Exception
-{
-    LdapConnection conn = getWiredConnection( getLdapServer() );
-
-    ManageDsaIT manageDSAIT = new ManageDsaITImpl();
-    manageDSAIT.setCritical( true );
-
-    ModifyDnRequest modifyDnRequest = new ModifyDnRequestImpl();
-    modifyDnRequest.setName( new Dn( "uid=elecharny,ou=users,ou=system" ) );
-    modifyDnRequest.setNewRdn( new Rdn( "uid=newuser" ) );
-    modifyDnRequest.setNewSuperior( new Dn( "uid=akarasuluref,ou=users,ou=system" ) );
-    modifyDnRequest.setDeleteOldRdn( true );
-    modifyDnRequest.addControl( manageDSAIT );
-
-    // ModifyDN success
-    try
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    private static final Logger LOG = LoggerFactory.getLogger( ModifyDnReferralIT.class );
+    
+    
+    /**
+     * Tests ModifyDN operation on referral entry with the ManageDsaIT control.
+     */
+    @Test
+    public void testOnReferralWithManageDsaITControl() throws Exception
     {
+        LdapConnection conn = getWiredConnection( getLdapServer() );
+    
+        ManageDsaIT manageDSAIT = new ManageDsaITImpl();
+        manageDSAIT.setCritical( true );
+    
+        // ModifyDN success
+        ModifyDnRequest modifyDnRequest = new ModifyDnRequestImpl();
+        modifyDnRequest.setName( new Dn( "uid=akarasuluref,ou=users,ou=system" ) );
+        modifyDnRequest.setNewRdn( new Rdn( "uid=ref" ) );
+        modifyDnRequest.setDeleteOldRdn( true );
+        modifyDnRequest.addControl( manageDSAIT );
+    
         conn.modifyDn( modifyDnRequest );
+        Entry entry = conn.lookup( "uid=ref,ou=users,ou=system", new Control[]
+            { manageDSAIT } );
+        assertNotNull( entry );
+        assertEquals( "uid=ref,ou=users,ou=system", entry.getDn().getName() );
+    
+        conn.close();
     }
-    catch ( LdapOperationException le )
+    
+    
+    /**
+     * Tests ModifyDN operation with newSuperior on referral entry with the
+     * ManageDsaIT control.
+     */
+    @Test
+    public void testNewSuperiorOnReferralWithManageDsaITControl() throws Exception
     {
-        assertEquals( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS, le.getResultCode() );
+        LdapConnection conn = getWiredConnection( getLdapServer() );
+    
+        ManageDsaIT manageDSAIT = new ManageDsaITImpl();
+        manageDSAIT.setCritical( true );
+    
+        ModifyDnRequest modifyDnRequest = new ModifyDnRequestImpl();
+        modifyDnRequest.setName( new Dn( "uid=elecharny,ou=users,ou=system" ) );
+        modifyDnRequest.setNewRdn( new Rdn( "uid=newuser" ) );
+        modifyDnRequest.setNewSuperior( new Dn( "uid=akarasuluref,ou=users,ou=system" ) );
+        modifyDnRequest.setDeleteOldRdn( true );
+        modifyDnRequest.addControl( manageDSAIT );
+    
+        // ModifyDN success
+        try
+        {
+            conn.modifyDn( modifyDnRequest );
+        }
+        catch ( LdapOperationException le )
+        {
+            assertEquals( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS, le.getResultCode() );
+        }
+    
+        conn.close();
     }
-
-    conn.close();
-}
-
-
-/**
- * Tests ModifyDN operation on normal and referral entries without the 
- * ManageDsaIT control. Referrals are sent back to the client with a
- * non-success result code.
- */
-@Test
-public void testOnReferral() throws Exception
-{
-    LdapConnection conn = getWiredConnection( getLdapServer() );
-
-    // referrals failure
-    ModifyDnRequest modifyDnRequest = new ModifyDnRequestImpl();
-    modifyDnRequest.setName( new Dn( "uid=akarasuluref,ou=users,ou=system" ) );
-    modifyDnRequest.setNewRdn( new Rdn( "uid=ref" ) );
-    modifyDnRequest.setDeleteOldRdn( true );
-
-    ModifyDnResponse modifyDnResponse = conn.modifyDn( modifyDnRequest );
-
-    assertEquals( ResultCodeEnum.REFERRAL, modifyDnResponse.getLdapResult().getResultCode() );
-
-    assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system" ) );
-    assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://foo:10389/uid=akarasulu,ou=users,ou=system" ) );
-    assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://bar:10389/uid=akarasulu,ou=users,ou=system" ) );
-
-    conn.close();
-}
-
-
-/**
- * Tests ModifyDN operation on normal and referral entries without the 
- * ManageDsaIT control. Referrals are sent back to the client with a
- * non-success result code.
- */
-@Test
-public void testNewSuperiorOnReferral() throws Exception
-{
-    LdapConnection conn = getWiredConnection( getLdapServer() );
-
-    // referrals failure
-    try
+    
+    
+    /**
+     * Tests ModifyDN operation on normal and referral entries without the
+     * ManageDsaIT control. Referrals are sent back to the client with a
+     * non-success result code.
+     */
+    @Test
+    public void testOnReferral() throws Exception
     {
-        conn.moveAndRename( "uid=elecharny,ou=users,ou=system", "uid=ref,uid=akarasuluref,ou=users,ou=system", true );
+        LdapConnection conn = getWiredConnection( getLdapServer() );
+    
+        // referrals failure
+        ModifyDnRequest modifyDnRequest = new ModifyDnRequestImpl();
+        modifyDnRequest.setName( new Dn( "uid=akarasuluref,ou=users,ou=system" ) );
+        modifyDnRequest.setNewRdn( new Rdn( "uid=ref" ) );
+        modifyDnRequest.setDeleteOldRdn( true );
+    
+        ModifyDnResponse modifyDnResponse = conn.modifyDn( modifyDnRequest );
+    
+        assertEquals( ResultCodeEnum.REFERRAL, modifyDnResponse.getLdapResult().getResultCode() );
+    
+        assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system" ) );
+        assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://foo:10389/uid=akarasulu,ou=users,ou=system" ) );
+        assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://bar:10389/uid=akarasulu,ou=users,ou=system" ) );
+    
+        conn.close();
     }
-    catch ( LdapOperationException e )
+    
+    
+    /**
+     * Tests ModifyDN operation on normal and referral entries without the
+     * ManageDsaIT control. Referrals are sent back to the client with a
+     * non-success result code.
+     */
+    @Test
+    public void testNewSuperiorOnReferral() throws Exception
     {
-        assertEquals( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS, e.getResultCode() );
+        LdapConnection conn = getWiredConnection( getLdapServer() );
+    
+        // referrals failure
+        try
+        {
+            conn.moveAndRename( "uid=elecharny,ou=users,ou=system", "uid=ref,uid=akarasuluref,ou=users,ou=system", true );
+        }
+        catch ( LdapOperationException e )
+        {
+            assertEquals( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS, e.getResultCode() );
+        }
+    
+        conn.close();
     }
-
-    conn.close();
-}
-
-
-/**
- * Tests ModifyDN operation on normal and referral entries without the 
- * ManageDsaIT control using JNDI instead of the Netscape API. Referrals 
- * are sent back to the client with a non-success result code.
- */
-@Test
-public void testThrowOnReferralWithJndi() throws Exception
-{
-    LdapContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
-
-    // ModifyDN referrals failure
-    try
+    
+    
+    /**
+     * Tests ModifyDN operation on normal and referral entries without the
+     * ManageDsaIT control using JNDI instead of the Netscape API. Referrals
+     * are sent back to the client with a non-success result code.
+     */
+    @Test
+    public void testThrowOnReferralWithJndi() throws Exception
     {
-        ctx.rename( "uid=akarasuluref,ou=users,ou=system", "uid=ref,ou=users,ou=system" );
-        fail( "Should never get here due to ModifyDN failure on ReferralException" );
+        LdapContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
+    
+        // ModifyDN referrals failure
+        try
+        {
+            ctx.rename( "uid=akarasuluref,ou=users,ou=system", "uid=ref,ou=users,ou=system" );
+            fail( "Should never get here due to ModifyDN failure on ReferralException" );
+        }
+        catch ( ReferralException e )
+        {
+            // seems JNDI only returns the first referral URL and not all so we test for it
+            assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", e.getReferralInfo() );
+        }
+    
+        ctx.close();
     }
-    catch ( ReferralException e )
+    
+    
+    /**
+     * Tests referral handling when an ancestor is a referral.
+     */
+    @Test
+    public void testAncestorReferral() throws Exception
     {
-        // seems JNDI only returns the first referral URL and not all so we test for it
-        assertEquals( "ldap://localhost:10389/uid=akarasulu,ou=users,ou=system", e.getReferralInfo() );
+        LOG.debug( "" );
+    
+        LdapConnection conn = getWiredConnection( getLdapServer() );
+    
+        // referrals failure
+        ModifyDnRequest modifyDnRequest = new ModifyDnRequestImpl();
+        modifyDnRequest.setName( new Dn( "ou=Computers,uid=akarasuluref,ou=users,ou=system" ) );
+        modifyDnRequest.setNewRdn( new Rdn( "ou=Machines" ) );
+        modifyDnRequest.setDeleteOldRdn( true );
+    
+        ModifyDnResponse modifyDnResponse = conn.modifyDn( modifyDnRequest );
+    
+        assertEquals( ResultCodeEnum.REFERRAL, modifyDnResponse.getLdapResult().getResultCode() );
+    
+        assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://localhost:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
+        assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://foo:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
+        assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
+            .contains( "ldap://bar:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
+    
+        conn.close();
     }
-
-    ctx.close();
-}
-
-
-/**
- * Tests referral handling when an ancestor is a referral.
- */
-@Test
-public void testAncestorReferral() throws Exception
-{
-    LOG.debug( "" );
-
-    LdapConnection conn = getWiredConnection( getLdapServer() );
-
-    // referrals failure
-    ModifyDnRequest modifyDnRequest = new ModifyDnRequestImpl();
-    modifyDnRequest.setName( new Dn( "ou=Computers,uid=akarasuluref,ou=users,ou=system" ) );
-    modifyDnRequest.setNewRdn( new Rdn( "ou=Machines" ) );
-    modifyDnRequest.setDeleteOldRdn( true );
-
-    ModifyDnResponse modifyDnResponse = conn.modifyDn( modifyDnRequest );
-
-    assertEquals( ResultCodeEnum.REFERRAL, modifyDnResponse.getLdapResult().getResultCode() );
-
-    assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://localhost:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
-    assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://foo:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
-    assertTrue( modifyDnResponse.getLdapResult().getReferral().getLdapUrls()
-        .contains( "ldap://bar:10389/ou=Computers,uid=akarasulu,ou=users,ou=system" ) );
-
-    conn.close();
-}
-
-
-/**
- * Tests referral handling when an ancestor is a referral.
- */
-@Test
-public void testNewSuperiorAncestorReferral() throws Exception
-{
-    LOG.debug( "" );
-
-    LdapConnection conn = getWiredConnection( getLdapServer() );
-
-    // referrals failure
-    try
+    
+    
+    /**
+     * Tests referral handling when an ancestor is a referral.
+     */
+    @Test
+    public void testNewSuperiorAncestorReferral() throws Exception
     {
-        conn.moveAndRename( "uid=elecharny,ou=users,ou=system",
-            "ou=Machines,ou=Computers,uid=akarasuluref,ou=users,ou=system", true );
-        fail( "Should never get here to affectsMultipleDSA error result code" );
+        LOG.debug( "" );
+    
+        LdapConnection conn = getWiredConnection( getLdapServer() );
+    
+        // referrals failure
+        try
+        {
+            conn.moveAndRename( "uid=elecharny,ou=users,ou=system",
+                "ou=Machines,ou=Computers,uid=akarasuluref,ou=users,ou=system", true );
+            fail( "Should never get here to affectsMultipleDSA error result code" );
+        }
+        catch ( LdapOperationException e )
+        {
+            assertEquals( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS, e.getResultCode() );
+        }
+    
+        conn.close();
     }
-    catch ( LdapOperationException e )
-    {
-        assertEquals( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS, e.getResultCode() );
-    }
-
-    conn.close();
-}
 }
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyRdnIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyRdnIT.java
index a5a95ad..f2a7c87 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyRdnIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyRdnIT.java
@@ -38,6 +38,7 @@
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -49,6 +50,7 @@
 import org.apache.directory.shared.ldap.model.entry.Entry;
 import org.apache.directory.shared.ldap.model.ldif.LdifUtils;
 import org.junit.Ignore;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -68,6 +70,8 @@
     })
 public class ModifyRdnIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private static final String BASE = "ou=system";
 
 
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/MoveIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/MoveIT.java
index f48c0f9..4c939e6 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/MoveIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/MoveIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.modifydn;
 
@@ -32,6 +32,7 @@
 import javax.naming.directory.SearchResult;
 import javax.naming.ldap.LdapContext;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -39,6 +40,7 @@
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.apache.directory.shared.ldap.model.exception.LdapUnwillingToPerformException;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -81,6 +83,8 @@
         "ou: child" })
 public class MoveIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private static final String DN = "uid=akarasulu,ou=users,ou=system";
     private static final String NEW_DN = "uid=akarasulu,ou=NewSuperior,ou=system";
     private static final String NEW_DN2 = "uid=elecharny,ou=NewSuperior,ou=system";
@@ -134,7 +138,7 @@
 
         LdapConnection con = getAdminConnection( getLdapServer() );
 
-        //now do something bad: make the parent a child of its own child 
+        //now do something bad: make the parent a child of its own child
         try
         {
             con.move( "ou=parent,ou=system", "ou=child,ou=parent,ou=system" );
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/IndexedNegationSearchIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/IndexedNegationSearchIT.java
index 2485b1a..259ddd4 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/search/IndexedNegationSearchIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/IndexedNegationSearchIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.search;
 
@@ -54,7 +54,7 @@
 
 
 /**
- * A set of tests to make sure the negation operator is working 
+ * A set of tests to make sure the negation operator is working
  * properly when included in search filters on indexed attributes.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
@@ -152,111 +152,111 @@
 })
 public class IndexedNegationSearchIT extends AbstractLdapTestUnit
 {
-@Rule
-public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.THREADSAFE );
-
-
-/**
- * Tests to make sure a negated search for OU of "test1" returns
- * those entries that do not have the OU attribute or do not have
- * a "test1" value for OU if the attribute exists.
- */
-@Test
-public void testSearchNotOUIndexed() throws Exception
-{
-    Set<SearchResult> results = getResults( "(!(ou=test1))" );
-    assertFalse( contains( "uid=test1,ou=test,ou=system", results ) );
-    assertTrue( contains( "uid=test2,ou=test,ou=system", results ) );
-    assertTrue( contains( "uid=testNoOU,ou=test,ou=system", results ) );
-}
-
-
-/**
- * Tests to make sure a negated search for actors without ou
- * with value 'drama' returns those that do not have the attribute
- * and do not have a 'drama' value for ou if the attribute still
- * exists.  This test DOES build an index on ou for the system
- * partition and should have failed if the bug in DIRSERVER-951
- * was present and reproducable.
- */
-@Test
-public void testSearchNotDramaIndexed() throws Exception
-{
-    // jack black has ou but not drama, and joe newbie has no ou what so ever
-    Set<SearchResult> results = getActorResults( "(!(ou=drama))" );
-    assertTrue( contains( "uid=jblack,ou=actors,ou=system", results ) );
-    assertTrue( contains( "uid=jnewbie,ou=actors,ou=system", results ) );
-    assertEquals( 2, results.size() );
-}
-
-
-boolean contains( String dn, Set<SearchResult> results )
-{
-    for ( SearchResult result : results )
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    
+    
+    /**
+     * Tests to make sure a negated search for OU of "test1" returns
+     * those entries that do not have the OU attribute or do not have
+     * a "test1" value for OU if the attribute exists.
+     */
+    @Test
+    public void testSearchNotOUIndexed() throws Exception
     {
-        if ( result.getNameInNamespace().equals( dn ) )
+        Set<SearchResult> results = getResults( "(!(ou=test1))" );
+        assertFalse( contains( "uid=test1,ou=test,ou=system", results ) );
+        assertTrue( contains( "uid=test2,ou=test,ou=system", results ) );
+        assertTrue( contains( "uid=testNoOU,ou=test,ou=system", results ) );
+    }
+    
+    
+    /**
+     * Tests to make sure a negated search for actors without ou
+     * with value 'drama' returns those that do not have the attribute
+     * and do not have a 'drama' value for ou if the attribute still
+     * exists.  This test DOES build an index on ou for the system
+     * partition and should have failed if the bug in DIRSERVER-951
+     * was present and reproducable.
+     */
+    @Test
+    public void testSearchNotDramaIndexed() throws Exception
+    {
+        // jack black has ou but not drama, and joe newbie has no ou what so ever
+        Set<SearchResult> results = getActorResults( "(!(ou=drama))" );
+        assertTrue( contains( "uid=jblack,ou=actors,ou=system", results ) );
+        assertTrue( contains( "uid=jnewbie,ou=actors,ou=system", results ) );
+        assertEquals( 2, results.size() );
+    }
+    
+    
+    boolean contains( String dn, Set<SearchResult> results )
+    {
+        for ( SearchResult result : results )
         {
-            return true;
+            if ( result.getNameInNamespace().equals( dn ) )
+            {
+                return true;
+            }
         }
+    
+        return false;
     }
-
-    return false;
-}
-
-
-/**
- * Tests to make sure a negated search for actors without ou
- * with value 'drama' returns those that do not have the attribute
- * and do not have a 'drama' value for ou if the attribute still
- * exists.  This test DOES build an index on ou for the system
- * partition and should have failed if the bug in DIRSERVER-951
- * was present and reproducable.
- */
-@Test
-public void testSearchNotDramaNotNewbieIndexed() throws Exception
-{
-    // jack black has ou but not drama, and joe newbie has no ou what so ever
-    Set<SearchResult> results = getActorResults( "(& (!(uid=jnewbie)) (!(ou=drama)) )" );
-    assertTrue( contains( "uid=jblack,ou=actors,ou=system", results ) );
-    assertFalse( contains( "uid=jnewbie,ou=actors,ou=system", results ) );
-    assertEquals( 1, results.size() );
-}
-
-
-Set<SearchResult> getActorResults( String filter ) throws Exception
-{
-    DirContext ctx = getWiredContext( getLdapServer() );
-    Set<SearchResult> results = new HashSet<SearchResult>();
-    SearchControls controls = new SearchControls();
-    controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
-    NamingEnumeration<SearchResult> namingEnumeration = ctx.search( "ou=actors,ou=system", filter, controls );
-    while ( namingEnumeration.hasMore() )
+    
+    
+    /**
+     * Tests to make sure a negated search for actors without ou
+     * with value 'drama' returns those that do not have the attribute
+     * and do not have a 'drama' value for ou if the attribute still
+     * exists.  This test DOES build an index on ou for the system
+     * partition and should have failed if the bug in DIRSERVER-951
+     * was present and reproducable.
+     */
+    @Test
+    public void testSearchNotDramaNotNewbieIndexed() throws Exception
     {
-        results.add( namingEnumeration.next() );
+        // jack black has ou but not drama, and joe newbie has no ou what so ever
+        Set<SearchResult> results = getActorResults( "(& (!(uid=jnewbie)) (!(ou=drama)) )" );
+        assertTrue( contains( "uid=jblack,ou=actors,ou=system", results ) );
+        assertFalse( contains( "uid=jnewbie,ou=actors,ou=system", results ) );
+        assertEquals( 1, results.size() );
     }
-
-    namingEnumeration.close();
-    ctx.close();
-
-    return results;
-}
-
-
-Set<SearchResult> getResults( String filter ) throws Exception
-{
-    DirContext ctx = getWiredContext( getLdapServer() );
-    Set<SearchResult> results = new HashSet<SearchResult>();
-    SearchControls controls = new SearchControls();
-    controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-    NamingEnumeration<SearchResult> namingEnumeration = ctx.search( "ou=system", filter, controls );
-    while ( namingEnumeration.hasMore() )
+    
+    
+    Set<SearchResult> getActorResults( String filter ) throws Exception
     {
-        results.add( namingEnumeration.next() );
+        DirContext ctx = getWiredContext( getLdapServer() );
+        Set<SearchResult> results = new HashSet<SearchResult>();
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+        NamingEnumeration<SearchResult> namingEnumeration = ctx.search( "ou=actors,ou=system", filter, controls );
+        while ( namingEnumeration.hasMore() )
+        {
+            results.add( namingEnumeration.next() );
+        }
+    
+        namingEnumeration.close();
+        ctx.close();
+    
+        return results;
     }
-
-    namingEnumeration.close();
-    ctx.close();
-
-    return results;
-}
+    
+    
+    Set<SearchResult> getResults( String filter ) throws Exception
+    {
+        DirContext ctx = getWiredContext( getLdapServer() );
+        Set<SearchResult> results = new HashSet<SearchResult>();
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+        NamingEnumeration<SearchResult> namingEnumeration = ctx.search( "ou=system", filter, controls );
+        while ( namingEnumeration.hasMore() )
+        {
+            results.add( namingEnumeration.next() );
+        }
+    
+        namingEnumeration.close();
+        ctx.close();
+    
+        return results;
+    }
 }
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/NegationSearchIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/NegationSearchIT.java
index f0164cc..423375ed 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/search/NegationSearchIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/NegationSearchIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.search;
 
@@ -45,9 +45,9 @@
 
 
 /**
- * A set of tests to make sure the negation operator is working 
+ * A set of tests to make sure the negation operator is working
  * properly when included in search filters. Created in response
- * to JIRA issue 
+ * to JIRA issue
  * <a href="https://issues.apache.org/jira/browse/DIRSERVER-951">DIRSERVER-951</a>.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
@@ -109,75 +109,75 @@
 })
 public class NegationSearchIT extends AbstractLdapTestUnit
 {
-@Rule
-public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.THREADSAFE );
-
-
-/**
- * Tests to make sure a negated search for actors without ou
- * with value 'drama' returns those that do not have the attribute
- * and do not have a 'drama' value for ou if the attribute still
- * exists.  This test does not build an index on ou for the system
- * partition.
- */
-@Test
-public void testSearchNotDrama() throws Exception
-{
-    // jack black has ou but not drama, and joe newbie has no ou what so ever
-    Set<SearchResult> results = getResults( "(!(ou=drama))" );
-    assertTrue( contains( "uid=jblack,ou=actors,ou=system", results ) );
-    assertTrue( contains( "uid=jnewbie,ou=actors,ou=system", results ) );
-    assertEquals( 2, results.size() );
-}
-
-
-/**
- * Tests to make sure a negated search for actors without ou
- * with value 'drama' returns those that do not have the attribute
- * and do not have a 'drama' value for ou if the attribute still
- * exists.  This test does not build an index on ou for the system
- * partition.
- */
-@Test
-public void testSearchNotDramaNotNewbie() throws Exception
-{
-    // jack black has ou but not drama, and joe newbie has no ou what so ever
-    Set<SearchResult> results = getResults( "(& (!(uid=jnewbie)) (!(ou=drama)) )" );
-    assertTrue( contains( "uid=jblack,ou=actors,ou=system", results ) );
-    assertFalse( contains( "uid=jnewbie,ou=actors,ou=system", results ) );
-    assertEquals( 1, results.size() );
-}
-
-
-boolean contains( String dn, Set<SearchResult> results )
-{
-    for ( SearchResult result : results )
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    
+    
+    /**
+     * Tests to make sure a negated search for actors without ou
+     * with value 'drama' returns those that do not have the attribute
+     * and do not have a 'drama' value for ou if the attribute still
+     * exists.  This test does not build an index on ou for the system
+     * partition.
+     */
+    @Test
+    public void testSearchNotDrama() throws Exception
     {
-        if ( result.getNameInNamespace().equals( dn ) )
+        // jack black has ou but not drama, and joe newbie has no ou what so ever
+        Set<SearchResult> results = getResults( "(!(ou=drama))" );
+        assertTrue( contains( "uid=jblack,ou=actors,ou=system", results ) );
+        assertTrue( contains( "uid=jnewbie,ou=actors,ou=system", results ) );
+        assertEquals( 2, results.size() );
+    }
+    
+    
+    /**
+     * Tests to make sure a negated search for actors without ou
+     * with value 'drama' returns those that do not have the attribute
+     * and do not have a 'drama' value for ou if the attribute still
+     * exists.  This test does not build an index on ou for the system
+     * partition.
+     */
+    @Test
+    public void testSearchNotDramaNotNewbie() throws Exception
+    {
+        // jack black has ou but not drama, and joe newbie has no ou what so ever
+        Set<SearchResult> results = getResults( "(& (!(uid=jnewbie)) (!(ou=drama)) )" );
+        assertTrue( contains( "uid=jblack,ou=actors,ou=system", results ) );
+        assertFalse( contains( "uid=jnewbie,ou=actors,ou=system", results ) );
+        assertEquals( 1, results.size() );
+    }
+    
+    
+    boolean contains( String dn, Set<SearchResult> results )
+    {
+        for ( SearchResult result : results )
         {
-            return true;
+            if ( result.getNameInNamespace().equals( dn ) )
+            {
+                return true;
+            }
         }
+    
+        return false;
     }
-
-    return false;
-}
-
-
-Set<SearchResult> getResults( String filter ) throws Exception
-{
-    DirContext ctx = getWiredContext( getLdapServer() );
-    Set<SearchResult> results = new HashSet<SearchResult>();
-    SearchControls controls = new SearchControls();
-    controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
-    NamingEnumeration<SearchResult> namingEnumeration = ctx.search( "ou=actors,ou=system", filter, controls );
-    while ( namingEnumeration.hasMore() )
+    
+    
+    Set<SearchResult> getResults( String filter ) throws Exception
     {
-        results.add( namingEnumeration.next() );
+        DirContext ctx = getWiredContext( getLdapServer() );
+        Set<SearchResult> results = new HashSet<SearchResult>();
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+        NamingEnumeration<SearchResult> namingEnumeration = ctx.search( "ou=actors,ou=system", filter, controls );
+        while ( namingEnumeration.hasMore() )
+        {
+            results.add( namingEnumeration.next() );
+        }
+    
+        namingEnumeration.close();
+        ctx.close();
+    
+        return results;
     }
-
-    namingEnumeration.close();
-    ctx.close();
-
-    return results;
-}
 }
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/PagedSearchIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/PagedSearchIT.java
index 2cf070f..4700beb 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/search/PagedSearchIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/PagedSearchIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.search;
 
@@ -180,7 +180,7 @@
         "objectClass: person",
         "cn: user8",
         "sn: user 8",
-        // 
+        //
         "dn: cn=user9,dc=users,ou=system",
         "objectClass: top",
         "objectClass: person",
@@ -198,7 +198,7 @@
 public class PagedSearchIT extends AbstractLdapTestUnit
 {
     @Rule
-    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.THREADSAFE );
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     
     private LdapApiService codec = LdapApiServiceFactory.getSingleton();
     
@@ -1083,7 +1083,7 @@
     
     
     /**
-     * Do a test with a paged search, changing the number of entries to 
+     * Do a test with a paged search, changing the number of entries to
      * return in the middle of the loop
      */
     @Test
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/PersistentSearchIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/PersistentSearchIT.java
index f8e208b..fc1d52b 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/search/PersistentSearchIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/PersistentSearchIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.search;
 
@@ -43,6 +43,7 @@
 import javax.naming.ldap.HasControls;
 import javax.naming.ldap.LdapContext;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
@@ -63,6 +64,7 @@
 import org.apache.directory.shared.ldap.model.message.controls.PersistentSearchImpl;
 import org.apache.directory.shared.ldap.util.JndiUtils;
 import org.junit.After;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
@@ -92,573 +94,575 @@
 })
 public class PersistentSearchIT extends AbstractLdapTestUnit
 {
-private static final Logger LOG = LoggerFactory.getLogger( PersistentSearchIT.class );
-
-private static final String BASE = "ou=system";
-private static final String PERSON_DESCRIPTION = "an American singer-songwriter";
-private static final String RDN = "cn=Tori Amos";
-
-
-/**
- * Creation of required attributes of a person entry.
- */
-private Attributes getPersonAttributes( String sn, String cn ) throws LdapException
-{
-    Attributes attributes = LdifUtils.createJndiAttributes(
-        "objectClass: top",
-        "objectClass: person",
-        "cn", cn,
-        "sn", sn );
-
-    return attributes;
-}
-
-EventDirContext ctx;
-EventService eventService;
-PSearchListener listener;
-Thread t;
-
-
-private void setUpListenerReturnECs() throws Exception
-{
-    setUpListener( true, new PersistentSearchImpl(), false );
-}
-
-
-private void setUpListener( boolean returnECs, PersistentSearch persistentSearch, boolean ignoreEmptyRegistryCheck )
-    throws Exception
-{
-    ctx = ( EventDirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-    eventService = getLdapServer().getDirectoryService().getEventService();
-    List<RegistrationEntry> registrationEntryList = eventService.getRegistrationEntries();
-
-    if ( !ignoreEmptyRegistryCheck )
-    {
-        assertTrue( registrationEntryList.isEmpty() );
-    }
-
-    persistentSearch.setReturnECs( returnECs );
-    listener = new PSearchListener( persistentSearch );
-    t = new Thread( listener, "PSearchListener" );
-    t.start();
-
-    // let's wait until the listener thread started
-    while ( eventService.getRegistrationEntries().isEmpty() )
-    {
-        Thread.sleep( 100 );
-    }
-
-    // Now we wait until the listener is registered (timing dependent crap)
-    Thread.sleep( 250 );
-}
-
-
-private void setUpListener() throws Exception
-{
-    ctx = ( EventDirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-    eventService = getLdapServer().getDirectoryService().getEventService();
-    List<RegistrationEntry> registrationEntryList = eventService.getRegistrationEntries();
-    assertTrue( registrationEntryList.isEmpty() );
-
-    listener = new PSearchListener();
-    t = new Thread( listener, "PSearchListener" );
-    t.start();
-
-    // let's wait until the listener thread started
-    while ( eventService.getRegistrationEntries().isEmpty() )
-    {
-        Thread.sleep( 100 );
-    }
-
-    // Now we wait until the listener is registered (timing dependent crap)
-    Thread.sleep( 250 );
-}
-
-
-@After
-public void tearDownListener() throws Exception
-{
-    listener.close();
-    ctx.close();
-
-    while ( !eventService.getRegistrationEntries().isEmpty() )
-    {
-        Thread.sleep( 100 );
-    }
-}
-
-
-private void waitForThreadToDie( Thread t ) throws Exception
-{
-    long start = System.currentTimeMillis();
-
-    while ( t.isAlive() )
-    {
-        Thread.sleep( 200 );
-        if ( System.currentTimeMillis() - start > 1000 )
-        {
-            break;
-        }
-    }
-}
-
-
-/**
- * Shows correct notifications for modify(4) changes.
- */
-@Test
-public void testPsearchModify() throws Exception
-{
-    setUpListener();
-    ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE,
-        new BasicAttributes( "description", PERSON_DESCRIPTION, true ) );
-    waitForThreadToDie( t );
-    assertNotNull( listener.result );
-    assertEquals( RDN, listener.result.getName() );
-}
-
-
-/**
- * Shows correct notifications for moddn(8) changes.
- */
-@Test
-public void testPsearchModifyDn() throws Exception
-{
-    setUpListener();
-    ctx.rename( RDN, "cn=Jack Black" );
-    waitForThreadToDie( t );
-    assertNotNull( listener.result );
-    assertEquals( "cn=Jack Black", listener.result.getName() );
-}
-
-
-/**
- * Shows correct notifications for delete(2) changes.
- */
-@Test
-public void testPsearchDelete() throws Exception
-{
-    setUpListener();
-    ctx.destroySubcontext( RDN );
-    waitForThreadToDie( t );
-    assertNotNull( listener.result );
-    assertEquals( RDN, listener.result.getName() );
-}
-
-
-/**
- * Shows correct notifications for add(1) changes.
- */
-@Test
-public void testPsearchAdd() throws Exception
-{
-    setUpListener();
-    ctx.createSubcontext( "cn=Jack Black", getPersonAttributes( "Black", "Jack Black" ) );
-    waitForThreadToDie( t );
-    assertNotNull( listener.result );
-    assertEquals( "cn=Jack Black", listener.result.getName() );
-}
-
-
-/**
- * Shows correct notifications for modify(4) changes with returned 
- * EntryChangeControl.
- */
-@Test
-public void testPsearchModifyWithEC() throws Exception
-{
-    setUpListenerReturnECs();
-    ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, new BasicAttributes( "description", PERSON_DESCRIPTION,
-        true ) );
-    waitForThreadToDie( t );
-    assertNotNull( listener.result );
-    assertEquals( RDN, listener.result.getName() );
-    assertEquals( listener.result.control.getChangeType(), ChangeType.MODIFY );
-}
-
-
-/**
- * Shows correct notifications for moddn(8) changes with returned 
- * EntryChangeControl.
- */
-@Test
-public void testPsearchModifyDnWithEC() throws Exception
-{
-    setUpListenerReturnECs();
-    ctx.rename( RDN, "cn=Jack Black" );
-    waitForThreadToDie( t );
-    assertNotNull( listener.result );
-    assertEquals( "cn=Jack Black", listener.result.getName() );
-    assertEquals( listener.result.control.getChangeType(), ChangeType.MODDN );
-    assertEquals( ( RDN + ",ou=system" ), listener.result.control.getPreviousDn().getName() );
-}
-
-
-/**
- * Shows correct notifications for delete(2) changes with returned 
- * EntryChangeControl.
- */
-@Test
-public void testPsearchDeleteWithEC() throws Exception
-{
-    setUpListenerReturnECs();
-    ctx.destroySubcontext( RDN );
-    waitForThreadToDie( t );
-    assertNotNull( listener.result );
-    assertEquals( RDN, listener.result.getName() );
-    assertEquals( listener.result.control.getChangeType(), ChangeType.DELETE );
-}
-
-
-/**
- * Shows correct notifications for add(1) changes with returned 
- * EntryChangeControl.
- */
-@Test
-public void testPsearchAddWithEC() throws Exception
-{
-    setUpListenerReturnECs();
-    ctx.createSubcontext( "cn=Jack Black", getPersonAttributes( "Black", "Jack Black" ) );
-    waitForThreadToDie( t );
-    assertNotNull( listener.result );
-    assertEquals( "cn=Jack Black", listener.result.getName() );
-    assertEquals( listener.result.control.getChangeType(), ChangeType.ADD );
-}
-
-
-/**
- * Shows correct notifications for only add(1) and modify(4) registered changes with returned 
- * EntryChangeControl but not deletes.
- */
-@Test
-public void testPsearchAddModifyEnabledWithEC() throws Exception
-{
-    PersistentSearch ctrl = new PersistentSearchImpl();
-    ctrl.setReturnECs( true );
-    ctrl.setChangeTypes( ChangeType.ADD.getValue() );
-    ctrl.enableNotification( ChangeType.MODIFY );
-    setUpListener( true, ctrl, false );
-    ctx.createSubcontext( "cn=Jack Black", getPersonAttributes( "Black", "Jack Black" ) );
-    waitForThreadToDie( t );
-
-    assertNotNull( listener.result );
-    assertEquals( "cn=Jack Black", listener.result.getName() );
-    assertEquals( listener.result.control.getChangeType(), ChangeType.ADD );
-    tearDownListener();
-
-    setUpListener( true, ctrl, true );
-    ctx.destroySubcontext( "cn=Jack Black" );
-    waitForThreadToDie( t );
-    assertNull( listener.result );
-
-    // thread is still waiting for notifications try a modify
-    ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, new BasicAttributes( "description", PERSON_DESCRIPTION,
-        true ) );
-    waitForThreadToDie( t );
-
-    assertNotNull( listener.result );
-    assertEquals( RDN, listener.result.getName() );
-    assertEquals( listener.result.control.getChangeType(), ChangeType.MODIFY );
-}
-
-/**
- * Shows correct notifications for add(1) changes with returned 
- * EntryChangeControl and changesOnly set to false so we return
- * the first set of entries.
- * 
- * This test is commented out because it exhibits some producer
- * consumer lockups (server and client being in same process)
- * 
- * PLUS ALL THIS GARBAGE IS TIME DEPENDENT!!!!!
- */
-//    public void testPsearchAddWithECAndFalseChangesOnly() throws Exception
-//    {
-//        PersistentSearchDecorator decorator = new PersistentSearchDecorator();
-//        decorator.setReturnECs( true );
-//        decorator.setChangesOnly( false );
-//        PSearchListener listener = new PSearchListener( decorator );
-//        Thread t = new Thread( listener );
-//        t.start();
-//        
-//        Thread.sleep( 3000 );
-//
-//        assertEquals( 5, listener.count );
-//        ctx.createSubcontext( "cn=Jack Black", getPersonAttributes( "Black", "Jack Black" ) );
-//        
-//        long start = System.currentTimeMillis();
-//        while ( t.isAlive() )
-//        {
-//            Thread.sleep( 100 );
-//            if ( System.currentTimeMillis() - start > 3000 )
-//            {
-//                break;
-//            }
-//        }
-//        
-//        assertEquals( 6, listener.count );
-//        assertNotNull( listener.result );
-//        assertEquals( "cn=Jack Black", listener.result.getName() );
-//        assertEquals( listener.result.decorator.getChangeType(), ChangeType.ADD );
-//    }
-
-/**
- * Shows notifications functioning with the JNDI notification API of the SUN
- * provider.
- *
-@Test
-public void testPsearchAbandon() throws Exception
-{
-    PersistentSearchDecorator decorator = new PersistentSearchDecorator();
-    decorator.setReturnECs( true );
-    PSearchListener listener = new PSearchListener( decorator );
-    Thread t = new Thread( listener );
-    t.start();
-
-    while ( !listener.isReady )
-    {
-        Thread.sleep( 100 );
-    }
-    Thread.sleep( 250 );
-
-    ctx.createSubcontext( "cn=Jack Black", getPersonAttributes( "Black", "Jack Black" ) );
-
-    long start = System.currentTimeMillis();
-    while ( t.isAlive() )
-    {
-        Thread.sleep( 100 );
-        if ( System.currentTimeMillis() - start > 3000 )
-        {
-            break;
-        }
-    }
-
-    assertNotNull( listener.result );
-    assertEquals( "cn=Jack Black", listener.result.getName() );
-    assertEquals( listener.result.decorator.getChangeType(), ChangeType.ADD );
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    private static final Logger LOG = LoggerFactory.getLogger( PersistentSearchIT.class );
     
-    listener = new PSearchListener( decorator );
-
-    t = new Thread( listener );
-    t.start();
-
-    ctx.destroySubcontext( "cn=Jack Black" );
-
-    start = System.currentTimeMillis();
-    while ( t.isAlive() )
+    private static final String BASE = "ou=system";
+    private static final String PERSON_DESCRIPTION = "an American singer-songwriter";
+    private static final String RDN = "cn=Tori Amos";
+    
+    
+    /**
+     * Creation of required attributes of a person entry.
+     */
+    private Attributes getPersonAttributes( String sn, String cn ) throws LdapException
     {
-        Thread.sleep( 100 );
-        if ( System.currentTimeMillis() - start > 3000 )
+        Attributes attributes = LdifUtils.createJndiAttributes(
+            "objectClass: top",
+            "objectClass: person",
+            "cn", cn,
+            "sn", sn );
+    
+        return attributes;
+    }
+    
+    EventDirContext ctx;
+    EventService eventService;
+    PSearchListener listener;
+    Thread t;
+    
+    
+    private void setUpListenerReturnECs() throws Exception
+    {
+        setUpListener( true, new PersistentSearchImpl(), false );
+    }
+    
+    
+    private void setUpListener( boolean returnECs, PersistentSearch persistentSearch, boolean ignoreEmptyRegistryCheck )
+        throws Exception
+    {
+        ctx = ( EventDirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+        eventService = getLdapServer().getDirectoryService().getEventService();
+        List<RegistrationEntry> registrationEntryList = eventService.getRegistrationEntries();
+    
+        if ( !ignoreEmptyRegistryCheck )
         {
-            break;
+            assertTrue( registrationEntryList.isEmpty() );
+        }
+    
+        persistentSearch.setReturnECs( returnECs );
+        listener = new PSearchListener( persistentSearch );
+        t = new Thread( listener, "PSearchListener" );
+        t.start();
+    
+        // let's wait until the listener thread started
+        while ( eventService.getRegistrationEntries().isEmpty() )
+        {
+            Thread.sleep( 100 );
+        }
+    
+        // Now we wait until the listener is registered (timing dependent crap)
+        Thread.sleep( 250 );
+    }
+    
+    
+    private void setUpListener() throws Exception
+    {
+        ctx = ( EventDirContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+        eventService = getLdapServer().getDirectoryService().getEventService();
+        List<RegistrationEntry> registrationEntryList = eventService.getRegistrationEntries();
+        assertTrue( registrationEntryList.isEmpty() );
+    
+        listener = new PSearchListener();
+        t = new Thread( listener, "PSearchListener" );
+        t.start();
+    
+        // let's wait until the listener thread started
+        while ( eventService.getRegistrationEntries().isEmpty() )
+        {
+            Thread.sleep( 100 );
+        }
+    
+        // Now we wait until the listener is registered (timing dependent crap)
+        Thread.sleep( 250 );
+    }
+    
+    
+    @After
+    public void tearDownListener() throws Exception
+    {
+        listener.close();
+        ctx.close();
+    
+        while ( !eventService.getRegistrationEntries().isEmpty() )
+        {
+            Thread.sleep( 100 );
         }
     }
-
-    // there seems to be a race condition here
-    // assertNull( listener.result );
-    assertNotNull( listener.result );
-    assertEquals( "cn=Jack Black", listener.result.getName() );
-    assertEquals( ChangeType.DELETE, listener.result.decorator.getChangeType() );
-    listener.result = null;
-
-    // thread is still waiting for notifications try a modify
-    ctx.modifyAttributes( Rdn, DirContext.REMOVE_ATTRIBUTE, new AttributesImpl( "description", PERSON_DESCRIPTION,
-        true ) );
-    start = System.currentTimeMillis();
-    while ( t.isAlive() )
+    
+    
+    private void waitForThreadToDie( Thread t ) throws Exception
     {
-        Thread.sleep( 200 );
-        if ( System.currentTimeMillis() - start > 3000 )
+        long start = System.currentTimeMillis();
+    
+        while ( t.isAlive() )
         {
-            break;
-        }
-    }
-
-    assertNull( listener.result );
-    //assertEquals( Rdn, listener.result.getName() );
-    //assertEquals( listener.result.decorator.getChangeType(), ChangeType.MODIFY );
-}*/
-
-class JndiNotificationListener implements NamespaceChangeListener, ObjectChangeListener
-{
-    boolean hasError = false;
-    ArrayList<EventObject> list = new ArrayList<EventObject>();
-    NamingExceptionEvent exceptionEvent = null;
-
-
-    public void objectAdded( NamingEvent evt )
-    {
-        list.add( 0, evt );
-    }
-
-
-    public void objectRemoved( NamingEvent evt )
-    {
-        list.add( 0, evt );
-    }
-
-
-    public void objectRenamed( NamingEvent evt )
-    {
-        list.add( 0, evt );
-    }
-
-
-    public void namingExceptionThrown( NamingExceptionEvent evt )
-    {
-        hasError = true;
-        exceptionEvent = evt;
-        list.add( 0, evt );
-    }
-
-
-    public void objectChanged( NamingEvent evt )
-    {
-        list.add( 0, evt );
-    }
-}
-
-class PSearchListener implements Runnable
-{
-    boolean isReady = false;
-    PSearchNotification result;
-    final PersistentSearchDecorator persistentSearch;
-    LdapContext ctx;
-    NamingEnumeration<SearchResult> list;
-
-
-    PSearchListener()
-    {
-        persistentSearch = new PersistentSearchDecorator( getLdapServer().getDirectoryService().getLdapCodecService() );
-    }
-
-
-    PSearchListener( PersistentSearch persistentSearch )
-    {
-        CodecControl<? extends Control> wrapped =
-            getLdapServer().getDirectoryService().getLdapCodecService().newControl( persistentSearch );
-        this.persistentSearch = ( PersistentSearchDecorator ) wrapped;
-    }
-
-
-    void close()
-    {
-        if ( list != null )
-        {
-            try
+            Thread.sleep( 200 );
+            if ( System.currentTimeMillis() - start > 1000 )
             {
-                list.close();
-                LOG.debug( "PSearchListener: search naming enumeration closed()" );
-            }
-            catch ( Exception e )
-            {
-                LOG.error( "Error closing NamingEnumeration on PSearchListener", e );
-            }
-        }
-
-        if ( ctx != null )
-        {
-            try
-            {
-                ctx.close();
-                LOG.debug( "PSearchListener: search context closed()" );
-            }
-            catch ( Exception e )
-            {
-                LOG.error( "Error closing connection on PSearchListener", e );
+                break;
             }
         }
     }
-
-
-    public void run()
+    
+    
+    /**
+     * Shows correct notifications for modify(4) changes.
+     */
+    @Test
+    public void testPsearchModify() throws Exception
     {
-        LOG.debug( "PSearchListener.run() called." );
-        LdapApiService codec = getLdapServer().getDirectoryService().getLdapCodecService();
-        persistentSearch.setCritical( true );
-        persistentSearch.setValue( persistentSearch.getValue() );
-
-        Control[] ctxCtls = new Control[]
-            { persistentSearch };
-
-        try
+        setUpListener();
+        ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE,
+            new BasicAttributes( "description", PERSON_DESCRIPTION, true ) );
+        waitForThreadToDie( t );
+        assertNotNull( listener.result );
+        assertEquals( RDN, listener.result.getName() );
+    }
+    
+    
+    /**
+     * Shows correct notifications for moddn(8) changes.
+     */
+    @Test
+    public void testPsearchModifyDn() throws Exception
+    {
+        setUpListener();
+        ctx.rename( RDN, "cn=Jack Black" );
+        waitForThreadToDie( t );
+        assertNotNull( listener.result );
+        assertEquals( "cn=Jack Black", listener.result.getName() );
+    }
+    
+    
+    /**
+     * Shows correct notifications for delete(2) changes.
+     */
+    @Test
+    public void testPsearchDelete() throws Exception
+    {
+        setUpListener();
+        ctx.destroySubcontext( RDN );
+        waitForThreadToDie( t );
+        assertNotNull( listener.result );
+        assertEquals( RDN, listener.result.getName() );
+    }
+    
+    
+    /**
+     * Shows correct notifications for add(1) changes.
+     */
+    @Test
+    public void testPsearchAdd() throws Exception
+    {
+        setUpListener();
+        ctx.createSubcontext( "cn=Jack Black", getPersonAttributes( "Black", "Jack Black" ) );
+        waitForThreadToDie( t );
+        assertNotNull( listener.result );
+        assertEquals( "cn=Jack Black", listener.result.getName() );
+    }
+    
+    
+    /**
+     * Shows correct notifications for modify(4) changes with returned
+     * EntryChangeControl.
+     */
+    @Test
+    public void testPsearchModifyWithEC() throws Exception
+    {
+        setUpListenerReturnECs();
+        ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, new BasicAttributes( "description", PERSON_DESCRIPTION,
+            true ) );
+        waitForThreadToDie( t );
+        assertNotNull( listener.result );
+        assertEquals( RDN, listener.result.getName() );
+        assertEquals( listener.result.control.getChangeType(), ChangeType.MODIFY );
+    }
+    
+    
+    /**
+     * Shows correct notifications for moddn(8) changes with returned
+     * EntryChangeControl.
+     */
+    @Test
+    public void testPsearchModifyDnWithEC() throws Exception
+    {
+        setUpListenerReturnECs();
+        ctx.rename( RDN, "cn=Jack Black" );
+        waitForThreadToDie( t );
+        assertNotNull( listener.result );
+        assertEquals( "cn=Jack Black", listener.result.getName() );
+        assertEquals( listener.result.control.getChangeType(), ChangeType.MODDN );
+        assertEquals( ( RDN + ",ou=system" ), listener.result.control.getPreviousDn().getName() );
+    }
+    
+    
+    /**
+     * Shows correct notifications for delete(2) changes with returned
+     * EntryChangeControl.
+     */
+    @Test
+    public void testPsearchDeleteWithEC() throws Exception
+    {
+        setUpListenerReturnECs();
+        ctx.destroySubcontext( RDN );
+        waitForThreadToDie( t );
+        assertNotNull( listener.result );
+        assertEquals( RDN, listener.result.getName() );
+        assertEquals( listener.result.control.getChangeType(), ChangeType.DELETE );
+    }
+    
+    
+    /**
+     * Shows correct notifications for add(1) changes with returned
+     * EntryChangeControl.
+     */
+    @Test
+    public void testPsearchAddWithEC() throws Exception
+    {
+        setUpListenerReturnECs();
+        ctx.createSubcontext( "cn=Jack Black", getPersonAttributes( "Black", "Jack Black" ) );
+        waitForThreadToDie( t );
+        assertNotNull( listener.result );
+        assertEquals( "cn=Jack Black", listener.result.getName() );
+        assertEquals( listener.result.control.getChangeType(), ChangeType.ADD );
+    }
+    
+    
+    /**
+     * Shows correct notifications for only add(1) and modify(4) registered changes with returned
+     * EntryChangeControl but not deletes.
+     */
+    @Test
+    public void testPsearchAddModifyEnabledWithEC() throws Exception
+    {
+        PersistentSearch ctrl = new PersistentSearchImpl();
+        ctrl.setReturnECs( true );
+        ctrl.setChangeTypes( ChangeType.ADD.getValue() );
+        ctrl.enableNotification( ChangeType.MODIFY );
+        setUpListener( true, ctrl, false );
+        ctx.createSubcontext( "cn=Jack Black", getPersonAttributes( "Black", "Jack Black" ) );
+        waitForThreadToDie( t );
+    
+        assertNotNull( listener.result );
+        assertEquals( "cn=Jack Black", listener.result.getName() );
+        assertEquals( listener.result.control.getChangeType(), ChangeType.ADD );
+        tearDownListener();
+    
+        setUpListener( true, ctrl, true );
+        ctx.destroySubcontext( "cn=Jack Black" );
+        waitForThreadToDie( t );
+        assertNull( listener.result );
+    
+        // thread is still waiting for notifications try a modify
+        ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, new BasicAttributes( "description", PERSON_DESCRIPTION,
+            true ) );
+        waitForThreadToDie( t );
+    
+        assertNotNull( listener.result );
+        assertEquals( RDN, listener.result.getName() );
+        assertEquals( listener.result.control.getChangeType(), ChangeType.MODIFY );
+    }
+    
+    /**
+     * Shows correct notifications for add(1) changes with returned
+     * EntryChangeControl and changesOnly set to false so we return
+     * the first set of entries.
+     * 
+     * This test is commented out because it exhibits some producer
+     * consumer lockups (server and client being in same process)
+     * 
+     * PLUS ALL THIS GARBAGE IS TIME DEPENDENT!!!!!
+     */
+    //    public void testPsearchAddWithECAndFalseChangesOnly() throws Exception
+    //    {
+    //        PersistentSearchDecorator decorator = new PersistentSearchDecorator();
+    //        decorator.setReturnECs( true );
+    //        decorator.setChangesOnly( false );
+    //        PSearchListener listener = new PSearchListener( decorator );
+    //        Thread t = new Thread( listener );
+    //        t.start();
+    //
+    //        Thread.sleep( 3000 );
+    //
+    //        assertEquals( 5, listener.count );
+    //        ctx.createSubcontext( "cn=Jack Black", getPersonAttributes( "Black", "Jack Black" ) );
+    //
+    //        long start = System.currentTimeMillis();
+    //        while ( t.isAlive() )
+    //        {
+    //            Thread.sleep( 100 );
+    //            if ( System.currentTimeMillis() - start > 3000 )
+    //            {
+    //                break;
+    //            }
+    //        }
+    //
+    //        assertEquals( 6, listener.count );
+    //        assertNotNull( listener.result );
+    //        assertEquals( "cn=Jack Black", listener.result.getName() );
+    //        assertEquals( listener.result.decorator.getChangeType(), ChangeType.ADD );
+    //    }
+    
+    /**
+     * Shows notifications functioning with the JNDI notification API of the SUN
+     * provider.
+     *
+    @Test
+    public void testPsearchAbandon() throws Exception
+    {
+        PersistentSearchDecorator decorator = new PersistentSearchDecorator();
+        decorator.setReturnECs( true );
+        PSearchListener listener = new PSearchListener( decorator );
+        Thread t = new Thread( listener );
+        t.start();
+    
+        while ( !listener.isReady )
         {
-            ctx = ( LdapContext ) getWiredContext( getLdapServer() ).lookup( BASE );
-            ctx.setRequestControls( JndiUtils.toJndiControls( codec, ctxCtls ) );
-            isReady = true;
-            LOG.debug( "PSearchListener is ready and about to issue persistent search request." );
-            list = ctx.search( "", "objectClass=*", null );
-            LOG.debug( "PSearchListener search request returned." );
-            EntryChange ecControl = null;
-
-            while ( list.hasMore() )
+            Thread.sleep( 100 );
+        }
+        Thread.sleep( 250 );
+    
+        ctx.createSubcontext( "cn=Jack Black", getPersonAttributes( "Black", "Jack Black" ) );
+    
+        long start = System.currentTimeMillis();
+        while ( t.isAlive() )
+        {
+            Thread.sleep( 100 );
+            if ( System.currentTimeMillis() - start > 3000 )
             {
-                LOG.debug( "PSearchListener search request got an item." );
-                javax.naming.ldap.Control[] controls;
-                SearchResult sresult = list.next();
-
-                if ( sresult instanceof HasControls )
+                break;
+            }
+        }
+    
+        assertNotNull( listener.result );
+        assertEquals( "cn=Jack Black", listener.result.getName() );
+        assertEquals( listener.result.decorator.getChangeType(), ChangeType.ADD );
+        
+        listener = new PSearchListener( decorator );
+    
+        t = new Thread( listener );
+        t.start();
+    
+        ctx.destroySubcontext( "cn=Jack Black" );
+    
+        start = System.currentTimeMillis();
+        while ( t.isAlive() )
+        {
+            Thread.sleep( 100 );
+            if ( System.currentTimeMillis() - start > 3000 )
+            {
+                break;
+            }
+        }
+    
+        // there seems to be a race condition here
+        // assertNull( listener.result );
+        assertNotNull( listener.result );
+        assertEquals( "cn=Jack Black", listener.result.getName() );
+        assertEquals( ChangeType.DELETE, listener.result.decorator.getChangeType() );
+        listener.result = null;
+    
+        // thread is still waiting for notifications try a modify
+        ctx.modifyAttributes( Rdn, DirContext.REMOVE_ATTRIBUTE, new AttributesImpl( "description", PERSON_DESCRIPTION,
+            true ) );
+        start = System.currentTimeMillis();
+        while ( t.isAlive() )
+        {
+            Thread.sleep( 200 );
+            if ( System.currentTimeMillis() - start > 3000 )
+            {
+                break;
+            }
+        }
+    
+        assertNull( listener.result );
+        //assertEquals( Rdn, listener.result.getName() );
+        //assertEquals( listener.result.decorator.getChangeType(), ChangeType.MODIFY );
+    }*/
+    
+    class JndiNotificationListener implements NamespaceChangeListener, ObjectChangeListener
+    {
+        boolean hasError = false;
+        ArrayList<EventObject> list = new ArrayList<EventObject>();
+        NamingExceptionEvent exceptionEvent = null;
+    
+    
+        public void objectAdded( NamingEvent evt )
+        {
+            list.add( 0, evt );
+        }
+    
+    
+        public void objectRemoved( NamingEvent evt )
+        {
+            list.add( 0, evt );
+        }
+    
+    
+        public void objectRenamed( NamingEvent evt )
+        {
+            list.add( 0, evt );
+        }
+    
+    
+        public void namingExceptionThrown( NamingExceptionEvent evt )
+        {
+            hasError = true;
+            exceptionEvent = evt;
+            list.add( 0, evt );
+        }
+    
+    
+        public void objectChanged( NamingEvent evt )
+        {
+            list.add( 0, evt );
+        }
+    }
+    
+    class PSearchListener implements Runnable
+    {
+        boolean isReady = false;
+        PSearchNotification result;
+        final PersistentSearchDecorator persistentSearch;
+        LdapContext ctx;
+        NamingEnumeration<SearchResult> list;
+    
+    
+        PSearchListener()
+        {
+            persistentSearch = new PersistentSearchDecorator( getLdapServer().getDirectoryService().getLdapCodecService() );
+        }
+    
+    
+        PSearchListener( PersistentSearch persistentSearch )
+        {
+            CodecControl<? extends Control> wrapped =
+                getLdapServer().getDirectoryService().getLdapCodecService().newControl( persistentSearch );
+            this.persistentSearch = ( PersistentSearchDecorator ) wrapped;
+        }
+    
+    
+        void close()
+        {
+            if ( list != null )
+            {
+                try
                 {
-                    controls = ( ( HasControls ) sresult ).getControls();
-
-                    if ( controls != null )
+                    list.close();
+                    LOG.debug( "PSearchListener: search naming enumeration closed()" );
+                }
+                catch ( Exception e )
+                {
+                    LOG.error( "Error closing NamingEnumeration on PSearchListener", e );
+                }
+            }
+    
+            if ( ctx != null )
+            {
+                try
+                {
+                    ctx.close();
+                    LOG.debug( "PSearchListener: search context closed()" );
+                }
+                catch ( Exception e )
+                {
+                    LOG.error( "Error closing connection on PSearchListener", e );
+                }
+            }
+        }
+    
+    
+        public void run()
+        {
+            LOG.debug( "PSearchListener.run() called." );
+            LdapApiService codec = getLdapServer().getDirectoryService().getLdapCodecService();
+            persistentSearch.setCritical( true );
+            persistentSearch.setValue( persistentSearch.getValue() );
+    
+            Control[] ctxCtls = new Control[]
+                { persistentSearch };
+    
+            try
+            {
+                ctx = ( LdapContext ) getWiredContext( getLdapServer() ).lookup( BASE );
+                ctx.setRequestControls( JndiUtils.toJndiControls( codec, ctxCtls ) );
+                isReady = true;
+                LOG.debug( "PSearchListener is ready and about to issue persistent search request." );
+                list = ctx.search( "", "objectClass=*", null );
+                LOG.debug( "PSearchListener search request returned." );
+                EntryChange ecControl = null;
+    
+                while ( list.hasMore() )
+                {
+                    LOG.debug( "PSearchListener search request got an item." );
+                    javax.naming.ldap.Control[] controls;
+                    SearchResult sresult = list.next();
+    
+                    if ( sresult instanceof HasControls )
                     {
-                        for ( javax.naming.ldap.Control jndiControl : controls )
+                        controls = ( ( HasControls ) sresult ).getControls();
+    
+                        if ( controls != null )
                         {
-                            if ( jndiControl.getID().equals(
-                                EntryChange.OID ) )
+                            for ( javax.naming.ldap.Control jndiControl : controls )
                             {
-                                ecControl = ( EntryChange ) JndiUtils.fromJndiControl( codec, jndiControl );
-                                ( ( EntryChangeDecorator ) ecControl ).decode( jndiControl.getEncodedValue() );
+                                if ( jndiControl.getID().equals(
+                                    EntryChange.OID ) )
+                                {
+                                    ecControl = ( EntryChange ) JndiUtils.fromJndiControl( codec, jndiControl );
+                                    ( ( EntryChangeDecorator ) ecControl ).decode( jndiControl.getEncodedValue() );
+                                }
                             }
                         }
                     }
+    
+                    result = new PSearchNotification( sresult, ecControl );
+                    break;
                 }
-
-                result = new PSearchNotification( sresult, ecControl );
-                break;
+    
+                LOG.debug( "PSearchListener broke out of while loop." );
             }
-
-            LOG.debug( "PSearchListener broke out of while loop." );
-        }
-        catch ( Exception e )
-        {
-            e.printStackTrace();
-            LOG.error( "PSearchListener encountered error", e );
-        }
-        finally
-        {
+            catch ( Exception e )
+            {
+                e.printStackTrace();
+                LOG.error( "PSearchListener encountered error", e );
+            }
+            finally
+            {
+            }
         }
     }
-}
-
-class PSearchNotification extends SearchResult
-{
-    private static final long serialVersionUID = 1L;
-    final EntryChange control;
-
-
-    public PSearchNotification( SearchResult result, EntryChange control )
+    
+    class PSearchNotification extends SearchResult
     {
-        super( result.getName(), result.getClassName(), result.getObject(), result.getAttributes(), result
-            .isRelative() );
-        this.control = control;
-    }
-
-
-    public String toString()
-    {
-        StringBuffer buf = new StringBuffer();
-        buf.append( "Dn: " ).append( getName() ).append( "\n" );
-
-        if ( control != null )
+        private static final long serialVersionUID = 1L;
+        final EntryChange control;
+    
+    
+        public PSearchNotification( SearchResult result, EntryChange control )
         {
-            buf.append( "    EntryChangeControl =\n" );
-            buf.append( "       changeType   : " ).append( control.getChangeType() ).append( "\n" );
-            buf.append( "       previousDN   : " ).append( control.getPreviousDn() ).append( "\n" );
-            buf.append( "       changeNumber : " ).append( control.getChangeNumber() ).append( "\n" );
+            super( result.getName(), result.getClassName(), result.getObject(), result.getAttributes(), result
+                .isRelative() );
+            this.control = control;
         }
-
-        return buf.toString();
+    
+    
+        public String toString()
+        {
+            StringBuffer buf = new StringBuffer();
+            buf.append( "Dn: " ).append( getName() ).append( "\n" );
+    
+            if ( control != null )
+            {
+                buf.append( "    EntryChangeControl =\n" );
+                buf.append( "       changeType   : " ).append( control.getChangeType() ).append( "\n" );
+                buf.append( "       previousDN   : " ).append( control.getPreviousDn() ).append( "\n" );
+                buf.append( "       changeNumber : " ).append( control.getChangeNumber() ).append( "\n" );
+            }
+    
+            return buf.toString();
+        }
     }
 }
-}
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchIT.java
index 1cfe006..4956df9 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.search;
 
@@ -45,6 +45,7 @@
 import javax.naming.ldap.LdapContext;
 import javax.naming.ldap.ManageReferralControl;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
@@ -54,6 +55,7 @@
 import org.apache.directory.shared.ldap.model.ldif.LdifEntry;
 import org.apache.directory.shared.ldap.model.ldif.LdifReader;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -124,6 +126,9 @@
 })
 public class ReferralSearchIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+
     @Before
     public void setupReferrals() throws Exception
     {
@@ -255,7 +260,7 @@
         assertNotNull( results.get( "ou=users" ) );
     
         // -------------------------------------------------------------------
-        // Now we will throw exceptions when searching for referrals 
+        // Now we will throw exceptions when searching for referrals
         // -------------------------------------------------------------------
     
         ctx.addToEnvironment( Context.REFERRAL, "throw" );
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchMoveAndRenameIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchMoveAndRenameIT.java
index 2ec4a98..8ccbdb9 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchMoveAndRenameIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchMoveAndRenameIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.search;
 
@@ -34,6 +34,7 @@
 import javax.naming.ldap.LdapContext;
 import javax.naming.ldap.ManageReferralControl;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
@@ -43,6 +44,7 @@
 import org.apache.directory.shared.ldap.model.ldif.LdifEntry;
 import org.apache.directory.shared.ldap.model.ldif.LdifReader;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -113,86 +115,89 @@
 })
 public class ReferralSearchMoveAndRenameIT extends AbstractLdapTestUnit
 {
-@Before
-public void setupReferrals() throws Exception
-{
-    getLdapServer().getDirectoryService().getChangeLog().setEnabled( false );
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
 
-    String ldif =
-        "dn: c=europ,ou=Countries,ou=system\n" +
-            "objectClass: top\n" +
-            "objectClass: referral\n" +
-            "objectClass: extensibleObject\n" +
-            "c: europ\n" +
-            "ref: ldap://localhost:" + getLdapServer().getPort() + "/c=france,ou=system\n\n" +
-
-            "dn: c=america,ou=Countries,ou=system\n" +
-            "objectClass: top\n" +
-            "objectClass: referral\n" +
-            "objectClass: extensibleObject\n" +
-            "c: america\n" +
-            "ref: ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system\n\n";
-
-    LdifReader reader = new LdifReader( new StringReader( ldif ) );
-
-    while ( reader.hasNext() )
+    @Before
+    public void setupReferrals() throws Exception
     {
-        LdifEntry entry = reader.next();
-        getLdapServer().getDirectoryService().getAdminSession().add(
-            new DefaultEntry( getLdapServer().getDirectoryService().getSchemaManager(), entry.getEntry() ) );
+        getLdapServer().getDirectoryService().getChangeLog().setEnabled( false );
+    
+        String ldif =
+            "dn: c=europ,ou=Countries,ou=system\n" +
+                "objectClass: top\n" +
+                "objectClass: referral\n" +
+                "objectClass: extensibleObject\n" +
+                "c: europ\n" +
+                "ref: ldap://localhost:" + getLdapServer().getPort() + "/c=france,ou=system\n\n" +
+    
+                "dn: c=america,ou=Countries,ou=system\n" +
+                "objectClass: top\n" +
+                "objectClass: referral\n" +
+                "objectClass: extensibleObject\n" +
+                "c: america\n" +
+                "ref: ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system\n\n";
+    
+        LdifReader reader = new LdifReader( new StringReader( ldif ) );
+    
+        while ( reader.hasNext() )
+        {
+            LdifEntry entry = reader.next();
+            getLdapServer().getDirectoryService().getAdminSession().add(
+                new DefaultEntry( getLdapServer().getDirectoryService().getSchemaManager(), entry.getEntry() ) );
+        }
     }
-}
-
-
-/**
- * Test of an search operation with a referral after the entry
- * has been moved.
- *
- * search for "cn=alex karasulu" on "c=usa, ou=system"
- * we should get a referral URL thrown, which point to
- * "c=usa, ou=system", and ask for a subtree search
- */
-@Test
-public void testSearchBaseWithReferralThrowAfterMoveAndRename() throws Exception
-{
-    DirContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
-
-    SearchControls controls = new SearchControls();
-    controls.setSearchScope( SearchControls.OBJECT_SCOPE );
-
-    try
+    
+    
+    /**
+     * Test of an search operation with a referral after the entry
+     * has been moved.
+     *
+     * search for "cn=alex karasulu" on "c=usa, ou=system"
+     * we should get a referral URL thrown, which point to
+     * "c=usa, ou=system", and ask for a subtree search
+     */
+    @Test
+    public void testSearchBaseWithReferralThrowAfterMoveAndRename() throws Exception
     {
-        ctx.search( "c=america,ou=Countries,ou=system", "(cn=alex karasulu)", controls );
-        fail( "Should fail here throwing a ReferralException" );
+        DirContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
+    
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope( SearchControls.OBJECT_SCOPE );
+    
+        try
+        {
+            ctx.search( "c=america,ou=Countries,ou=system", "(cn=alex karasulu)", controls );
+            fail( "Should fail here throwing a ReferralException" );
+        }
+        catch ( ReferralException re )
+        {
+            String referral = ( String ) re.getReferralInfo();
+            assertEquals( "ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system??base", referral );
+        }
+    
+        ( ( LdapContext ) ctx ).setRequestControls( new javax.naming.ldap.Control[]
+            { new ManageReferralControl() } );
+    
+        // Now let's move the entry
+        ctx.rename( "c=america,ou=Countries,ou=system", "c=us,ou=system" );
+    
+        controls.setSearchScope( SearchControls.OBJECT_SCOPE );
+    
+        ( ( LdapContext ) ctx ).setRequestControls( new javax.naming.ldap.Control[]
+            {} );
+    
+        try
+        {
+            NamingEnumeration<SearchResult> results = ctx.search( "c=us,ou=system", "(cn=alex karasulu)", controls );
+    
+            results.next();
+            fail( "Should fail here throwing a ReferralException" );
+        }
+        catch ( ReferralException re )
+        {
+            String referral = ( String ) re.getReferralInfo();
+            assertEquals( "ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system??base", referral );
+        }
     }
-    catch ( ReferralException re )
-    {
-        String referral = ( String ) re.getReferralInfo();
-        assertEquals( "ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system??base", referral );
-    }
-
-    ( ( LdapContext ) ctx ).setRequestControls( new javax.naming.ldap.Control[]
-        { new ManageReferralControl() } );
-
-    // Now let's move the entry
-    ctx.rename( "c=america,ou=Countries,ou=system", "c=us,ou=system" );
-
-    controls.setSearchScope( SearchControls.OBJECT_SCOPE );
-
-    ( ( LdapContext ) ctx ).setRequestControls( new javax.naming.ldap.Control[]
-        {} );
-
-    try
-    {
-        NamingEnumeration<SearchResult> results = ctx.search( "c=us,ou=system", "(cn=alex karasulu)", controls );
-
-        results.next();
-        fail( "Should fail here throwing a ReferralException" );
-    }
-    catch ( ReferralException re )
-    {
-        String referral = ( String ) re.getReferralInfo();
-        assertEquals( "ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system??base", referral );
-    }
-}
 }
\ No newline at end of file
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchNoRevertIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchNoRevertIT.java
index dc942a3..c3b0edf 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchNoRevertIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/ReferralSearchNoRevertIT.java
@@ -6,16 +6,16 @@
  *  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. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.directory.server.operations.search;
 
@@ -32,6 +32,7 @@
 import javax.naming.ldap.LdapContext;
 import javax.naming.ldap.ManageReferralControl;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
@@ -46,6 +47,7 @@
 import org.apache.directory.shared.ldap.model.ldif.LdifReader;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -136,91 +138,93 @@
 })
 public class ReferralSearchNoRevertIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
 
-@Before
-public void setupReferrals() throws Exception
-{
-    getLdapServer().getDirectoryService().getChangeLog().setEnabled( false );
-
-    String ldif =
-        "dn: c=europ,ou=Countries,ou=system\n" +
-            "objectClass: top\n" +
-            "objectClass: referral\n" +
-            "objectClass: extensibleObject\n" +
-            "c: europ\n" +
-            "ref: ldap://localhost:" + getLdapServer().getPort() + "/c=france,ou=system\n\n" +
-
-            "dn: c=america,ou=Countries,ou=system\n" +
-            "objectClass: top\n" +
-            "objectClass: referral\n" +
-            "objectClass: extensibleObject\n" +
-            "c: america\n" +
-            "ref: ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system\n\n";
-
-    LdifReader reader = new LdifReader( new StringReader( ldif ) );
-    while ( reader.hasNext() )
+    @Before
+    public void setupReferrals() throws Exception
     {
-        LdifEntry entry = reader.next();
-        getLdapServer().getDirectoryService().getAdminSession().add(
-            new DefaultEntry( getLdapServer().getDirectoryService().getSchemaManager(), entry.getEntry() ) );
+        getLdapServer().getDirectoryService().getChangeLog().setEnabled( false );
+    
+        String ldif =
+            "dn: c=europ,ou=Countries,ou=system\n" +
+                "objectClass: top\n" +
+                "objectClass: referral\n" +
+                "objectClass: extensibleObject\n" +
+                "c: europ\n" +
+                "ref: ldap://localhost:" + getLdapServer().getPort() + "/c=france,ou=system\n\n" +
+    
+                "dn: c=america,ou=Countries,ou=system\n" +
+                "objectClass: top\n" +
+                "objectClass: referral\n" +
+                "objectClass: extensibleObject\n" +
+                "c: america\n" +
+                "ref: ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system\n\n";
+    
+        LdifReader reader = new LdifReader( new StringReader( ldif ) );
+        while ( reader.hasNext() )
+        {
+            LdifEntry entry = reader.next();
+            getLdapServer().getDirectoryService().getAdminSession().add(
+                new DefaultEntry( getLdapServer().getDirectoryService().getSchemaManager(), entry.getEntry() ) );
+        }
     }
-}
-
-
-/**
- * Test of an search operation with a referral after the entry
- * has been moved.
- *
- * search for "cn=alex karasulu" on "c=america, ou=system"
- * we should get a referral URL thrown, which point to
- * "c=usa, ou=system", and ask for a subtree search
- */
-@Test
-public void testSearchBaseWithReferralThrowAfterMove() throws Exception
-{
-    DirContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
-
-    SearchControls controls = new SearchControls();
-    controls.setSearchScope( SearchControls.OBJECT_SCOPE );
-
-    try
+    
+    
+    /**
+     * Test of an search operation with a referral after the entry
+     * has been moved.
+     *
+     * search for "cn=alex karasulu" on "c=america, ou=system"
+     * we should get a referral URL thrown, which point to
+     * "c=usa, ou=system", and ask for a subtree search
+     */
+    @Test
+    public void testSearchBaseWithReferralThrowAfterMove() throws Exception
     {
-        ctx.search( "c=america,ou=Countries,ou=system", "(cn=alex karasulu)", controls );
-        fail( "Should fail here throwing a ReferralException" );
+        DirContext ctx = getWiredContextThrowOnRefferal( getLdapServer() );
+    
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope( SearchControls.OBJECT_SCOPE );
+    
+        try
+        {
+            ctx.search( "c=america,ou=Countries,ou=system", "(cn=alex karasulu)", controls );
+            fail( "Should fail here throwing a ReferralException" );
+        }
+        catch ( ReferralException re )
+        {
+            String referral = ( String ) re.getReferralInfo();
+            assertEquals( "ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system??base", referral );
+        }
+    
+        ( ( LdapContext ) ctx ).setRequestControls( new javax.naming.ldap.Control[]
+            { new ManageReferralControl() } );
+    
+        // Now let's move the entry
+        ctx.rename( "c=america,ou=Countries,ou=system", "c=america,ou=system" );
+    
+        controls.setSearchScope( SearchControls.OBJECT_SCOPE );
+    
+        ( ( LdapContext ) ctx ).setRequestControls( new javax.naming.ldap.Control[]
+            {} );
+    
+        try
+        {
+            ctx.search( "c=america,ou=system", "(cn=alex karasulu)", controls );
+            fail( "Should fail here throwing a ReferralException" );
+        }
+        catch ( ReferralException re )
+        {
+            String referral = ( String ) re.getReferralInfo();
+            assertEquals( "ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system??base", referral );
+        }
     }
-    catch ( ReferralException re )
+    
+    
+    @After
+    public void after()
     {
-        String referral = ( String ) re.getReferralInfo();
-        assertEquals( "ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system??base", referral );
+        getLdapServer().getDirectoryService().getChangeLog().setEnabled( true );
     }
-
-    ( ( LdapContext ) ctx ).setRequestControls( new javax.naming.ldap.Control[]
-        { new ManageReferralControl() } );
-
-    // Now let's move the entry
-    ctx.rename( "c=america,ou=Countries,ou=system", "c=america,ou=system" );
-
-    controls.setSearchScope( SearchControls.OBJECT_SCOPE );
-
-    ( ( LdapContext ) ctx ).setRequestControls( new javax.naming.ldap.Control[]
-        {} );
-
-    try
-    {
-        ctx.search( "c=america,ou=system", "(cn=alex karasulu)", controls );
-        fail( "Should fail here throwing a ReferralException" );
-    }
-    catch ( ReferralException re )
-    {
-        String referral = ( String ) re.getReferralInfo();
-        assertEquals( "ldap://localhost:" + getLdapServer().getPort() + "/c=usa,ou=system??base", referral );
-    }
-}
-
-
-@After
-public void after()
-{
-    getLdapServer().getDirectoryService().getChangeLog().setEnabled( true );
-}
 }
\ No newline at end of file
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/SchemaSearchIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/SchemaSearchIT.java
index d3b58a1..83b13bf 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/search/SchemaSearchIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/SchemaSearchIT.java
@@ -35,11 +35,13 @@
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -166,197 +168,199 @@
 })
 public class SchemaSearchIT extends AbstractLdapTestUnit
 {
-private static final String DN = "cn=schema";
-private static final String FILTER = "(objectclass=subschema)";
-
-
-protected void checkForAttributes( Attributes attrs, String[] attrNames )
-{
-    for ( int i = 0; i < attrNames.length; i++ )
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    private static final String DN = "cn=schema";
+    private static final String FILTER = "(objectclass=subschema)";
+    
+    
+    protected void checkForAttributes( Attributes attrs, String[] attrNames )
     {
-        String attrName = attrNames[i];
-
-        assertNotNull( "Check if attr " + attrName + " is present", attrs.get( attrNames[i] ) );
-    }
-}
-
-
-/**
- * Check if modifyTimestamp and createTimestamp are present in the search result,
- * if they are requested.
- */
-@Test
-public void testRequestOperationalAttributes() throws Exception
-{
-    DirContext ctx = getWiredContext( getLdapServer() );
-    SearchControls ctls = new SearchControls();
-
-    String[] attrNames =
-        { "creatorsName", "createTimestamp", "modifiersName", "modifyTimestamp" };
-
-    ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
-    ctls.setReturningAttributes( attrNames );
-
-    NamingEnumeration<SearchResult> result = ctx.search( DN, FILTER, ctls );
-
-    if ( result.hasMore() )
-    {
-        SearchResult entry = result.next();
-        checkForAttributes( entry.getAttributes(), attrNames );
-    }
-    else
-    {
-        fail( "entry " + DN + " not found" );
-    }
-
-    result.close();
-}
-
-
-/**
- * Check if modifyTimestamp and createTimestamp are present in the search result,
- * if + is requested.
- */
-@Test
-public void testRequestAllOperationalAttributes() throws Exception
-{
-    DirContext ctx = getWiredContext( getLdapServer() );
-    SearchControls ctls = new SearchControls();
-
-    ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
-    ctls.setReturningAttributes( new String[]
-        { "+" } );
-
-    NamingEnumeration<SearchResult> result = ctx.search( DN, FILTER, ctls );
-
-    if ( result.hasMore() )
-    {
-        SearchResult entry = result.next();
-        String[] attrNames =
-            { "creatorsName", "createTimestamp", "modifiersName", "modifyTimestamp" };
-        checkForAttributes( entry.getAttributes(), attrNames );
-    }
-    else
-    {
-        fail( "entry " + DN + " not found" );
-    }
-
-    result.close();
-}
-
-
-/**
- * Test case for DIRSERVER-1083: Search on an custom attribute added to
- * the dynamic schema fails when no result is found.
- */
-@Test
-public void testSearchingNewSchemaElements() throws Exception
-{
-    DirContext ctx = getWiredContext( getLdapServer() );
-
-    // create an entry with the schema objectClass personActiveDirectory
-    Attributes person = new BasicAttributes( "objectClass", "top", true );
-    person.get( "objectClass" ).add( "person" );
-    person.get( "objectClass" ).add( "personActiveDirectory" );
-    person.put( "cn", "foobar" );
-    person.put( "sn", "bar" );
-    person.put( "pwdLastSet", "3" );
-    person.put( "SourceAD", "blah" );
-    person.put( "useraccountcontrol", "7" );
-    person.put( "sAMAccountName", "foobar" );
-    ctx.createSubcontext( "cn=foobar,ou=system", person );
-
-    // Confirm creation with a lookup
-    Attributes read = ctx.getAttributes( "cn=foobar,ou=system" );
-    assertNotNull( read );
-    assertEquals( "3", read.get( "pwdLastSet" ).get() );
-
-    // Now search for foobar with pwdLastSet value of 3
-    SearchControls searchControls = new SearchControls();
-    searchControls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
-    NamingEnumeration<SearchResult> results = ctx.search( "ou=system", "(pwdLastSet=3)", searchControls );
-    assertTrue( results.hasMore() );
-    SearchResult result = results.next();
-    assertNotNull( result );
-    assertEquals( "cn=foobar", result.getName() );
-    Attributes attributes = result.getAttributes();
-    assertEquals( "3", attributes.get( "pwdLastSet" ).get() );
-    results.close();
-
-    // Now search with bogus value for pwdLastSet
-    results = ctx.search( "ou=system", "(pwdLastSet=300)", searchControls );
-    assertFalse( results.hasMore() );
-    results.close();
-}
-
-
-/**
- * Test case for DIRSERVER-: Ensure that schema entry is returned,
- * even if no ManageDsaIT decorator is present in the search request.
- */
-@Test
-public void testRequestWithoutManageDsaITControl() throws Exception
-{
-    DirContext ctx = getWiredContext( getLdapServer() );
-
-    // this removes the ManageDsaIT decorator from the search request
-    ctx.addToEnvironment( DirContext.REFERRAL, "throw" );
-
-    SearchControls ctls = new SearchControls();
-    String[] attrNames =
-        { "objectClasses", "attributeTypes", "ldapSyntaxes", "matchingRules", "matchingRuleUse", "createTimestamp",
-            "modifyTimestamp" };
-    ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
-    ctls.setReturningAttributes( attrNames );
-
-    NamingEnumeration<SearchResult> result = ctx.search( DN, FILTER, ctls );
-
-    if ( result.hasMore() )
-    {
-        SearchResult entry = result.next();
-        checkForAttributes( entry.getAttributes(), attrNames );
-    }
-    else
-    {
-        fail( "entry " + DN + " not found" );
-    }
-
-    result.close();
-}
-
-
-/**
- * Test a search done on cn=schema
- */
-@Test
-public void testSubSchemaSubEntrySearch() throws Exception
-{
-    DirContext ctx = getWiredContext( getLdapServer() );
-
-    SearchControls searchControls = new SearchControls();
-    searchControls.setSearchScope( SearchControls.OBJECT_SCOPE );
-    searchControls.setReturningAttributes( new String[]
-        { "objectClasses" } );
-    NamingEnumeration<SearchResult> results = ctx.search( "cn=schema", "(ObjectClass=*)", searchControls );
-
-    assertTrue( results.hasMore() );
-    SearchResult result = results.next();
-    Attributes entry = result.getAttributes();
-
-    Attribute objectClasses = entry.get( "objectClasses" );
-    NamingEnumeration<?> ocs = objectClasses.getAll();
-
-    while ( ocs.hasMore() )
-    {
-        String oc = ( String ) ocs.nextElement();
-        if ( oc.startsWith( "( 2.5.6.6" ) )
+        for ( int i = 0; i < attrNames.length; i++ )
         {
-            assertEquals(
-                "( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL MUST ( sn $ cn ) MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) X-SCHEMA 'core' )",
-                oc );
+            String attrName = attrNames[i];
+    
+            assertNotNull( "Check if attr " + attrName + " is present", attrs.get( attrNames[i] ) );
         }
     }
-
-    results.close();
-}
+    
+    
+    /**
+     * Check if modifyTimestamp and createTimestamp are present in the search result,
+     * if they are requested.
+     */
+    @Test
+    public void testRequestOperationalAttributes() throws Exception
+    {
+        DirContext ctx = getWiredContext( getLdapServer() );
+        SearchControls ctls = new SearchControls();
+    
+        String[] attrNames =
+            { "creatorsName", "createTimestamp", "modifiersName", "modifyTimestamp" };
+    
+        ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+        ctls.setReturningAttributes( attrNames );
+    
+        NamingEnumeration<SearchResult> result = ctx.search( DN, FILTER, ctls );
+    
+        if ( result.hasMore() )
+        {
+            SearchResult entry = result.next();
+            checkForAttributes( entry.getAttributes(), attrNames );
+        }
+        else
+        {
+            fail( "entry " + DN + " not found" );
+        }
+    
+        result.close();
+    }
+    
+    
+    /**
+     * Check if modifyTimestamp and createTimestamp are present in the search result,
+     * if + is requested.
+     */
+    @Test
+    public void testRequestAllOperationalAttributes() throws Exception
+    {
+        DirContext ctx = getWiredContext( getLdapServer() );
+        SearchControls ctls = new SearchControls();
+    
+        ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+        ctls.setReturningAttributes( new String[]
+            { "+" } );
+    
+        NamingEnumeration<SearchResult> result = ctx.search( DN, FILTER, ctls );
+    
+        if ( result.hasMore() )
+        {
+            SearchResult entry = result.next();
+            String[] attrNames =
+                { "creatorsName", "createTimestamp", "modifiersName", "modifyTimestamp" };
+            checkForAttributes( entry.getAttributes(), attrNames );
+        }
+        else
+        {
+            fail( "entry " + DN + " not found" );
+        }
+    
+        result.close();
+    }
+    
+    
+    /**
+     * Test case for DIRSERVER-1083: Search on an custom attribute added to
+     * the dynamic schema fails when no result is found.
+     */
+    @Test
+    public void testSearchingNewSchemaElements() throws Exception
+    {
+        DirContext ctx = getWiredContext( getLdapServer() );
+    
+        // create an entry with the schema objectClass personActiveDirectory
+        Attributes person = new BasicAttributes( "objectClass", "top", true );
+        person.get( "objectClass" ).add( "person" );
+        person.get( "objectClass" ).add( "personActiveDirectory" );
+        person.put( "cn", "foobar" );
+        person.put( "sn", "bar" );
+        person.put( "pwdLastSet", "3" );
+        person.put( "SourceAD", "blah" );
+        person.put( "useraccountcontrol", "7" );
+        person.put( "sAMAccountName", "foobar" );
+        ctx.createSubcontext( "cn=foobar,ou=system", person );
+    
+        // Confirm creation with a lookup
+        Attributes read = ctx.getAttributes( "cn=foobar,ou=system" );
+        assertNotNull( read );
+        assertEquals( "3", read.get( "pwdLastSet" ).get() );
+    
+        // Now search for foobar with pwdLastSet value of 3
+        SearchControls searchControls = new SearchControls();
+        searchControls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+        NamingEnumeration<SearchResult> results = ctx.search( "ou=system", "(pwdLastSet=3)", searchControls );
+        assertTrue( results.hasMore() );
+        SearchResult result = results.next();
+        assertNotNull( result );
+        assertEquals( "cn=foobar", result.getName() );
+        Attributes attributes = result.getAttributes();
+        assertEquals( "3", attributes.get( "pwdLastSet" ).get() );
+        results.close();
+    
+        // Now search with bogus value for pwdLastSet
+        results = ctx.search( "ou=system", "(pwdLastSet=300)", searchControls );
+        assertFalse( results.hasMore() );
+        results.close();
+    }
+    
+    
+    /**
+     * Test case for DIRSERVER-: Ensure that schema entry is returned,
+     * even if no ManageDsaIT decorator is present in the search request.
+     */
+    @Test
+    public void testRequestWithoutManageDsaITControl() throws Exception
+    {
+        DirContext ctx = getWiredContext( getLdapServer() );
+    
+        // this removes the ManageDsaIT decorator from the search request
+        ctx.addToEnvironment( DirContext.REFERRAL, "throw" );
+    
+        SearchControls ctls = new SearchControls();
+        String[] attrNames =
+            { "objectClasses", "attributeTypes", "ldapSyntaxes", "matchingRules", "matchingRuleUse", "createTimestamp",
+                "modifyTimestamp" };
+        ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+        ctls.setReturningAttributes( attrNames );
+    
+        NamingEnumeration<SearchResult> result = ctx.search( DN, FILTER, ctls );
+    
+        if ( result.hasMore() )
+        {
+            SearchResult entry = result.next();
+            checkForAttributes( entry.getAttributes(), attrNames );
+        }
+        else
+        {
+            fail( "entry " + DN + " not found" );
+        }
+    
+        result.close();
+    }
+    
+    
+    /**
+     * Test a search done on cn=schema
+     */
+    @Test
+    public void testSubSchemaSubEntrySearch() throws Exception
+    {
+        DirContext ctx = getWiredContext( getLdapServer() );
+    
+        SearchControls searchControls = new SearchControls();
+        searchControls.setSearchScope( SearchControls.OBJECT_SCOPE );
+        searchControls.setReturningAttributes( new String[]
+            { "objectClasses" } );
+        NamingEnumeration<SearchResult> results = ctx.search( "cn=schema", "(ObjectClass=*)", searchControls );
+    
+        assertTrue( results.hasMore() );
+        SearchResult result = results.next();
+        Attributes entry = result.getAttributes();
+    
+        Attribute objectClasses = entry.get( "objectClasses" );
+        NamingEnumeration<?> ocs = objectClasses.getAll();
+    
+        while ( ocs.hasMore() )
+        {
+            String oc = ( String ) ocs.nextElement();
+            if ( oc.startsWith( "( 2.5.6.6" ) )
+            {
+                assertEquals(
+                    "( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL MUST ( sn $ cn ) MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) X-SCHEMA 'core' )",
+                    oc );
+            }
+        }
+    
+        results.close();
+    }
 }
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchIT.java
index 5373a70..eee7a3f 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchIT.java
@@ -46,6 +46,7 @@
 import javax.naming.directory.SearchResult;
 import javax.naming.ldap.LdapContext;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.LdapNetworkConnection;
 import org.apache.directory.server.annotations.CreateLdapServer;
@@ -69,6 +70,7 @@
 import org.apache.directory.shared.ldap.model.name.Dn;
 import org.apache.directory.shared.ldap.util.JndiUtils;
 import org.junit.Ignore;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -183,6 +185,8 @@
 })
 public class SearchIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
     private static final String BASE = "ou=system";
     
     //public static LdapServer getLdapServer();
@@ -1708,6 +1712,8 @@
         {
             ++i;
         }
+        
+        cursor.close();
     
         assertEquals( sizeLimit, i );
         connection.close();
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchLimitsIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchLimitsIT.java
index 7c3556f..6bb8afa 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchLimitsIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchLimitsIT.java
@@ -35,6 +35,7 @@
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
@@ -51,6 +52,7 @@
 import org.apache.directory.shared.ldap.model.exception.LdapException;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -121,373 +123,375 @@
 })
 public class SearchLimitsIT extends AbstractLdapTestUnit
 {
-
-/**
- * An {@link Interceptor} that fakes a specified amount of delay to each
- * search iteration so we can make sure search time limits are adhered to.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-class DelayInducingInterceptor extends BaseInterceptor
-{
-    private Long delayMillis;
-
-
-    public DelayInducingInterceptor()
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+    
+    /**
+     * An {@link Interceptor} that fakes a specified amount of delay to each
+     * search iteration so we can make sure search time limits are adhered to.
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     */
+    class DelayInducingInterceptor extends BaseInterceptor
     {
-        super( "DelayInterceptor" );
-    }
-
-
-    public EntryFilteringCursor search( SearchOperationContext searchContext ) throws LdapException
-    {
-        EntryFilteringCursor cursor = next( searchContext );
-        cursor.addEntryFilter( new EntryFilter()
+        private Long delayMillis;
+    
+    
+        public DelayInducingInterceptor()
         {
-            public boolean accept( SearchingOperationContext operation, Entry result ) throws Exception
-            {
-                if ( delayMillis != null )
-                {
-                    Thread.sleep( delayMillis );
-                }
-
-                return true;
-            }
-        } );
-
-        return cursor;
-    }
-
-
-    public void setDelayMillis( long delayMillis )
-    {
-        if ( delayMillis <= 0 )
-        {
-            this.delayMillis = null;
+            super( "DelayInterceptor" );
         }
-
-        this.delayMillis = delayMillis;
+    
+    
+        public EntryFilteringCursor search( SearchOperationContext searchContext ) throws LdapException
+        {
+            EntryFilteringCursor cursor = next( searchContext );
+            cursor.addEntryFilter( new EntryFilter()
+            {
+                public boolean accept( SearchingOperationContext operation, Entry result ) throws Exception
+                {
+                    if ( delayMillis != null )
+                    {
+                        Thread.sleep( delayMillis );
+                    }
+    
+                    return true;
+                }
+            } );
+    
+            return cursor;
+        }
+    
+    
+        public void setDelayMillis( long delayMillis )
+        {
+            if ( delayMillis <= 0 )
+            {
+                this.delayMillis = null;
+            }
+    
+            this.delayMillis = delayMillis;
+        }
     }
-}
-
-private int oldMaxTimeLimit;
-private long oldMaxSizeLimit;
-private DelayInducingInterceptor delayInterceptor;
-
-
-@Before
-public void setUp() throws Exception
-{
-    oldMaxTimeLimit = getLdapServer().getMaxTimeLimit();
-    oldMaxSizeLimit = getLdapServer().getMaxSizeLimit();
-    delayInterceptor = new DelayInducingInterceptor();
-    getLdapServer().getDirectoryService().addFirst( delayInterceptor );
-}
-
-
-@After
-public void tearDown() throws Exception
-{
-    getLdapServer().setMaxTimeLimit( oldMaxTimeLimit );
-    getLdapServer().setMaxSizeLimit( oldMaxSizeLimit );
-    getLdapServer().getDirectoryService().remove( "DelayInterceptor" );
-}
-
-
-// -----------------------------------------------------------------------
-// Time Limit Tests
-// -----------------------------------------------------------------------
-
-/**
- * Sets up the server with unlimited search time limit but constrains time
- * by request time limit value to cause a time limit exceeded exception on
- * the client.
- */
-@Test(expected = TimeLimitExceededException.class)
-public void testRequestConstrainedUnlimitByConfiguration() throws Exception
-{
-    getLdapServer().setMaxTimeLimit( LdapServer.NO_TIME_LIMIT );
-    delayInterceptor.setDelayMillis( 500 );
-
-    getActorsWithLimit( "(objectClass=*)", 499, LdapServer.NO_SIZE_LIMIT );
-}
-
-
-/**
- * Sets up the server with longer search time limit than the request's
- * which constrains time by request time limit value to cause a time limit
- * exceeded exception on the client.
- */
-@Test(expected = TimeLimitExceededException.class)
-public void testRequestConstrainedLessThanConfiguration() throws Exception
-{
-    getLdapServer().setMaxTimeLimit( 10000 ); // this is in seconds
-    delayInterceptor.setDelayMillis( 500 );
-
-    getActorsWithLimit( "(objectClass=*)", 499, LdapServer.NO_SIZE_LIMIT );
-}
-
-
-/**
- * Sets up the server with shorter search time limit than the request's
- * which constrains time by using server max limit value to cause a time
- * limit exceeded exception on the client.
- */
-@Test(expected = TimeLimitExceededException.class)
-public void testRequestConstrainedGreaterThanConfiguration() throws Exception
-{
-    getLdapServer().setMaxTimeLimit( 1 ); // this is in seconds
-    delayInterceptor.setDelayMillis( 1100 );
-
-    getActorsWithLimit( "(objectClass=*)", 100000, LdapServer.NO_SIZE_LIMIT );
-}
-
-
-/**
- * Sets up the server with limited search time with unlimited request
- * time limit.  Should work just fine for the administrative user.
- */
-@Test
-public void testRequestUnlimitedConfigurationLimited() throws Exception
-{
-    getLdapServer().setMaxTimeLimit( 1 ); // this is in seconds
-    delayInterceptor.setDelayMillis( 500 );
-
-    getActorsWithLimit( "(objectClass=*)",
-        LdapServer.NO_TIME_LIMIT, LdapServer.NO_SIZE_LIMIT );
-}
-
-
-/**
- * Sets up the server with limited search time with unlimited request
- * time limit.  Should not work for non administrative users.
- */
-@Test(expected = TimeLimitExceededException.class)
-public void testNonAdminRequestUnlimitedConfigurationLimited() throws Exception
-{
-    getLdapServer().setMaxTimeLimit( 1 ); // this is in seconds
-    delayInterceptor.setDelayMillis( 500 );
-
-    getActorsWithLimitNonAdmin( "(objectClass=*)",
-        LdapServer.NO_TIME_LIMIT, LdapServer.NO_SIZE_LIMIT );
-}
-
-
-// -----------------------------------------------------------------------
-// Size Limit Tests
-// -----------------------------------------------------------------------
-
-/**
- * Sets up the server with unlimited search size limit but constrains size
- * by request size limit value to cause a size limit exceeded exception on
- * the client.
- */
-@Test(expected = SizeLimitExceededException.class)
-public void testRequestConstrainedUnlimitByConfigurationSize() throws Exception
-{
-    getLdapServer().setMaxSizeLimit( LdapServer.NO_SIZE_LIMIT );
-
-    getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 1 );
-}
-
-
-/**
- * Sets up the server with longer search size limit than the request's
- * which constrains size by request size limit value to cause a size limit
- * exceeded exception on the client.
- */
-@Test(expected = SizeLimitExceededException.class)
-public void testRequestConstrainedLessThanConfigurationSize() throws Exception
-{
-    getLdapServer().setMaxSizeLimit( 10000 );
-
-    getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 1 );
-}
-
-
-/**
- * Sets up the server with shorter search size limit than the request's
- * which constrains size by using server max limit value. Should work
- * just fine for the administrative user.
- */
-@Test
-public void testRequestConstrainedGreaterThanConfigurationSize() throws Exception
-{
-    getLdapServer().setMaxSizeLimit( 1 );
-    Set<String> set = getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 100000 );
-    assertEquals( 4, set.size() );
-}
-
-
-/**
- * Sets up the server with shorter search size limit than the request's
- * which constrains size by using server max limit value to cause a size
- * limit exceeded exception on the client.
- */
-@Test(expected = SizeLimitExceededException.class)
-public void testNonAdminRequestConstrainedGreaterThanConfigurationSize() throws Exception
-{
-    getLdapServer().setMaxSizeLimit( 1 );
-
-    // We are not using the admin : it should fail
-    getActorsWithLimitNonAdmin( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 100000 );
-}
-
-
-/**
- * Sets up the server with limited search size with unlimited request
- * size limit.  Should work just fine for the administrative user.
- */
-@Test
-public void testRequestUnlimitedConfigurationLimitedSize() throws Exception
-{
-    getLdapServer().setMaxSizeLimit( 1 );
-    Set<String> set = getActorsWithLimit( "(objectClass=*)",
-        LdapServer.NO_TIME_LIMIT, LdapServer.NO_SIZE_LIMIT );
-
-    assertEquals( 4, set.size() );
-}
-
-
-/**
- * Sets up the server with limited search size with unlimited request
- * size limit.  Should not work for non administrative users.
- */
-@Test(expected = SizeLimitExceededException.class)
-public void testNonAdminRequestUnlimitedConfigurationLimitedSize() throws Exception
-{
-    getLdapServer().setMaxSizeLimit( 1 );
-    getActorsWithLimitNonAdmin( "(objectClass=*)",
-        LdapServer.NO_TIME_LIMIT, LdapServer.NO_SIZE_LIMIT );
-}
-
-
-/**
- * Test for DIRSERVER-1235.
- * Sets up the server with unlimited search size limit but constrains size
- * by request size limit value. The request size limit is less than the
- * expected number of result entries, so exception expected.
- * 
- * cf RFC 4511 :
- *  "sizeLimitExceeded (4)
- *   Indicates that the size limit specified by the client was
- *   exceeded before the operation could be completed."
- */
-@Test(expected = SizeLimitExceededException.class)
-public void testRequestConstraintedLessThanExpectedSize() throws Exception
-{
-    getLdapServer().setMaxSizeLimit( LdapServer.NO_SIZE_LIMIT );
-
-    getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 3 );
-}
-
-
-/**
- * Test for DIRSERVER-1235.
- * Sets up the server with unlimited search size limit but constrains size
- * by request size limit value. The request size limit is equal to the
- * expected number of result entries so no exception expected.
- */
-@Test
-public void testRequestConstraintedEqualToExpectedSize() throws Exception
-{
-    getLdapServer().setMaxSizeLimit( LdapServer.NO_SIZE_LIMIT );
-    Set<String> set = getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 4 );
-    assertEquals( 4, set.size() );
-}
-
-
-/**
- * Test for DIRSERVER-1235.
- * Sets up the server with unlimited search size limit but constrains size
- * by request size limit value. The request size limit is greater than the
- * expected number of result entries so no exception expected.
- */
-@Test
-public void testRequestConstraintedGreaterThanExpectedSize() throws Exception
-{
-    getLdapServer().setMaxSizeLimit( LdapServer.NO_SIZE_LIMIT );
-    Set<String> set = getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 5 );
-    assertEquals( 4, set.size() );
-}
-
-
-/**
- * Test for DIRSERVER-1235.
- * Reads an entry using object scope and size limit 1, no exception
- * expected.
- */
-@Test
-public void testRequestObjectScopeAndSizeLimit() throws Exception
-{
-    getLdapServer().setMaxSizeLimit( LdapServer.NO_SIZE_LIMIT );
-
-    DirContext ctx = getWiredContext( getLdapServer() );
-    String filter = "(objectClass=*)";
-    SearchControls controls = new SearchControls();
-    controls.setTimeLimit( 0 );
-    controls.setCountLimit( 1 );
-    controls.setSearchScope( SearchControls.OBJECT_SCOPE );
-
-    NamingEnumeration<SearchResult> namingEnumeration =
-        ctx.search( "ou=actors,ou=system", filter, controls );
-    assertTrue( namingEnumeration.hasMore() );
-    namingEnumeration.next();
-    assertFalse( namingEnumeration.hasMore() );
-}
-
-
-// -----------------------------------------------------------------------
-// Utility Methods
-// -----------------------------------------------------------------------
-
-/**
- * Do a search request from the ou=actors,ou=system base, with a principal
- * which is the administrator.
- */
-private Set<String> getActorsWithLimit( String filter, int timeLimitMillis, long sizeLimit ) throws Exception
-{
-    DirContext ctx = getWiredContext( getLdapServer() );
-    Set<String> results = new HashSet<String>();
-    SearchControls controls = new SearchControls();
-    controls.setTimeLimit( timeLimitMillis );
-    controls.setCountLimit( sizeLimit );
-    controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
-
-    NamingEnumeration<SearchResult> namingEnumeration =
-        ctx.search( "ou=actors,ou=system", filter, controls );
-
-    while ( namingEnumeration.hasMore() )
+    
+    private int oldMaxTimeLimit;
+    private long oldMaxSizeLimit;
+    private DelayInducingInterceptor delayInterceptor;
+    
+    
+    @Before
+    public void setUp() throws Exception
     {
-        results.add( namingEnumeration.next().getNameInNamespace() );
+        oldMaxTimeLimit = getLdapServer().getMaxTimeLimit();
+        oldMaxSizeLimit = getLdapServer().getMaxSizeLimit();
+        delayInterceptor = new DelayInducingInterceptor();
+        getLdapServer().getDirectoryService().addFirst( delayInterceptor );
     }
-
-    return results;
-}
-
-
-/**
- * Do a search request from the ou=actors,ou=system base, with a principal
- * which is not the administrator.
- */
-private Set<String> getActorsWithLimitNonAdmin( String filter, int timeLimitMillis, long sizeLimit )
-    throws Exception
-{
-    DirContext ctx = getWiredContext( getLdapServer(), "uid=jblack,ou=actors,ou=system", "secret" );
-    Set<String> results = new HashSet<String>();
-    SearchControls controls = new SearchControls();
-    controls.setTimeLimit( timeLimitMillis );
-    controls.setCountLimit( sizeLimit );
-    controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
-
-    NamingEnumeration<SearchResult> namingEnumeration =
-        ctx.search( "ou=actors,ou=system", filter, controls );
-
-    while ( namingEnumeration.hasMore() )
+    
+    
+    @After
+    public void tearDown() throws Exception
     {
-        results.add( namingEnumeration.next().getNameInNamespace() );
+        getLdapServer().setMaxTimeLimit( oldMaxTimeLimit );
+        getLdapServer().setMaxSizeLimit( oldMaxSizeLimit );
+        getLdapServer().getDirectoryService().remove( "DelayInterceptor" );
     }
-
-    return results;
-}
+    
+    
+    // -----------------------------------------------------------------------
+    // Time Limit Tests
+    // -----------------------------------------------------------------------
+    
+    /**
+     * Sets up the server with unlimited search time limit but constrains time
+     * by request time limit value to cause a time limit exceeded exception on
+     * the client.
+     */
+    @Test(expected = TimeLimitExceededException.class)
+    public void testRequestConstrainedUnlimitByConfiguration() throws Exception
+    {
+        getLdapServer().setMaxTimeLimit( LdapServer.NO_TIME_LIMIT );
+        delayInterceptor.setDelayMillis( 500 );
+    
+        getActorsWithLimit( "(objectClass=*)", 499, LdapServer.NO_SIZE_LIMIT );
+    }
+    
+    
+    /**
+     * Sets up the server with longer search time limit than the request's
+     * which constrains time by request time limit value to cause a time limit
+     * exceeded exception on the client.
+     */
+    @Test(expected = TimeLimitExceededException.class)
+    public void testRequestConstrainedLessThanConfiguration() throws Exception
+    {
+        getLdapServer().setMaxTimeLimit( 10000 ); // this is in seconds
+        delayInterceptor.setDelayMillis( 500 );
+    
+        getActorsWithLimit( "(objectClass=*)", 499, LdapServer.NO_SIZE_LIMIT );
+    }
+    
+    
+    /**
+     * Sets up the server with shorter search time limit than the request's
+     * which constrains time by using server max limit value to cause a time
+     * limit exceeded exception on the client.
+     */
+    @Test(expected = TimeLimitExceededException.class)
+    public void testRequestConstrainedGreaterThanConfiguration() throws Exception
+    {
+        getLdapServer().setMaxTimeLimit( 1 ); // this is in seconds
+        delayInterceptor.setDelayMillis( 1100 );
+    
+        getActorsWithLimit( "(objectClass=*)", 100000, LdapServer.NO_SIZE_LIMIT );
+    }
+    
+    
+    /**
+     * Sets up the server with limited search time with unlimited request
+     * time limit.  Should work just fine for the administrative user.
+     */
+    @Test
+    public void testRequestUnlimitedConfigurationLimited() throws Exception
+    {
+        getLdapServer().setMaxTimeLimit( 1 ); // this is in seconds
+        delayInterceptor.setDelayMillis( 500 );
+    
+        getActorsWithLimit( "(objectClass=*)",
+            LdapServer.NO_TIME_LIMIT, LdapServer.NO_SIZE_LIMIT );
+    }
+    
+    
+    /**
+     * Sets up the server with limited search time with unlimited request
+     * time limit.  Should not work for non administrative users.
+     */
+    @Test(expected = TimeLimitExceededException.class)
+    public void testNonAdminRequestUnlimitedConfigurationLimited() throws Exception
+    {
+        getLdapServer().setMaxTimeLimit( 1 ); // this is in seconds
+        delayInterceptor.setDelayMillis( 500 );
+    
+        getActorsWithLimitNonAdmin( "(objectClass=*)",
+            LdapServer.NO_TIME_LIMIT, LdapServer.NO_SIZE_LIMIT );
+    }
+    
+    
+    // -----------------------------------------------------------------------
+    // Size Limit Tests
+    // -----------------------------------------------------------------------
+    
+    /**
+     * Sets up the server with unlimited search size limit but constrains size
+     * by request size limit value to cause a size limit exceeded exception on
+     * the client.
+     */
+    @Test(expected = SizeLimitExceededException.class)
+    public void testRequestConstrainedUnlimitByConfigurationSize() throws Exception
+    {
+        getLdapServer().setMaxSizeLimit( LdapServer.NO_SIZE_LIMIT );
+    
+        getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 1 );
+    }
+    
+    
+    /**
+     * Sets up the server with longer search size limit than the request's
+     * which constrains size by request size limit value to cause a size limit
+     * exceeded exception on the client.
+     */
+    @Test(expected = SizeLimitExceededException.class)
+    public void testRequestConstrainedLessThanConfigurationSize() throws Exception
+    {
+        getLdapServer().setMaxSizeLimit( 10000 );
+    
+        getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 1 );
+    }
+    
+    
+    /**
+     * Sets up the server with shorter search size limit than the request's
+     * which constrains size by using server max limit value. Should work
+     * just fine for the administrative user.
+     */
+    @Test
+    public void testRequestConstrainedGreaterThanConfigurationSize() throws Exception
+    {
+        getLdapServer().setMaxSizeLimit( 1 );
+        Set<String> set = getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 100000 );
+        assertEquals( 4, set.size() );
+    }
+    
+    
+    /**
+     * Sets up the server with shorter search size limit than the request's
+     * which constrains size by using server max limit value to cause a size
+     * limit exceeded exception on the client.
+     */
+    @Test(expected = SizeLimitExceededException.class)
+    public void testNonAdminRequestConstrainedGreaterThanConfigurationSize() throws Exception
+    {
+        getLdapServer().setMaxSizeLimit( 1 );
+    
+        // We are not using the admin : it should fail
+        getActorsWithLimitNonAdmin( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 100000 );
+    }
+    
+    
+    /**
+     * Sets up the server with limited search size with unlimited request
+     * size limit.  Should work just fine for the administrative user.
+     */
+    @Test
+    public void testRequestUnlimitedConfigurationLimitedSize() throws Exception
+    {
+        getLdapServer().setMaxSizeLimit( 1 );
+        Set<String> set = getActorsWithLimit( "(objectClass=*)",
+            LdapServer.NO_TIME_LIMIT, LdapServer.NO_SIZE_LIMIT );
+    
+        assertEquals( 4, set.size() );
+    }
+    
+    
+    /**
+     * Sets up the server with limited search size with unlimited request
+     * size limit.  Should not work for non administrative users.
+     */
+    @Test(expected = SizeLimitExceededException.class)
+    public void testNonAdminRequestUnlimitedConfigurationLimitedSize() throws Exception
+    {
+        getLdapServer().setMaxSizeLimit( 1 );
+        getActorsWithLimitNonAdmin( "(objectClass=*)",
+            LdapServer.NO_TIME_LIMIT, LdapServer.NO_SIZE_LIMIT );
+    }
+    
+    
+    /**
+     * Test for DIRSERVER-1235.
+     * Sets up the server with unlimited search size limit but constrains size
+     * by request size limit value. The request size limit is less than the
+     * expected number of result entries, so exception expected.
+     * 
+     * cf RFC 4511 :
+     *  "sizeLimitExceeded (4)
+     *   Indicates that the size limit specified by the client was
+     *   exceeded before the operation could be completed."
+     */
+    @Test(expected = SizeLimitExceededException.class)
+    public void testRequestConstraintedLessThanExpectedSize() throws Exception
+    {
+        getLdapServer().setMaxSizeLimit( LdapServer.NO_SIZE_LIMIT );
+    
+        getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 3 );
+    }
+    
+    
+    /**
+     * Test for DIRSERVER-1235.
+     * Sets up the server with unlimited search size limit but constrains size
+     * by request size limit value. The request size limit is equal to the
+     * expected number of result entries so no exception expected.
+     */
+    @Test
+    public void testRequestConstraintedEqualToExpectedSize() throws Exception
+    {
+        getLdapServer().setMaxSizeLimit( LdapServer.NO_SIZE_LIMIT );
+        Set<String> set = getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 4 );
+        assertEquals( 4, set.size() );
+    }
+    
+    
+    /**
+     * Test for DIRSERVER-1235.
+     * Sets up the server with unlimited search size limit but constrains size
+     * by request size limit value. The request size limit is greater than the
+     * expected number of result entries so no exception expected.
+     */
+    @Test
+    public void testRequestConstraintedGreaterThanExpectedSize() throws Exception
+    {
+        getLdapServer().setMaxSizeLimit( LdapServer.NO_SIZE_LIMIT );
+        Set<String> set = getActorsWithLimit( "(objectClass=*)", LdapServer.NO_TIME_LIMIT, 5 );
+        assertEquals( 4, set.size() );
+    }
+    
+    
+    /**
+     * Test for DIRSERVER-1235.
+     * Reads an entry using object scope and size limit 1, no exception
+     * expected.
+     */
+    @Test
+    public void testRequestObjectScopeAndSizeLimit() throws Exception
+    {
+        getLdapServer().setMaxSizeLimit( LdapServer.NO_SIZE_LIMIT );
+    
+        DirContext ctx = getWiredContext( getLdapServer() );
+        String filter = "(objectClass=*)";
+        SearchControls controls = new SearchControls();
+        controls.setTimeLimit( 0 );
+        controls.setCountLimit( 1 );
+        controls.setSearchScope( SearchControls.OBJECT_SCOPE );
+    
+        NamingEnumeration<SearchResult> namingEnumeration =
+            ctx.search( "ou=actors,ou=system", filter, controls );
+        assertTrue( namingEnumeration.hasMore() );
+        namingEnumeration.next();
+        assertFalse( namingEnumeration.hasMore() );
+    }
+    
+    
+    // -----------------------------------------------------------------------
+    // Utility Methods
+    // -----------------------------------------------------------------------
+    
+    /**
+     * Do a search request from the ou=actors,ou=system base, with a principal
+     * which is the administrator.
+     */
+    private Set<String> getActorsWithLimit( String filter, int timeLimitMillis, long sizeLimit ) throws Exception
+    {
+        DirContext ctx = getWiredContext( getLdapServer() );
+        Set<String> results = new HashSet<String>();
+        SearchControls controls = new SearchControls();
+        controls.setTimeLimit( timeLimitMillis );
+        controls.setCountLimit( sizeLimit );
+        controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+    
+        NamingEnumeration<SearchResult> namingEnumeration =
+            ctx.search( "ou=actors,ou=system", filter, controls );
+    
+        while ( namingEnumeration.hasMore() )
+        {
+            results.add( namingEnumeration.next().getNameInNamespace() );
+        }
+    
+        return results;
+    }
+    
+    
+    /**
+     * Do a search request from the ou=actors,ou=system base, with a principal
+     * which is not the administrator.
+     */
+    private Set<String> getActorsWithLimitNonAdmin( String filter, int timeLimitMillis, long sizeLimit )
+        throws Exception
+    {
+        DirContext ctx = getWiredContext( getLdapServer(), "uid=jblack,ou=actors,ou=system", "secret" );
+        Set<String> results = new HashSet<String>();
+        SearchControls controls = new SearchControls();
+        controls.setTimeLimit( timeLimitMillis );
+        controls.setCountLimit( sizeLimit );
+        controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+    
+        NamingEnumeration<SearchResult> namingEnumeration =
+            ctx.search( "ou=actors,ou=system", filter, controls );
+    
+        while ( namingEnumeration.hasMore() )
+        {
+            results.add( namingEnumeration.next().getNameInNamespace() );
+        }
+    
+        return results;
+    }
 }
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchPerfIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchPerfIT.java
index 82dacf7..074fc46 100644
--- a/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchPerfIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchPerfIT.java
@@ -23,6 +23,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.ldap.client.api.EntryCursorImpl;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.LdapNetworkConnection;
@@ -37,6 +38,7 @@
 import org.apache.directory.shared.ldap.model.message.SearchRequestImpl;
 import org.apache.directory.shared.ldap.model.message.SearchScope;
 import org.apache.directory.shared.ldap.model.name.Dn;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -53,6 +55,9 @@
     { @CreateTransport(protocol = "LDAP") })
 public class SearchPerfIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+
     /**
      * test a search request perf.
      */
diff --git a/server-integ/src/test/java/org/apache/directory/server/replication/ClientInitialRefreshIT.java b/server-integ/src/test/java/org/apache/directory/server/replication/ClientInitialRefreshIT.java
index 5b6bd55..271d6ee 100644
--- a/server-integ/src/test/java/org/apache/directory/server/replication/ClientInitialRefreshIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/replication/ClientInitialRefreshIT.java
@@ -25,6 +25,7 @@
 
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ContextEntry;
@@ -49,6 +50,7 @@
 import org.apache.directory.shared.ldap.model.schema.SchemaManager;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.Test;
 
 
@@ -59,6 +61,9 @@
  */
 public class ClientInitialRefreshIT
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+
     private static LdapServer providerServer;
 
     private static SchemaManager schemaManager;
@@ -398,7 +403,7 @@
 
 
     /**
-     * Test that we can load entries, kill the consumer in the middle of the load, 
+     * Test that we can load entries, kill the consumer in the middle of the load,
      * restart the consumer and still get all the entries.
      */
     @Test
diff --git a/server-integ/src/test/java/org/apache/directory/server/replication/ClientServerReplicationIT.java b/server-integ/src/test/java/org/apache/directory/server/replication/ClientServerReplicationIT.java
index 6a9da53..1229d44 100644
--- a/server-integ/src/test/java/org/apache/directory/server/replication/ClientServerReplicationIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/replication/ClientServerReplicationIT.java
@@ -29,6 +29,7 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.annotations.CreateConsumer;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -60,6 +61,7 @@
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
+import org.junit.Rule;
 import org.junit.Test;
 
 
@@ -70,6 +72,9 @@
  */
 public class ClientServerReplicationIT
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+
     private static LdapServer providerServer;
 
     private static LdapServer consumerServer;
diff --git a/server-integ/src/test/java/org/apache/directory/server/replication/MockSyncReplConsumer.java b/server-integ/src/test/java/org/apache/directory/server/replication/MockSyncReplConsumer.java
index e4a97a3..d2250ce 100644
--- a/server-integ/src/test/java/org/apache/directory/server/replication/MockSyncReplConsumer.java
+++ b/server-integ/src/test/java/org/apache/directory/server/replication/MockSyncReplConsumer.java
@@ -193,7 +193,7 @@
      * Connect to the remote server. Note that a SyncRepl consumer will be connected to only
      * one remote server
      * 
-     * @return true if the connections have been successful. 
+     * @return true if the connections have been successful.
      */
     public boolean connect()
     {
@@ -471,7 +471,7 @@
     }
 
 
-    /** 
+    /**
      * {@inheritDoc}
      */
     public void setConfig( ReplicationConsumerConfig config )
diff --git a/server-integ/src/test/java/org/apache/directory/server/schema/SchemaIT.java b/server-integ/src/test/java/org/apache/directory/server/schema/SchemaIT.java
index 5fa92b3..9846eee 100644
--- a/server-integ/src/test/java/org/apache/directory/server/schema/SchemaIT.java
+++ b/server-integ/src/test/java/org/apache/directory/server/schema/SchemaIT.java
@@ -43,6 +43,7 @@
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
 import org.apache.directory.server.core.annotations.CreateDS;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
@@ -53,6 +54,7 @@
 import org.apache.directory.shared.ldap.model.schema.parsers.AttributeTypeDescriptionSchemaParser;
 import org.apache.directory.shared.ldap.model.schema.parsers.ObjectClassDescriptionSchemaParser;
 import org.apache.directory.shared.ldap.util.JndiUtils;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -66,6 +68,9 @@
 @CreateDS(name = "SchemaIT-class")
 public class SchemaIT extends AbstractLdapTestUnit
 {
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE );
+
     private static final String SUBSCHEMA_SUBENTRY = "subschemaSubentry";
     private static final AttributeTypeDescriptionSchemaParser ATTRIBUTE_TYPE_DESCRIPTION_SCHEMA_PARSER = new AttributeTypeDescriptionSchemaParser();
     private static final ObjectClassDescriptionSchemaParser OBJECT_CLASS_DESCRIPTION_SCHEMA_PARSER = new ObjectClassDescriptionSchemaParser();
diff --git a/server-integ/src/test/resources/log4j.properties b/server-integ/src/test/resources/log4j.properties
index facb3e6..29b52d7 100644
--- a/server-integ/src/test/resources/log4j.properties
+++ b/server-integ/src/test/resources/log4j.properties
@@ -14,8 +14,29 @@
 #    See the License for the specific language governing permissions and
 #    limitations under the License.
 #############################################################################
-log4j.rootCategory=OFF, stdout
+#log4j.rootCategory=OFF, stdout
 
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %p [%c] - %m%n
+#log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+#log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+#log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %p [%c] - %m%n
+
+log4j.rootCategory=DEBUG, rollingFile
+
+log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
+log4j.appender.rollingFile.File=/tmp/cursor-server-integ.log
+log4j.appender.rollingFile.MaxFileSize=1MB
+log4j.appender.rollingFile.MaxBackupIndex=5
+log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
+log4j.appender.rollingFile.layout.ConversionPattern=%m%n
+
+log4j.logger.org=FATAL
+log4j.logger.JdbmTable=FATAL
+log4j.logger.JdbmIndex=FATAL
+log4j.logger.BaseRecordManager=FATAL
+log4j.logger.LOG_CHANGES=FATAL
+log4j.logger.net=FATAL
+log4j.logger.aci-logger=FATAL
+log4j.logger.DupsCursor=FATAL
+log4j.logger.PROVIDER_LOG=FATAL
+log4j.logger.CONSUMER_LOG=FATAL
+log4j.logger.CURSOR=DEBUG