Merge branch 'master' of
https://gitbox.apache.org/repos/asf/directory-server

# Conflicts:
#	service/src/test/java/org/apache/directory/server/UberJarMainTest.java
diff --git a/all/pom.xml b/all/pom.xml
index 96cd601..533c931 100644
--- a/all/pom.xml
+++ b/all/pom.xml
@@ -163,11 +163,11 @@
               <promoteTransitiveDependencies>true</promoteTransitiveDependencies>
               <filters>
                 <filter>
-                  <artifact>org.bouncycastle:bcprov-jdk15on</artifact>
+                  <artifact>*:*</artifact>
                   <excludes>
-                    <exclude>META-INF/BCK*.SF</exclude>
-                    <exclude>META-INF/BCK*.DSA</exclude>
-                    <exclude>META-INF/BCK*.RSA</exclude>
+                    <exclude>META-INF/*.SF</exclude>
+                    <exclude>META-INF/*.DSA</exclude>
+                    <exclude>META-INF/*.RSA</exclude>
                   </excludes>
                 </filter>
               </filters>
diff --git a/core-annotations/pom.xml b/core-annotations/pom.xml
index 7cf584d..d61876c 100644
--- a/core-annotations/pom.xml
+++ b/core-annotations/pom.xml
@@ -88,6 +88,12 @@
       <groupId>org.apache.directory.mavibot</groupId>
       <artifactId>mavibot</artifactId>
     </dependency>
+    
+    <!-- Override the default version bundled with Mavibot -->
+    <dependency>
+        <groupId>commons-collections</groupId>
+        <artifactId>commons-collections</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>${project.groupId}</groupId>
diff --git a/core-annotations/src/main/java/org/apache/directory/server/core/factory/DSAnnotationProcessor.java b/core-annotations/src/main/java/org/apache/directory/server/core/factory/DSAnnotationProcessor.java
index b5be49c..028808c 100644
--- a/core-annotations/src/main/java/org/apache/directory/server/core/factory/DSAnnotationProcessor.java
+++ b/core-annotations/src/main/java/org/apache/directory/server/core/factory/DSAnnotationProcessor.java
@@ -472,7 +472,7 @@
     
     private static boolean isDn( String str )
     {
-        if ( ( Strings.isEmpty( str ) ) | ( str.length() < 3 ) )
+        if ( ( Strings.isEmpty( str ) ) || ( str.length() < 3 ) )
         {
             return false;
         }
diff --git a/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MoveIT.java b/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MoveIT.java
index 13f75d4..93a72e2 100644
--- a/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MoveIT.java
+++ b/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MoveIT.java
@@ -86,7 +86,7 @@
 
         Dn dn = new Dn( oldDn );
         Entry entry = new DefaultEntry( getService().getSchemaManager(), dn,
-            "ObjectClass: top", 
+            "ObjectClass: top",
             "ObjectClass: person",
             "sn: TEST",
             "cn: test" );
@@ -100,7 +100,7 @@
 
         assertNotNull( connection.lookup( newDn ) );
         assertNull( connection.lookup( oldDn ) );
-        
+
         connection.close();
     }
 
@@ -115,29 +115,29 @@
         LdapConnection connection = IntegrationUtils.getAdminConnection( getService() );
 
         Entry test1 = new DefaultEntry( getService().getSchemaManager(), "cn=test1,ou=system",
-            "ObjectClass: top", 
+            "ObjectClass: top",
             "ObjectClass: person",
             "sn: Test1",
             "cn: tes1t" );
 
         Entry childTest1 = new DefaultEntry( getService().getSchemaManager(), "cn=childTest1,cn=test1,ou=system",
-            "ObjectClass: top", 
+            "ObjectClass: top",
             "ObjectClass: person",
             "sn: child test1",
             "cn: childTest1" );
 
         Entry test2 = new DefaultEntry( getService().getSchemaManager(), "cn=test2,ou=system",
-            "ObjectClass: top", 
+            "ObjectClass: top",
             "ObjectClass: person",
             "sn: Test2",
             "cn: test2" );
 
         Entry childTest2 = new DefaultEntry( getService().getSchemaManager(), "cn=childTest2,cn=test2,ou=system",
-            "ObjectClass: top", 
+            "ObjectClass: top",
             "ObjectClass: person",
             "sn: child test2",
             "cn: childTest2" );
-        
+
         connection.add( test1 );
         connection.add( test2 );
         connection.add( childTest1 );
@@ -156,11 +156,11 @@
         assertNotNull( connection.lookup( "cn=childTest2,cn=test2,ou=system" ) );
         assertNotNull( connection.lookup( "cn=test1,cn=test2,ou=system" ) );
         assertNotNull( connection.lookup( "cn=childTest1,cn=test1,cn=test2,ou=system" ) );
-        
+
         connection.close();
     }
-    
-    
+
+
     /**
      * Test a move operation to a non existing parent:
      * cn=test,ou=system will be moved to cn=test,ou=users,ou=system
@@ -176,7 +176,7 @@
 
         Dn dn = new Dn( oldDn );
         Entry entry = new DefaultEntry( getService().getSchemaManager(), dn,
-            "ObjectClass: top", 
+            "ObjectClass: top",
             "ObjectClass: person",
             "sn: TEST",
             "cn: test" );
@@ -198,7 +198,7 @@
 
         assertNull( connection.lookup( newDn ) );
         assertNotNull( connection.lookup( oldDn ) );
-        
+
         connection.close();
     }
 
@@ -219,7 +219,7 @@
 
         Dn dn = new Dn( oldDn );
         Entry entry = new DefaultEntry( getService().getSchemaManager(), dn,
-            "ObjectClass: top", 
+            "ObjectClass: top",
             "ObjectClass: person",
             "sn: TEST",
             "cn: test" );
@@ -228,7 +228,7 @@
 
         Dn targetDn = new Dn( targetDnStr );
         Entry target = new DefaultEntry( getService().getSchemaManager(), targetDn,
-            "ObjectClass: top", 
+            "ObjectClass: top",
             "ObjectClass: person",
             "sn: TEST",
             "cn: test" );
@@ -247,7 +247,7 @@
             assertNotNull( connection.lookup( newDn ) );
             assertNotNull( connection.lookup( oldDn ) );
         }
-        
+
         connection.close();
     }
 }
diff --git a/core-integ/src/test/java/org/apache/directory/server/core/operations/moveAndRename/MoveAndRenameIT.java b/core-integ/src/test/java/org/apache/directory/server/core/operations/moveAndRename/MoveAndRenameIT.java
index 2af0261..0900b7e 100644
--- a/core-integ/src/test/java/org/apache/directory/server/core/operations/moveAndRename/MoveAndRenameIT.java
+++ b/core-integ/src/test/java/org/apache/directory/server/core/operations/moveAndRename/MoveAndRenameIT.java
@@ -134,25 +134,25 @@
         Entry oldCommon = connection.lookup( "ou=people,ou=system", "*", "+" );
         Entry oldSuperior = connection.lookup( "ou=committers,ou=Apache,ou=people,ou=system", "*", "+" );
         Entry newSuperior = connection.lookup( "dc=domain,ou=system", "*", "+" );
-        
+
         // Check the old common
         Attribute nbSubordinate = oldCommon.get( "nbSubordinates" );
         Attribute nbChildren = oldCommon.get( "nbChildren" );
-        
+
         assertEquals( "5", nbSubordinate.getString() );
         assertEquals( "1", nbChildren.getString() );
 
         // The old superior
         nbSubordinate = oldSuperior.get( "nbSubordinates" );
         nbChildren = oldSuperior.get( "nbChildren" );
-        
+
         assertEquals( "2", nbSubordinate.getString() );
         assertEquals( "2", nbChildren.getString() );
 
         // The new superior
         nbSubordinate = newSuperior.get( "nbSubordinates" );
         nbChildren = newSuperior.get( "nbChildren" );
-        
+
         assertEquals( "0", nbSubordinate.getString() );
         assertEquals( "0", nbChildren.getString() );
 
@@ -166,41 +166,41 @@
         connection.moveAndRename( oldDn, newDn, true );
 
         assertNull( connection.lookup( oldDn ) );
-        
+
         Entry movedEntry = connection.lookup( newDn, "*", "+" );
         assertNotNull( movedEntry );
         assertTrue( movedEntry.contains( "cn", "emmanuel" ) );
         assertFalse( movedEntry.contains( "cn", "elecharny" ) );
-        
+
         // Get the nbSubordinates before the move
         oldCommon = connection.lookup( "ou=people,ou=system", "*", "+" );
         oldSuperior = connection.lookup( "ou=committers,ou=Apache,ou=people,ou=system", "*", "+" );
         newSuperior = connection.lookup( "dc=domain,ou=system", "*", "+" );
-        
+
         // Check the old common
         nbSubordinate = oldCommon.get( "nbSubordinates" );
         nbChildren = oldCommon.get( "nbChildren" );
-        
+
         assertEquals( "4", nbSubordinate.getString() );
         assertEquals( "1", nbChildren.getString() );
 
         // The old superior
         nbSubordinate = oldSuperior.get( "nbSubordinates" );
         nbChildren = oldSuperior.get( "nbChildren" );
-        
+
         assertEquals( "1", nbSubordinate.getString() );
         assertEquals( "1", nbChildren.getString() );
 
         // The new superior
         nbSubordinate = newSuperior.get( "nbSubordinates" );
         nbChildren = newSuperior.get( "nbChildren" );
-        
+
         assertEquals( "1", nbSubordinate.getString() );
         assertEquals( "1", nbChildren.getString() );
         connection.close();
     }
 
-    
+
     /**
      * Test a simple MoveAndRename move operation
      * cn=elecharny,ou=committers,ou=Apache,ou=people,ou=system will be moved to 
@@ -220,25 +220,25 @@
         Entry oldCommon = connection.lookup( "ou=people,ou=system", "*", "+" );
         Entry oldSuperior = connection.lookup( "ou=committers,ou=Apache,ou=people,ou=system", "*", "+" );
         Entry newSuperior = connection.lookup( "dc=domain,ou=system", "*", "+" );
-        
+
         // Check the old common
         Attribute nbSubordinate = oldCommon.get( "nbSubordinates" );
         Attribute nbChildren = oldCommon.get( "nbChildren" );
-        
+
         assertEquals( "5", nbSubordinate.getString() );
         assertEquals( "1", nbChildren.getString() );
 
         // The old superior
         nbSubordinate = oldSuperior.get( "nbSubordinates" );
         nbChildren = oldSuperior.get( "nbChildren" );
-        
+
         assertEquals( "2", nbSubordinate.getString() );
         assertEquals( "2", nbChildren.getString() );
 
         // The new superior
         nbSubordinate = newSuperior.get( "nbSubordinates" );
         nbChildren = newSuperior.get( "nbChildren" );
-        
+
         assertEquals( "0", nbSubordinate.getString() );
         assertEquals( "0", nbChildren.getString() );
 
@@ -252,42 +252,42 @@
         connection.moveAndRename( oldDn, newDn, false );
 
         assertNull( connection.lookup( oldDn ) );
-        
+
         Entry movedEntry = connection.lookup( newDn, "*", "+" );
         assertNotNull( movedEntry );
         assertTrue( movedEntry.contains( "cn", "emmanuel" ) );
         assertTrue( movedEntry.contains( "cn", "elecharny" ) );
-        
+
         // Get the nbSubordinates before the move
         oldCommon = connection.lookup( "ou=people,ou=system", "*", "+" );
         oldSuperior = connection.lookup( "ou=committers,ou=Apache,ou=people,ou=system", "*", "+" );
         newSuperior = connection.lookup( "dc=domain,ou=system", "*", "+" );
-        
+
         // Check the old common
         nbSubordinate = oldCommon.get( "nbSubordinates" );
         nbChildren = oldCommon.get( "nbChildren" );
-        
+
         assertEquals( "4", nbSubordinate.getString() );
         assertEquals( "1", nbChildren.getString() );
 
         // The old superior
         nbSubordinate = oldSuperior.get( "nbSubordinates" );
         nbChildren = oldSuperior.get( "nbChildren" );
-        
+
         assertEquals( "1", nbSubordinate.getString() );
         assertEquals( "1", nbChildren.getString() );
 
         // The new superior
         nbSubordinate = newSuperior.get( "nbSubordinates" );
         nbChildren = newSuperior.get( "nbChildren" );
-        
+
         assertEquals( "1", nbSubordinate.getString() );
         assertEquals( "1", nbChildren.getString() );
 
         connection.close();
     }
 
-    
+
     /**
      * Test a simple MoveAndRename move operation
      * ou=Apache,ou=system will be moved to cn=test,ou=users,ou=system
@@ -300,7 +300,6 @@
     public void testMoveAndRenameRdnNotInObjectClass() throws Exception
     {
         LdapConnection connection = IntegrationUtils.getAdminConnection( getService() );
-        
 
         String oldDn = "ou=Apache,ou=system";
         String newDn = "uid=test,ou=people,ou=system";
@@ -311,17 +310,17 @@
         connection.moveAndRename( oldDn, newDn );
 
         assertNull( connection.lookup( oldDn ) );
-        
+
         Entry movedEntry = connection.lookup( newDn );
         assertNotNull( movedEntry );
         assertTrue( movedEntry.contains( "cn", "test" ) );
         assertTrue( movedEntry.contains( "cn", "jDoe" ) );
         assertTrue( movedEntry.contains( "ou", "Apache" ) );
-        
+
         connection.close();
     }
-    
-    
+
+
     /**
      * Check that when doing a rename, with a SV RDN, we don't have the previous RDN in the entry,
      * if the deleteOldrdn flag is set to true
@@ -353,9 +352,9 @@
             "c: FR" );
 
         connection.add( frEntry );
-        
+
         Entry original = connection.lookup( frDn );
-        
+
         assertNotNull( original );
 
         // rename the FR entry to DE entry : should fail as DE entry already exists
diff --git a/core-integ/src/test/java/org/apache/directory/server/core/operations/rename/RenameIT.java b/core-integ/src/test/java/org/apache/directory/server/core/operations/rename/RenameIT.java
index a93d904..a2c3f88 100644
--- a/core-integ/src/test/java/org/apache/directory/server/core/operations/rename/RenameIT.java
+++ b/core-integ/src/test/java/org/apache/directory/server/core/operations/rename/RenameIT.java
@@ -88,24 +88,24 @@
             "cn: test1" );
 
         connection.add( entry );
-        
+
         Entry original = connection.lookup( oldDn );
-        
+
         assertNotNull( original );
 
         connection.rename( oldDn, "cn=TEST2" );
-        
+
         Entry renamed = connection.lookup( newDn );
-        
+
         assertNotNull( renamed );
         assertEquals( newDn, renamed.getDn().toString() );
         Attribute attribute = renamed.get( "cn" );
-        
-        assertTrue( attribute.contains(  "test1" ) );
-        assertTrue( attribute.contains(  "test2" ) );
+
+        assertTrue( attribute.contains( "test1" ) );
+        assertTrue( attribute.contains( "test2" ) );
     }
-    
-    
+
+
     /**
      * Check that when doing a rename, with a MV RDN, and teh deleteOldRdn flag set to true,
      * we don't have the previous RDN in the entry.
@@ -128,25 +128,25 @@
             "cn: test1" );
 
         connection.add( entry );
-        
+
         Entry original = connection.lookup( oldDn );
-        
+
         assertNotNull( original );
 
         connection.rename( oldDn, "cn=test2", true );
-        
+
         assertNull( connection.lookup( oldDn ) );
         Entry renamed = connection.lookup( newDn );
-        
+
         assertNotNull( renamed );
         assertEquals( newDn, renamed.getDn().toString() );
         Attribute attribute = renamed.get( "cn" );
-        
+
         assertFalse( attribute.contains( "test1" ) );
         assertTrue( attribute.contains( "test2" ) );
     }
-    
-    
+
+
     /**
      * Check that when doing a rename, with a MV RDN, and the deleteOldRdn flag set to false,
      * we have the previous RDN in the entry.
@@ -169,25 +169,25 @@
             "cn: test1" );
 
         connection.add( entry );
-        
+
         Entry original = connection.lookup( oldDn );
-        
+
         assertNotNull( original );
 
         connection.rename( oldDn, "cn=test2", false );
-        
+
         assertNull( connection.lookup( oldDn ) );
         Entry renamed = connection.lookup( newDn );
-        
+
         assertNotNull( renamed );
         assertEquals( newDn, renamed.getDn().toString() );
         Attribute attribute = renamed.get( "cn" );
-        
+
         assertTrue( attribute.contains( "test1" ) );
         assertTrue( attribute.contains( "test2" ) );
     }
-    
-    
+
+
     /**
      * Check that when doing a rename, with a SV RDN, we get an error if the deleteOldRdn flag is
      * set to false
@@ -209,9 +209,9 @@
             "c: FR" );
 
         connection.add( entry );
-        
+
         Entry original = connection.lookup( oldDn );
-        
+
         assertNotNull( original );
 
         try
@@ -222,12 +222,12 @@
         {
             System.out.println( e.getMessage() );
         }
-        
+
         assertNotNull( connection.lookup( oldDn ) );
         assertNull( connection.lookup( newDn ) );
     }
-    
-    
+
+
     /**
      * Check that when doing a rename, with a SV RDN, we don't have the previous RDN in the entry,
      * if the deleteOldrdn flgg is set to true
@@ -249,25 +249,25 @@
             "c: FR" );
 
         connection.add( entry );
-        
+
         Entry original = connection.lookup( oldDn );
-        
+
         assertNotNull( original );
 
         connection.rename( oldDn, "c=DE", true );
-        
+
         assertNull( connection.lookup( oldDn ) );
         Entry renamed = connection.lookup( newDn );
-        
+
         assertNotNull( renamed );
         assertEquals( newDn, renamed.getDn().toString() );
         Attribute countryName = renamed.get( "c" );
-        
+
         assertTrue( countryName.contains( "DE" ) );
         assertFalse( countryName.contains( "FR" ) );
     }
-    
-    
+
+
     /**
      * Check that when doing a rename, with a SV RDN, we don't have the previous RDN in the entry,
      * if the deleteOldrdn flag is set to true
@@ -299,9 +299,9 @@
             "c: FR" );
 
         connection.add( frEntry );
-        
+
         Entry original = connection.lookup( frDn );
-        
+
         assertNotNull( original );
 
         // rename the FR entry to DE entry : should fail as DE entry already exists
@@ -325,15 +325,15 @@
             assertFalse( originalDe.get( "c" ).contains( "FR" ) );
         }
     }
-    
-    
+
+
     /**
      * Check that when doing a rename, with a SV RDN, we get an error if the deleteOldRdn flag is
      * set to false
      * 
      * @throws Exception
      */
-    @Test 
+    @Test
     public void testRenameMvAttributeSVAttributeKeepOldRdn() throws Exception
     {
         LdapConnection connection = IntegrationUtils.getAdminConnection( getService() );
@@ -351,26 +351,26 @@
             "cn: test" );
 
         connection.add( entry );
-        
+
         Entry original = connection.lookup( oldDn );
-        
+
         assertNotNull( original );
 
         connection.rename( oldDn, "displayName=myTest", false );
-        
+
         assertNull( connection.lookup( oldDn ) );
         Entry renamed = connection.lookup( newDn );
-        
+
         assertNotNull( renamed );
         assertEquals( newDn, renamed.getDn().toString() );
         Attribute displayName = renamed.get( "displayName" );
         Attribute cn = renamed.get( "cn" );
-        
+
         assertTrue( displayName.contains( "mytest" ) );
         assertTrue( cn.contains( "test" ) );
     }
-    
-    
+
+
     /**
      * Check that when doing a rename, from a MV attribute to a SV attribute, we don't have 
      * the previous RDN in the entry, if the deleteOldrdn flgg is set to true
@@ -393,24 +393,24 @@
             "ObjectClass: inetOrgPerson",
             "sn: TEST",
             "cn: test",
-            "gn: test");
+            "gn: test" );
 
         connection.add( entry );
-        
+
         Entry original = connection.lookup( oldDn );
-        
+
         assertNotNull( original );
 
         connection.rename( oldDn, "displayName=MyTest", true );
-        
+
         assertNull( connection.lookup( oldDn ) );
         Entry renamed = connection.lookup( newDn );
-        
+
         assertNotNull( renamed );
         assertEquals( newDn, renamed.getDn().toString() );
         Attribute displayName = renamed.get( "displayName" );
         Attribute cn = renamed.get( "gn" );
-        
+
         assertTrue( displayName.contains( "mytest" ) );
         assertNull( cn );
     }
diff --git a/core/pom.xml b/core/pom.xml
index 1821f93..393f52e 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -158,6 +158,11 @@
       <groupId>org.bouncycastle</groupId>
       <artifactId>bcprov-jdk15on</artifactId>
     </dependency>
+
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcpkix-jdk15on</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
@@ -261,6 +266,10 @@
                 org.bouncycastle.x509;version=${bcprov.version},
                 org.bouncycastle.asn1;version=${bcprov.version},
                 org.bouncycastle.asn1.x509;version=${bcprov.version},
+                org.bouncycastle.operator;version=${bcprov.version},
+                org.bouncycastle.operator.jcajce;version=${bcprov.version},
+                org.bouncycastle.cert;version=${bcprov.version},
+                org.bouncycastle.cert.jcajce;version=${bcprov.version},
                 org.slf4j;version=${slf4j.api.bundleversion}
             </Import-Package>
           </instructions>
diff --git a/core/src/main/java/org/apache/directory/server/core/security/CertificateUtil.java b/core/src/main/java/org/apache/directory/server/core/security/CertificateUtil.java
index be1e40f..11ada86 100644
--- a/core/src/main/java/org/apache/directory/server/core/security/CertificateUtil.java
+++ b/core/src/main/java/org/apache/directory/server/core/security/CertificateUtil.java
@@ -26,6 +26,7 @@
 import java.io.InputStream;
 import java.math.BigInteger;
 import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.security.InvalidKeyException;
@@ -40,36 +41,33 @@
 import java.security.SignatureException;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
+import java.time.Duration;
+import java.time.Instant;
 import java.util.Date;
 import java.util.Enumeration;
 
 import javax.net.ssl.KeyManagerFactory;
+import javax.security.auth.x500.X500Principal;
 
 import org.apache.directory.api.util.Strings;
-
-import sun.security.x509.AlgorithmId;
-import sun.security.x509.BasicConstraintsExtension;
-import sun.security.x509.CertificateAlgorithmId;
-import sun.security.x509.CertificateExtensions;
-import sun.security.x509.CertificateSerialNumber;
-import sun.security.x509.CertificateValidity;
-import sun.security.x509.CertificateVersion;
-import sun.security.x509.CertificateX509Key;
-import sun.security.x509.DNSName;
-import sun.security.x509.GeneralName;
-import sun.security.x509.GeneralNames;
-import sun.security.x509.IPAddressName;
-import sun.security.x509.SubjectAlternativeNameExtension;
-import sun.security.x509.X500Name;
-import sun.security.x509.X509CertImpl;
-import sun.security.x509.X509CertInfo;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.cert.CertIOException;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 
 /**
  * Helper class used to generate self-signed certificates, and load a KeyStore
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-@SuppressWarnings("restriction")
 public final class CertificateUtil
 {
     private static final boolean SELF_SIGNED = true;
@@ -81,94 +79,40 @@
         // Nothing to do
     }
     
-    
-    private static void setInfo( X509CertInfo info, X500Name subject, X500Name issuer, KeyPair keyPair, int days, 
-        String algoStr, boolean isCA ) 
-        throws CertificateException, IOException, NoSuchAlgorithmException
+    public static X509Certificate generateX509Certificate( X500Principal subjectDn, X500Principal issuerDn, KeyPair keyPair,
+            long daysValidity, String sigAlgorithm, boolean isCa )
+                    throws CertificateException
     {
-        Date from = new Date();
-        Date to = new Date( from.getTime() + days * 86_400_000L );
-        CertificateValidity interval = new CertificateValidity( from, to );
-
-        // Feed the certificate info structure
-        // version         [0]  EXPLICIT Version DEFAULT v1
-        // Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
-        info.set( X509CertInfo.VERSION, new CertificateVersion( CertificateVersion.V3 ) );
-        
-        // serialNumber         CertificateSerialNumber
-        // CertificateSerialNumber  ::=  INTEGER
+        Instant from = Instant.now();
+        Instant to = from.plus( Duration.ofDays( daysValidity ) );
         BigInteger serialNumber = new BigInteger( 64, new SecureRandom() );
-        info.set( X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber( serialNumber ) );
+        try
+        {
+            ContentSigner signer = new JcaContentSignerBuilder( sigAlgorithm ).build( keyPair.getPrivate() );
+            InetAddress localHost = InetAddress.getLocalHost();
+            GeneralName[] sanLocalHost = new GeneralName[] {
+                    new GeneralName( GeneralName.dNSName,
+                            localHost.getHostName() ),
+                    new GeneralName( GeneralName.iPAddress, localHost.getHostAddress() )
+            };
+            X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder( issuerDn,
+                    serialNumber,
+                    Date.from( from ),
+                    Date.from( to ),
+                    subjectDn,
+                    keyPair.getPublic() )
+                .addExtension( Extension.basicConstraints, CRITICAL, new BasicConstraints( isCa ) )
+                .addExtension( Extension.subjectAlternativeName, false, new GeneralNames( sanLocalHost ) );
 
-        // signature            AlgorithmIdentifier
-        AlgorithmId algo = AlgorithmId.get( algoStr );
-        info.set( X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId( algo ) );
-
-        // issuer               Name
-        // Name ::= CHOICE {
-        //          RDNSequence }
-        // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
-        // RelativeDistinguishedName ::=
-        //          SET OF AttributeTypeAndValue
-        // AttributeTypeAndValue ::= SEQUENCE {
-        //          type     AttributeType,
-        //          value    AttributeValue }
-        // AttributeType ::= OBJECT IDENTIFIER
-        // AttributeValue ::= ANY DEFINED BY AttributeType
-        info.set( X509CertInfo.ISSUER, issuer );
-        
-        // validity             Validity,
-        // Validity ::= SEQUENCE {
-        //          notBefore      Time,
-        //          notAfter       Time }
-        info.set( X509CertInfo.VALIDITY, interval );
-        
-        // subject              Name
-        // Name ::= CHOICE {
-        //          RDNSequence }
-        // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
-        // RelativeDistinguishedName ::=
-        //          SET OF AttributeTypeAndValue
-        // AttributeTypeAndValue ::= SEQUENCE {
-        //          type     AttributeType,
-        //          value    AttributeValue }
-        // AttributeType ::= OBJECT IDENTIFIER
-        // AttributeValue ::= ANY DEFINED BY AttributeType
-        info.set( X509CertInfo.SUBJECT, subject );
-        
-        // subjectPublicKeyInfo SubjectPublicKeyInfo,
-        // SubjectPublicKeyInfo  ::=  SEQUENCE  {
-        //          algorithm            AlgorithmIdentifier,
-        //          subjectPublicKey     BIT STRING  }
-        info.set( X509CertInfo.KEY, new CertificateX509Key( keyPair.getPublic() ) );
-
-        // Extensions. Basically, a subjectAltName and a Basic-Constraint 
-        CertificateExtensions extensions = new CertificateExtensions();
-
-        // SubjectAltName
-        GeneralNames names = new GeneralNames();
-        names.add( new GeneralName( new DNSName( InetAddress.getLocalHost().getHostName() ) ) );
-        String ipAddress = InetAddress.getLocalHost().getHostAddress();
-        names.add( new GeneralName( new IPAddressName( ipAddress ) ) );
-        
-        // A wildcard
-        //names.add( new GeneralName( 
-        //    new DNSName( 
-        //        new DerValue( 
-        //            DerValue.tag_IA5String, "*.apache.org" ) ) ) );
-        SubjectAlternativeNameExtension subjectAltName = new SubjectAlternativeNameExtension( names );
-        
-        extensions.set( subjectAltName.getExtensionId().toString(), subjectAltName );
-
-        // The Basic-Constraint,
-        BasicConstraintsExtension basicConstraint = new BasicConstraintsExtension( CRITICAL, isCA, -1 );
-        extensions.set( basicConstraint.getExtensionId().toString(), basicConstraint );
-
-        // Inject the extensions into the cert
-        info.set( X509CertInfo.EXTENSIONS, extensions );
+            return new JcaX509CertificateConverter().setProvider( new BouncyCastleProvider() )
+                    .getCertificate( certificateBuilder.build( signer ) );
+        }
+        catch ( OperatorCreationException | CertIOException | UnknownHostException e )
+        {
+            throw new CertificateException( "BouncyCastle failed to generate the X509 certificate.", e );
+        }
     }
     
-    
     /**
      * Create a self signed certificate
      * 
@@ -184,23 +128,12 @@
      * @throws NoSuchProviderException  If we don't have a security provider
      * @throws InvalidKeyException  If the KeyPair is invalid
      */
-    public static X509Certificate generateSelfSignedCertificate( X500Name issuer, KeyPair keyPair,  int days, String algoStr ) 
+    public static X509Certificate generateSelfSignedCertificate( X500Principal issuer, KeyPair keyPair,  int days, String algoStr ) 
         throws CertificateException, IOException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException
     {
-        // Create the certificate info
-        X509CertInfo info = new X509CertInfo();
-        
-        // Set the common certificate info
-        setInfo( info, issuer, issuer, keyPair, days, algoStr, SELF_SIGNED );
-        
-        // Sign the cert to identify the algorithm that's used.
-        X509CertImpl certificate = new X509CertImpl( info );
-        certificate.sign( keyPair.getPrivate(), algoStr );
-
-        return certificate;
+        return generateX509Certificate( issuer, issuer, keyPair, days, algoStr, SELF_SIGNED );
     }
     
-    
     /**
      * Generate a Certificate signed by a CA certificate
      * 
@@ -216,20 +149,10 @@
      * @throws NoSuchProviderException  If we don't have a security provider
      * @throws InvalidKeyException  If the KeyPair is invalid
      */
-    public static X509Certificate generateCertificate( X500Name subject, X500Name issuer, KeyPair keyPair,  int days, String algoStr ) 
+    public static X509Certificate generateCertificate( X500Principal subject, X500Principal issuer, KeyPair keyPair,  int days, String algoStr ) 
         throws CertificateException, IOException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException
     {
-        // Create the certificate info
-        X509CertInfo info = new X509CertInfo();
-        
-        // Set the common certificate info
-        setInfo( info, subject, issuer, keyPair, days, algoStr, CA_SIGNED );
-         
-        // Sign the cert to identify the algorithm that's used.
-        X509CertImpl certificate = new X509CertImpl( info );
-        certificate.sign( keyPair.getPrivate(), algoStr );
-
-        return certificate;
+        return generateX509Certificate( subject, issuer, keyPair, days, algoStr, CA_SIGNED );
     }
     
     
@@ -330,8 +253,7 @@
         KeyPair keyPair = keyPairGenerator.generateKeyPair();
         
         // Generate the subject's name
-        @SuppressWarnings("restriction")
-        X500Name owner = new X500Name( "apacheds", "directory", "apache", "US" );
+        X500Principal owner = new X500Principal( "CN=apacheds,OU=directory,O=apache,C=US" );
 
         // Create the self-signed certificate
         X509Certificate certificate = CertificateUtil.generateSelfSignedCertificate( owner, keyPair, 365, "SHA256WithECDSA" );
diff --git a/core/src/test/java/org/apache/directory/server/core/DefaultDirectoryServiceTest.java b/core/src/test/java/org/apache/directory/server/core/DefaultDirectoryServiceTest.java
index df0df02..90c2731 100644
--- a/core/src/test/java/org/apache/directory/server/core/DefaultDirectoryServiceTest.java
+++ b/core/src/test/java/org/apache/directory/server/core/DefaultDirectoryServiceTest.java
@@ -46,7 +46,7 @@
         for ( int i = 0; i < service.getInterceptors().size(); i++ )
         {
             Interceptor interceptor = service.getInterceptors().get( i );
-            
+
             if ( existingInterceptorName.equals( interceptor.getName() ) )
             {
                 final Interceptor nextInterceptor = service.getInterceptors().get( i + 1 );
diff --git a/core/src/test/java/org/apache/directory/server/core/security/CertificateUtilTest.java b/core/src/test/java/org/apache/directory/server/core/security/CertificateUtilTest.java
index 2ccc5a5..0a60df2 100644
--- a/core/src/test/java/org/apache/directory/server/core/security/CertificateUtilTest.java
+++ b/core/src/test/java/org/apache/directory/server/core/security/CertificateUtilTest.java
@@ -25,9 +25,9 @@
 import java.security.KeyPairGenerator;
 import java.security.cert.X509Certificate;
 
-import org.junit.Test;
+import javax.security.auth.x500.X500Principal;
 
-import sun.security.x509.X500Name;
+import org.junit.Test;
 
 /**
  * Test for the CertificateUtil class.
@@ -42,7 +42,7 @@
     public void testSelfSignedCertificateCreation() throws IOException, GeneralSecurityException
     {
         // Generate the subject's name
-        X500Name owner = new X500Name( "apacheds", "directory", "apache", "US" );
+        X500Principal owner = new X500Principal( "CN=apacheds,OU=directory,O=apache,C=US" );
         
         
         // generate the asymetric keys
diff --git a/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/KerberosUtils.java b/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/KerberosUtils.java
index 43b3f21..23381c8 100644
--- a/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/KerberosUtils.java
+++ b/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/KerberosUtils.java
@@ -389,11 +389,11 @@
     {
         String cipherName = Strings.toLowerCaseAscii( encType.getName() );
 
-        for ( String c : cipherAlgoMap.keySet() )
+        for ( Map.Entry<String, String> entry : cipherAlgoMap.entrySet() )
         {
-            if ( cipherName.startsWith( c ) )
+            if ( cipherName.startsWith( entry.getKey() ) )
             {
-                return cipherAlgoMap.get( c );
+                return entry.getValue();
             }
         }
 
diff --git a/ldap-client-test/pom.xml b/ldap-client-test/pom.xml
index ac48d74..682bccd 100644
--- a/ldap-client-test/pom.xml
+++ b/ldap-client-test/pom.xml
@@ -98,6 +98,12 @@
       <groupId>org.apache.directory.mavibot</groupId>
       <artifactId>mavibot</artifactId>
     </dependency>
+    
+    <!-- Override the default version bundled with Mavibot -->
+    <dependency>
+        <groupId>commons-collections</groupId>
+        <artifactId>commons-collections</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>org.apache.directory.api</groupId>
diff --git a/mavibot-partition/pom.xml b/mavibot-partition/pom.xml
index 253c2f0..2b73ade 100644
--- a/mavibot-partition/pom.xml
+++ b/mavibot-partition/pom.xml
@@ -32,6 +32,12 @@
       <artifactId>mavibot</artifactId>
     </dependency>
 
+    <!-- Override the default version bundled with Mavibot -->
+    <dependency>
+        <groupId>commons-collections</groupId>
+        <artifactId>commons-collections</artifactId>
+    </dependency>
+    
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>apacheds-core-api</artifactId>
diff --git a/pom.xml b/pom.xml
index 2bebe80..dbf7a16 100644
--- a/pom.xml
+++ b/pom.xml
@@ -54,20 +54,20 @@
     <skin.version>1.0.3</skin.version>
     
     <!-- Set versions for depending jars -->
-    <ant.version>1.10.8</ant.version>
-    <bcprov.version>1.65</bcprov.version>
+    <ant.version>1.10.9</ant.version>
+    <bcprov.version>1.67</bcprov.version>
     <commons.cli.version>1.4</commons.cli.version>
     <commons.codec.version>1.14</commons.codec.version>
     <commons.collections.version>4.4</commons.collections.version>
     <commons.daemon.version>1.2.0</commons.daemon.version>
     <commons.lang.version>3.9</commons.lang.version>
     <commons.net.version>3.6</commons.net.version>
-    <commons.pool.version>2.8.0</commons.pool.version>
+    <commons.pool.version>2.8.1</commons.pool.version>
     <dnsjava.version>2.1.9</dnsjava.version>
     <caffeine.version>2.7.0</caffeine.version>
     <findbugs.annotations.version>1.0.0</findbugs.annotations.version>
     <forbiddenapis.version>2.6</forbiddenapis.version>
-    <jetty.version>9.4.24.v20191120</jetty.version>
+    <jetty.version>9.4.34.v20201102</jetty.version>
     <!-- The Jetty bundle exports are using version 9.4.5, not 9.4.5.v20170502... -->
     <jetty.bundle.version>9.4.19</jetty.bundle.version>
     <junit.version>4.12</junit.version>
@@ -1071,6 +1071,13 @@
         <groupId>org.apache.directory.mavibot</groupId>
         <artifactId>mavibot</artifactId>
         <version>${org.apache.directory.mavibot.version}</version>
+        <!-- Can be removed once we pick up the next Mavibot version -->
+        <exclusions>
+            <exclusion>
+              <groupId>commons-collections</groupId>
+              <artifactId>commons-collections</artifactId>
+            </exclusion>
+        </exclusions>
       </dependency>
       
       <!-- Mina dependencies -->
@@ -1088,6 +1095,13 @@
         <artifactId>commons-codec</artifactId>
         <version>${commons.codec.version}</version>
       </dependency>
+
+      <!-- Can be removed once we pick up the next Mavibot version -->
+      <dependency>
+        <groupId>commons-collections</groupId>
+        <artifactId>commons-collections</artifactId>
+        <version>3.2.2</version>
+      </dependency>
       
       <dependency>
         <groupId>org.apache.commons</groupId>
@@ -1265,6 +1279,12 @@
         <artifactId>bcprov-jdk15on</artifactId>
         <version>${bcprov.version}</version>
       </dependency>
+    
+      <dependency>
+        <groupId>org.bouncycastle</groupId>
+        <artifactId>bcpkix-jdk15on</artifactId>
+        <version>${bcprov.version}</version>
+      </dependency>
 
       <dependency>
         <groupId>org.eclipse.jetty</groupId>
@@ -1277,7 +1297,7 @@
         <artifactId>annotations</artifactId>
         <version>${findbugs.annotations.version}</version>
       </dependency>
-      
+    
       <dependency>
         <groupId>com.github.ben-manes.caffeine</groupId>
         <artifactId>caffeine</artifactId>
diff --git a/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/KerberosConfig.java b/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/KerberosConfig.java
index 5237d9c..b3e2e9a 100644
--- a/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/KerberosConfig.java
+++ b/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/KerberosConfig.java
@@ -26,6 +26,8 @@
 import javax.security.auth.kerberos.KerberosPrincipal;
 
 import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.kerberos.shared.replay.ReplayCache;
+import org.apache.directory.server.kerberos.shared.replay.ReplayCacheImpl;
 import org.apache.directory.shared.kerberos.KerberosUtils;
 import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
 import org.apache.directory.shared.kerberos.codec.types.PrincipalNameType;
@@ -80,6 +82,9 @@
     public static final String[] DEFAULT_ENCRYPTION_TYPES = new String[]
         { "aes128-cts-hmac-sha1-96", "des-cbc-md5", "des3-cbc-sha1-kd" };
 
+    /** The default ReplayCache type */
+    public static final Class<? extends ReplayCache> DEFAULT_REPLAY_CACHE_TYPE = ReplayCacheImpl.class;
+
     /** The primary realm */
     private String primaryRealm = KerberosConfig.DEFAULT_REALM;
 
@@ -119,6 +124,9 @@
     /** Whether to verify the body checksum. */
     private boolean isBodyChecksumVerified = KerberosConfig.DEFAULT_VERIFY_BODY_CHECKSUM;
 
+    /** Replay cache implementing class. */
+    private Class<? extends ReplayCache> replayCacheType = KerberosConfig.DEFAULT_REPLAY_CACHE_TYPE;
+
     /** The encryption types. */
     private Set<EncryptionType> encryptionTypes;
 
@@ -419,6 +427,18 @@
     }
 
 
+    public Class<? extends ReplayCache> getReplayCacheType()
+    {
+        return replayCacheType;
+    }
+
+
+    public void setReplayCacheType( Class<? extends ReplayCache> replayCacheType )
+    {
+        this.replayCacheType = replayCacheType;
+    }
+
+
     public long getMinimumTicketLifetime()
     {
         return minimumTicketLifetime;
diff --git a/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/KdcServer.java b/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/KdcServer.java
index cd919da..c2a3696 100644
--- a/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/KdcServer.java
+++ b/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/KdcServer.java
@@ -29,7 +29,6 @@
 import org.apache.directory.server.kerberos.protocol.KerberosProtocolHandler;
 import org.apache.directory.server.kerberos.protocol.codec.KerberosProtocolCodecFactory;
 import org.apache.directory.server.kerberos.shared.replay.ReplayCache;
-import org.apache.directory.server.kerberos.shared.replay.ReplayCacheImpl;
 import org.apache.directory.server.kerberos.shared.store.PrincipalStore;
 import org.apache.directory.server.protocol.shared.DirectoryBackedService;
 import org.apache.directory.server.protocol.shared.transport.TcpTransport;
@@ -89,6 +88,8 @@
         this.config = config;
         super.setServiceName( SERVICE_NAME );
         super.setSearchBaseDn( config.getSearchBaseDn() );
+
+        initReplayCache();
     }
 
 
@@ -110,10 +111,6 @@
 
         store = new DirectoryPrincipalStore( getDirectoryService(), new Dn( this.getSearchBaseDn() ) );
 
-        LOG.debug( "initializing the kerberos replay cache" );
-
-        replayCache = new ReplayCacheImpl( config.getAllowableClockSkew() );
-
         // Kerberos can use UDP or TCP
         for ( Transport transport : transports )
         {
@@ -255,4 +252,36 @@
 
         return sb.toString();
     }
+
+    private void initReplayCache()
+    {
+        LOG.debug( "initializing the kerberos replay cache" );
+
+        Class<? extends ReplayCache> clazz = config.getReplayCacheType();
+        if ( clazz == null )
+        {
+            LOG.trace( "Kerberos replay cache is disabled" );
+            return;
+        }
+
+        LOG.debug( "Creating ReplayCache of type {}", clazz.getName() );
+        ReplayCache instance = null;
+        try
+        {
+            try
+            {
+                instance = clazz.getConstructor( Long.TYPE ).newInstance( config.getAllowableClockSkew() );
+            }
+            catch ( NoSuchMethodException e )
+            {
+                instance = clazz.newInstance();
+            }
+        }
+        catch ( Exception e )
+        {
+            LOG.error( "Failed to create the ReplayCache instance. No replay cache will be used!", e );
+        }
+        replayCache = instance;
+    }
+
 }
diff --git a/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingService.java b/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingService.java
index 1cd8797..54266b9 100644
--- a/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingService.java
+++ b/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingService.java
@@ -322,7 +322,7 @@
                 EncTicketPart encTicketPart = tgt.getEncTicketPart();
                 EncryptionKey sessionKey = encTicketPart.getKey();
 
-                if ( authenticatorChecksum == null || authenticatorChecksum.getChecksumType() == null
+                if ( authenticatorChecksum.getChecksumType() == null
                     || authenticatorChecksum.getChecksumValue() == null || bodyBytes == null )
                 {
                     throw new KerberosException( ErrorType.KRB_AP_ERR_INAPP_CKSUM );
diff --git a/protocol-kerberos/src/test/java/org/apache/directory/server/kerberos/protocol/TGSReplayCacheTest.java b/protocol-kerberos/src/test/java/org/apache/directory/server/kerberos/protocol/TGSReplayCacheTest.java
new file mode 100644
index 0000000..2273068
--- /dev/null
+++ b/protocol-kerberos/src/test/java/org/apache/directory/server/kerberos/protocol/TGSReplayCacheTest.java
@@ -0,0 +1,193 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ * 
+ */
+package org.apache.directory.server.kerberos.protocol;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.text.ParseException;
+
+import javax.security.auth.kerberos.KerberosPrincipal;
+
+import org.apache.directory.server.kerberos.KerberosConfig;
+import org.apache.directory.server.kerberos.kdc.KdcServer;
+import org.apache.directory.server.kerberos.protocol.AbstractAuthenticationServiceTest.KrbDummySession;
+import org.apache.directory.server.kerberos.shared.crypto.encryption.CipherTextHandler;
+import org.apache.directory.server.kerberos.shared.replay.ReplayCache;
+import org.apache.directory.shared.kerberos.KerberosTime;
+import org.apache.directory.shared.kerberos.codec.options.KdcOptions;
+import org.apache.directory.shared.kerberos.components.EncTicketPart;
+import org.apache.directory.shared.kerberos.components.EncryptionKey;
+import org.apache.directory.shared.kerberos.components.KdcReq;
+import org.apache.directory.shared.kerberos.components.KdcReqBody;
+import org.apache.directory.shared.kerberos.exceptions.ErrorType;
+import org.apache.directory.shared.kerberos.exceptions.KerberosException;
+import org.apache.directory.shared.kerberos.messages.KrbError;
+import org.apache.directory.shared.kerberos.messages.TgsRep;
+import org.apache.directory.shared.kerberos.messages.Ticket;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Tests for configurable {@link ReplayCache}.
+ */
+public class TGSReplayCacheTest extends AbstractTicketGrantingServiceTest
+{
+    private KdcServer kdcServer;
+    private KerberosProtocolHandler handler;
+
+    /**
+     * Shutdown the Kerberos server
+     */
+    @After
+    public void shutDown()
+    {
+        kdcServer.stop();
+    }
+
+    /**
+     * Tests the replay cache is used by default.
+     */
+    @Test
+    public void testDefaultReplayCache() throws Exception
+    {
+        initKdcServer( new KerberosConfig() );
+
+        KdcReq message = createTgsRequest();
+
+        KrbDummySession session = new KrbDummySession();
+        handler.messageReceived( session, message );
+        assertEquals( "session.getMessage() instanceOf", TgsRep.class, session.getMessage().getClass() );
+
+        handler.messageReceived( session, message );
+        Object msg = session.getMessage();
+        assertEquals( "session.getMessage() instanceOf", KrbError.class, msg.getClass() );
+        KrbError error = (KrbError) msg;
+        assertEquals( "Replay not detected", ErrorType.KRB_AP_ERR_REPEAT, error.getErrorCode() );
+    }
+
+    /**
+     * Tests the replay cache is not used if the type is explicitly set to null.
+     */
+    @Test
+    public void testNullReplayCacheType() throws Exception
+    {
+        KerberosConfig config = new KerberosConfig();
+        config.setReplayCacheType( null );
+        initKdcServer( config );
+
+        KdcReq message = createTgsRequest();
+
+        KrbDummySession session = new KrbDummySession();
+        handler.messageReceived( session, message );
+        assertEquals( "session.getMessage() instanceOf", TgsRep.class, session.getMessage().getClass() );
+
+        handler.messageReceived( session, message );
+        assertEquals( "session.getMessage() instanceOf", TgsRep.class, session.getMessage().getClass() );
+    }
+
+    /**
+     * Tests that custom replay cache can be set.
+     */
+    @Test
+    public void testDummyReplayCacheType() throws Exception
+    {
+        KerberosConfig config = new KerberosConfig();
+        config.setReplayCacheType( DisabledReplayCache.class );
+        initKdcServer( config );
+
+        KdcReq message = createTgsRequest();
+
+        KrbDummySession session = new KrbDummySession();
+        handler.messageReceived( session, message );
+        assertEquals( "session.getMessage() instanceOf", TgsRep.class, session.getMessage().getClass() );
+
+        handler.messageReceived( session, message );
+        assertEquals( "session.getMessage() instanceOf", TgsRep.class, session.getMessage().getClass() );
+
+        assertTrue( "Incorrect cache implementation", DisabledReplayCache.replayTested );
+    }
+
+    private KdcReq createTgsRequest() throws KerberosException, ParseException, Exception
+    {
+        // Get the mutable ticket part.
+        KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
+        EncTicketPart encTicketPart = getTicketArchetype( clientPrincipal );
+
+        // Seal the ticket for the server.
+        KerberosPrincipal serverPrincipal = new KerberosPrincipal( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" );
+        String passPhrase = "randomKey";
+        EncryptionKey serverKey = getEncryptionKey( serverPrincipal, passPhrase );
+        Ticket tgt = getTicket( encTicketPart, serverPrincipal, serverKey );
+
+        KdcReqBody kdcReqBody = new KdcReqBody();
+        kdcReqBody.setSName( getPrincipalName( "ldap/ldap.example.com@EXAMPLE.COM" ) );
+        kdcReqBody.setRealm( "EXAMPLE.COM" );
+        kdcReqBody.setEType( kdcServer.getConfig().getEncryptionTypes() );
+        kdcReqBody.setNonce( random.nextInt() );
+        kdcReqBody.setKdcOptions( new KdcOptions() );
+
+        long now = System.currentTimeMillis();
+
+        KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
+        kdcReqBody.setTill( requestedEndTime );
+
+        KdcReq message = getKdcRequest( tgt, kdcReqBody );
+        return message;
+    }
+
+    /**
+     * Creates a new instance of {@link KdcServer}.
+     */
+    private void initKdcServer( KerberosConfig config )
+    {
+        config.setBodyChecksumVerified( false );
+        kdcServer = new KdcServer( config );
+        handler = new KerberosProtocolHandler( kdcServer, new MapPrincipalStoreImpl() );
+        lockBox = new CipherTextHandler();
+    }
+
+    public static class DisabledReplayCache implements ReplayCache
+    {
+
+        public static volatile boolean replayTested = false;
+
+        @Override
+        public boolean isReplay(KerberosPrincipal serverPrincipal, KerberosPrincipal clientPrincipal, KerberosTime clientTime,
+                int clientMicroSeconds)
+        {
+            replayTested = true;
+            return false;
+        }
+
+        @Override
+        public void save(KerberosPrincipal serverPrincipal, KerberosPrincipal clientPrincipal, KerberosTime clientTime,
+                int clientMicroSeconds)
+        {
+        }
+
+        @Override
+        public void clear()
+        {
+        }
+
+    }
+
+}
diff --git a/server-annotations/src/main/java/org/apache/directory/server/annotations/CreateKdcServer.java b/server-annotations/src/main/java/org/apache/directory/server/annotations/CreateKdcServer.java
index 86c6fb7..eb40d63 100644
--- a/server-annotations/src/main/java/org/apache/directory/server/annotations/CreateKdcServer.java
+++ b/server-annotations/src/main/java/org/apache/directory/server/annotations/CreateKdcServer.java
@@ -28,6 +28,8 @@
 import java.lang.annotation.Target;
 
 import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.kerberos.shared.replay.ReplayCache;
+import org.apache.directory.server.kerberos.shared.replay.ReplayCacheImpl;
 
 
 /**
@@ -83,4 +85,7 @@
     
     /** @return the DN of the search base for finding users and services */
     String searchBaseDn() default ServerDNConstants.USER_EXAMPLE_COM_DN;
+
+    /** @return the replay cache implementing class */
+    Class<? extends ReplayCache> replayCacheType() default ReplayCacheImpl.class;
 }
\ No newline at end of file
diff --git a/server-annotations/src/main/java/org/apache/directory/server/factory/ServerAnnotationProcessor.java b/server-annotations/src/main/java/org/apache/directory/server/factory/ServerAnnotationProcessor.java
index be226c6..70f736e 100644
--- a/server-annotations/src/main/java/org/apache/directory/server/factory/ServerAnnotationProcessor.java
+++ b/server-annotations/src/main/java/org/apache/directory/server/factory/ServerAnnotationProcessor.java
@@ -408,6 +408,7 @@
         kdcConfig.setPrimaryRealm( createKdcServer.primaryRealm() );
         kdcConfig.setMaximumTicketLifetime( createKdcServer.maxTicketLifetime() );
         kdcConfig.setMaximumRenewableLifetime( createKdcServer.maxRenewableLifetime() );
+        kdcConfig.setReplayCacheType( createKdcServer.replayCacheType() );
 
         KdcServer kdcServer = new KdcServer( kdcConfig );
 
diff --git a/server-annotations/src/test/java/org/apache/directory/server/factory/CreateKdcServerAnnotationTest.java b/server-annotations/src/test/java/org/apache/directory/server/factory/CreateKdcServerAnnotationTest.java
index fbc4610..dbb6b80 100644
--- a/server-annotations/src/test/java/org/apache/directory/server/factory/CreateKdcServerAnnotationTest.java
+++ b/server-annotations/src/test/java/org/apache/directory/server/factory/CreateKdcServerAnnotationTest.java
@@ -23,6 +23,8 @@
 
 import static org.junit.Assert.assertEquals;
 
+import javax.security.auth.kerberos.KerberosPrincipal;
+
 import org.apache.directory.api.util.FileUtils;
 import org.apache.directory.server.annotations.CreateKdcServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -31,6 +33,8 @@
 import org.apache.directory.server.core.factory.DSAnnotationProcessor;
 import org.apache.directory.server.kerberos.KerberosConfig;
 import org.apache.directory.server.kerberos.kdc.KdcServer;
+import org.apache.directory.server.kerberos.shared.replay.ReplayCache;
+import org.apache.directory.shared.kerberos.KerberosTime;
 import org.apache.mina.util.AvailablePortFinder;
 import org.junit.Test;
 
@@ -47,6 +51,7 @@
         kdcPrincipal = "krbtgt/apache.org@apache.org",
         maxTicketLifetime = 1000,
         maxRenewableLifetime = 2000,
+        replayCacheType = DisabledReplayCache.class,
         transports =
             {
                 @CreateTransport(protocol = "TCP"),
@@ -69,6 +74,7 @@
         assertEquals( "krbtgt/apache.org@apache.org", config.getServicePrincipal().getName() );
         assertEquals( 1000, config.getMaximumTicketLifetime() );
         assertEquals( 2000, config.getMaximumRenewableLifetime() );
+        assertEquals( DisabledReplayCache.class, config.getReplayCacheType() );
         
         server.stop();
         directoryService.shutdown();
@@ -101,11 +107,38 @@
         assertEquals( "krbtgt/apache.org@apache.org", config.getServicePrincipal().getName() );
         assertEquals( 1000, config.getMaximumTicketLifetime() );
         assertEquals( 2000, config.getMaximumRenewableLifetime() );
+        assertEquals( KerberosConfig.DEFAULT_REPLAY_CACHE_TYPE, config.getReplayCacheType() );
         
         server.stop();
         directoryService.shutdown();
 
         FileUtils.deleteDirectory( directoryService.getInstanceLayout().getInstanceDirectory() );
     }
-    
+
+    /**
+     * Empty {@link ReplayCache} implementation which doesn't cache.
+     */
+    public static class DisabledReplayCache implements ReplayCache
+    {
+
+        @Override
+        public boolean isReplay(KerberosPrincipal serverPrincipal, KerberosPrincipal clientPrincipal, KerberosTime clientTime,
+                int clientMicroSeconds)
+        {
+            return false;
+        }
+
+        @Override
+        public void save(KerberosPrincipal serverPrincipal, KerberosPrincipal clientPrincipal, KerberosTime clientTime,
+                int clientMicroSeconds)
+        {
+        }
+
+        @Override
+        public void clear()
+        {
+        }
+
+    }
+
 }
diff --git a/service/pom.xml b/service/pom.xml
index 856b264..c438aaf 100644
--- a/service/pom.xml
+++ b/service/pom.xml
@@ -108,10 +108,11 @@
             <configuration>
               <filters>
                 <filter>
-                  <artifact>org.bouncycastle:bcprov-jdk15on</artifact>
+                  <artifact>*:*</artifact>
                   <excludes>
                     <exclude>META-INF/*.SF</exclude>
                     <exclude>META-INF/*.DSA</exclude>
+                    <exclude>META-INF/*.RSA</exclude>
                   </excludes>
                 </filter>
               </filters>
diff --git a/service/src/test/java/org/apache/directory/server/UberJarMainTest.java b/service/src/test/java/org/apache/directory/server/UberJarMainTest.java
index 5c1c3af..0cb2210 100644
--- a/service/src/test/java/org/apache/directory/server/UberJarMainTest.java
+++ b/service/src/test/java/org/apache/directory/server/UberJarMainTest.java
@@ -35,6 +35,8 @@
 import java.util.Locale;
 import java.util.TimeZone;
 
+import javax.security.auth.x500.X500Principal;
+
 import org.apache.directory.api.ldap.codec.api.SchemaBinaryAttributeDetector;
 import org.apache.directory.api.ldap.model.cursor.EntryCursor;
 import org.apache.directory.api.ldap.model.entry.DefaultEntry;
@@ -44,8 +46,6 @@
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.message.SearchScope;
 import org.apache.directory.api.ldap.model.name.Dn;
-import org.apache.directory.api.ldap.model.schema.ObjectClass;
-import org.apache.directory.api.ldap.model.schema.registries.Schema;
 import org.apache.directory.api.util.Network;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.LdapConnectionConfig;
@@ -57,11 +57,7 @@
 import org.junit.Before;
 import org.junit.Test;
 
-import sun.security.x509.X500Name;
-
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 
 
 /**
@@ -76,10 +72,10 @@
 
     /** The instance directory */
     private File instanceDirectory;
-    
+
     /** The UberjarMain */
     private UberjarMain uberjarMain;
-    
+
     private KeyStore keyStore;
 
     @Before
@@ -98,17 +94,16 @@
 
         // Creating the UberjarMain
         uberjarMain = new UberjarMain();
-        
+
         try
         {
             // Create a temporary keystore, be sure to remove it when exiting the test
             File keyStoreFile = File.createTempFile( "testStore", "ks" );
             keyStoreFile.deleteOnExit();
 
-            
             keyStore = KeyStore.getInstance( KeyStore.getDefaultType() );
             char[] keyStorePassword = "secret".toCharArray();
-            
+
             try ( InputStream keyStoreData = new FileInputStream( keyStoreFile ) )
             {
                 keyStore.load( null, keyStorePassword );
@@ -117,16 +112,17 @@
             // Generate the asymmetric keys, using EC algorithm
             KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( "EC" );
             KeyPair keyPair = keyPairGenerator.generateKeyPair();
-            
+
             // Generate the subject's name
-            @SuppressWarnings("restriction")
-            X500Name owner = new X500Name( "apacheds", "directory", "apache", "US" );
+            X500Principal owner = new X500Principal( "CN=apacheds,OU=directory,O=apache,C=US" );
 
             // Create the self-signed certificate
-            X509Certificate certificate = CertificateUtil.generateSelfSignedCertificate( owner, keyPair, 365, "SHA256WithECDSA" );
-            
-            keyStore.setKeyEntry( "apachedsKey", keyPair.getPrivate(), keyStorePassword, new X509Certificate[] { certificate } );
-            
+            X509Certificate certificate = CertificateUtil.generateSelfSignedCertificate( owner, keyPair, 365,
+                "SHA256WithECDSA" );
+
+            keyStore.setKeyEntry( "apachedsKey", keyPair.getPrivate(), keyStorePassword, new X509Certificate[]
+                { certificate } );
+
             try ( FileOutputStream out = new FileOutputStream( keyStoreFile ) )
             {
                 keyStore.store( out, keyStorePassword );
@@ -134,12 +130,12 @@
         }
         catch ( Exception e )
         {
-            
+
         }
 
     }
 
-    
+
     @After
     public void delete() throws Exception
     {
@@ -148,8 +144,8 @@
             uberjarMain.stop();
         }
     }
-    
-    
+
+
     private LdapConnection createConnection() throws LdapException, UnknownHostException
     {
         LdapConnectionConfig configuration = new LdapConnectionConfig();
@@ -164,11 +160,11 @@
 
         // Binding on the connection
         connection.bind();
-        
+
         return connection;
     }
-    
-    
+
+
     private Thread createServer()
     {
         // First start the server to initialize the example partition 
@@ -180,7 +176,7 @@
             public void run()
             {
                 LdapConnection connection = null;
-                
+
                 try
                 {
                     // Creating a connection on the created server
@@ -188,7 +184,7 @@
 
                     // Looking for the Root DSE entry
                     Entry rootDseEntry = connection.lookup( Dn.ROOT_DSE );
-                    
+
                     if ( rootDseEntry == null )
                     {
                         // This isn't good
@@ -226,51 +222,35 @@
      */
     @Test
     public void nisTest() throws Exception
-    {   
+    {
         // First start the server to initialize the example partition 
         uberjarMain.start( instanceDirectory.toString() );
-        
+
         // Creating a separate thread for the connection verification
         Thread connectionVerificationThread = new Thread()
         {
             public void run()
             {
                 LdapConnection connection = null;
-                
+
                 try
                 {
                     // Creating a connection on the created server
                     connection = createConnection();
-                    connection.setTimeOut( 0L );
-                    
-                    connection.modify( "cn=nis,ou=schema", 
-                        new DefaultModification( 
+
+                    connection.modify( "cn=nis,ou=schema",
+                        new DefaultModification(
                             ModificationOperation.REPLACE_ATTRIBUTE, "m-disabled", "FALSE" ) );
-                    
-                    // Ok, now try to fetch the NIS schema elements
-                    Entry nisSchema = connection.lookup( "cn=nis,ou=schema" );
-                    
-                    assertEquals( "FALSE", nisSchema.get( "m-disabled" ).getString() );
-                    
-                    Entry posixAccount = connection.lookup( "m-oid=1.3.6.1.1.1.2.0,ou=objectClasses,cn=nis,ou=schema" );
-                    
-                    Throwable exception = connection.exceptionCaught();
 
-                    assertNotNull( exception );
-
-                    if ( exception != null )
-                    {
-                        System.out.println( exception.getMessage() );
-                    }
-                    
                     // Reload the schema in order to be able to deal with NIS elements
                     connection.loadSchema();
-                    
-                    posixAccount = connection.lookup( "m-oid=1.3.6.1.1.1.2.0,ou=objectClasses,cn=nis,ou=schema" );
-                    
-                    exception = connection.exceptionCaught();
-                        
-                    assertNull( exception );
+
+                    // Ok, now try to fetch the NIS schema elements
+                    Entry nisSchema = connection.lookup( "cn=nis,ou=schema" );
+
+                    assertEquals( "FALSE", nisSchema.get( "m-disabled" ).getString() );
+
+                    Entry posixAccount = connection.lookup( "m-oid=1.3.6.1.1.1.2.0,ou=objectClasses,cn=nis,ou=schema" );
 
                     if ( posixAccount == null )
                     {
@@ -316,9 +296,9 @@
      */
     @Test
     public void serviceInstanceTest() throws Exception
-    {   
+    {
         Thread connectionVerificationThread = createServer();
-        
+
         // Starting the connection verification thread
         // and waiting for the termination of it
         connectionVerificationThread.start();
@@ -329,15 +309,15 @@
         {
             fail();
         }
-        
+
         // Stop the server
         uberjarMain.stop();
 
         // Restart the server
         uberjarMain.start( instanceDirectory.toString() );
-        
+
         LdapConnection connection = null;
-        
+
         try
         {
             // Creating a connection on the created server
@@ -345,18 +325,18 @@
 
             // Looking for the Root DSE entry
             Entry rootDseEntry = connection.lookup( Dn.ROOT_DSE );
-            
+
             Entry nisSchema = connection.lookup( "cn=nis,ou=schema" );
-            
+
             System.out.println( "Before nis anabling" );
             System.out.println( nisSchema );
 
             Entry nisObjectClass = connection.lookup( "ou=objectClasses,cn=nis,ou=schema" );
 
             System.out.println( nisObjectClass );
-            
+
             Entry posixAccount = connection.lookup( "m-oid=1.3.6.1.1.1.2.0,ou=objectClasses,cn=nis,ou=schema" );
-            
+
             System.out.println( "posixAccount : " + posixAccount );
 
             if ( rootDseEntry == null )
@@ -392,10 +372,10 @@
      */
     @Test
     public void repairTest() throws Exception
-    {   
+    {
         // First start the server to initialize the example partition 
         Thread connectionVerificationThread = createServer();
-        
+
         // Starting the connection verification thread
         // and waiting for the termination of it
         connectionVerificationThread.start();
@@ -406,7 +386,7 @@
         {
             fail();
         }
-        
+
         // Add a few entries to create a more complex hierarchy
         // We will have :
         // dc=example,dc=com
@@ -423,137 +403,125 @@
         //   ou=groups
         //     cn=users
         LdapConnection connection = createConnection();
-        
+
         // First level
-        Entry people = new DefaultEntry( 
+        Entry people = new DefaultEntry(
             "ou=People,dc=example,dc=com",
             "objectClass: organizationalUnit",
             "objectClass: top",
-            "ou: People"
-            );
-        
+            "ou: People" );
+
         connection.add( people );
-        
-        Entry groups = new DefaultEntry( 
+
+        Entry groups = new DefaultEntry(
             "ou=Groups,dc=example,dc=com",
             "objectClass: organizationalUnit",
             "objectClass: top",
-            "ou: Groups"
-            );
-        
+            "ou: Groups" );
+
         connection.add( groups );
-        
+
         // Second level
-        Entry committers  = new DefaultEntry( 
+        Entry committers = new DefaultEntry(
             "ou=Committers,ou=people,dc=example,dc=com",
             "objectClass: organizationalUnit",
             "objectClass: top",
-            "ou: Committers"
-            );
+            "ou: Committers" );
 
         connection.add( committers );
 
-        Entry pmcs  = new DefaultEntry( 
+        Entry pmcs = new DefaultEntry(
             "ou=Pmcs,ou=people,dc=example,dc=com",
             "objectClass: organizationalUnit",
             "objectClass: top",
-            "ou: Pmcs"
-            );
+            "ou: Pmcs" );
 
         connection.add( pmcs );
 
-        Entry users  = new DefaultEntry( 
+        Entry users = new DefaultEntry(
             "ou=Users,ou=people,dc=example,dc=com",
             "objectClass: organizationalUnit",
             "objectClass: top",
-            "ou: Users"
-            );
+            "ou: Users" );
 
         connection.add( users );
 
         // Third level, committers
-        Entry emmanuelCommitter  = new DefaultEntry( 
+        Entry emmanuelCommitter = new DefaultEntry(
             "cn=emmanuel,ou=Committers,ou=people,dc=example,dc=com",
             "objectClass: person",
             "objectClass: top",
             "cn: emmanuel",
-            "sn: Emmanuel Lecharny"
-            );
+            "sn: Emmanuel Lecharny" );
 
         connection.add( emmanuelCommitter );
 
-        Entry kiranCommitter  = new DefaultEntry( 
+        Entry kiranCommitter = new DefaultEntry(
             "cn=kiran,ou=Committers,ou=people,dc=example,dc=com",
             "objectClass: person",
             "objectClass: top",
             "cn: kiran",
-            "sn: Kiran Ayyagari"
-            );
+            "sn: Kiran Ayyagari" );
 
         connection.add( kiranCommitter );
 
-        Entry stefanCommitter  = new DefaultEntry( 
+        Entry stefanCommitter = new DefaultEntry(
             "cn=stefan,ou=Committers,ou=people,dc=example,dc=com",
             "objectClass: person",
             "objectClass: top",
             "cn: stefan",
-            "sn: Stefan Seelmann"
-            );
+            "sn: Stefan Seelmann" );
 
         connection.add( stefanCommitter );
-        
-        Entry radovanCommitter  = new DefaultEntry( 
+
+        Entry radovanCommitter = new DefaultEntry(
             "cn=radovan,ou=Committers,ou=people,dc=example,dc=com",
             "objectClass: person",
             "objectClass: top",
             "cn: radovan",
-            "sn: Radovan Semancik"
-            );
+            "sn: Radovan Semancik" );
 
         connection.add( radovanCommitter );
 
         // Third level, PMCs
-        Entry emmanuelPmc = new DefaultEntry( 
+        Entry emmanuelPmc = new DefaultEntry(
             "cn=emmanuel,ou=Pmcs,ou=people,dc=example,dc=com",
             "objectClass: person",
             "objectClass: top",
             "cn: emmanuel",
-            "sn: Emmanuel Lecharny"
-            );
+            "sn: Emmanuel Lecharny" );
 
         connection.add( emmanuelPmc );
 
-        Entry kiranPmc = new DefaultEntry( 
+        Entry kiranPmc = new DefaultEntry(
             "cn=kiran,ou=Pmcs,ou=people,dc=example,dc=com",
             "objectClass: person",
             "objectClass: top",
             "cn: kiran",
-            "sn: Kiran Ayyagari"
-            );
+            "sn: Kiran Ayyagari" );
 
         connection.add( kiranPmc );
 
-        Entry stefanPmc = new DefaultEntry( 
+        Entry stefanPmc = new DefaultEntry(
             "cn=stefan,ou=Pmcs,ou=people,dc=example,dc=com",
             "objectClass: person",
             "objectClass: top",
             "cn: stefan",
-            "sn: Stefan Seelmann"
-            );
+            "sn: Stefan Seelmann" );
 
         connection.add( stefanPmc );
-        
+
         // Now, check that we have 13 entries
         int entryCount = 0;
-        
-        EntryCursor cursor = connection.search( "dc=example, dc=com","(ObjectClass=*)", SearchScope.SUBTREE, "*" );
-        
+
+        EntryCursor cursor = connection.search( "dc=example, dc=com", "(ObjectClass=*)", SearchScope.SUBTREE, "*" );
+
         while ( cursor.next() )
         {
             cursor.get();
             entryCount++;
         }
-        
+
         assertEquals( 13, entryCount );
 
         // Stop the server
@@ -564,7 +532,7 @@
 
         // And restart it
         connectionVerificationThread = createServer();
-        
+
         // Starting the connection verification thread
         // and waiting for the termination of it
         connectionVerificationThread.start();
@@ -580,15 +548,15 @@
         connection = createConnection();
 
         entryCount = 0;
-        
-        cursor = connection.search( "dc=example, dc=com","(ObjectClass=*)", SearchScope.SUBTREE, "*" );
-        
+
+        cursor = connection.search( "dc=example, dc=com", "(ObjectClass=*)", SearchScope.SUBTREE, "*" );
+
         while ( cursor.next() )
         {
             cursor.get();
             entryCount++;
         }
-        
+
         assertEquals( 13, entryCount );
     }
 }
diff --git a/test-framework/src/main/java/org/apache/directory/server/core/integ/AbstractLdapTestUnit.java b/test-framework/src/main/java/org/apache/directory/server/core/integ/AbstractLdapTestUnit.java
index 9d290c6..b869e8c 100644
--- a/test-framework/src/main/java/org/apache/directory/server/core/integ/AbstractLdapTestUnit.java
+++ b/test-framework/src/main/java/org/apache/directory/server/core/integ/AbstractLdapTestUnit.java
@@ -30,20 +30,19 @@
 import java.security.KeyStore;
 import java.security.cert.X509Certificate;
 
+import javax.security.auth.x500.X500Principal;
+
 import org.apache.directory.server.core.api.DirectoryService;
 import org.apache.directory.server.core.security.CertificateUtil;
 import org.apache.directory.server.kerberos.kdc.KdcServer;
 import org.apache.directory.server.ldap.LdapServer;
 
-import sun.security.x509.X500Name;
-
 
 /**
  * An abstract class created to hold common elements.
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-@SuppressWarnings("restriction")
 public abstract class AbstractLdapTestUnit
 {
     /** The used DirectoryService instance */
@@ -106,10 +105,10 @@
         KeyPair keyPair = keyPairGenerator.generateKeyPair();
         
         // Generate the subject's name
-        X500Name subject = new X500Name( subjectDn, "directory", "apache", "US" );
+        X500Principal subject = new X500Principal( "CN=" + subjectDn + ",OU=directory,O=apache,C=US" );
         
         // Generate the issuer's name
-        X500Name issuer = new X500Name( issuerDn, "directory", "apache", "US" );
+        X500Principal issuer = new X500Principal( "CN=" + issuerDn + ",OU=directory,O=apache,C=US" );
 
         // Create the self-signed certificate
         X509Certificate certificate = CertificateUtil.generateCertificate( subject, issuer, keyPair, days, algorithm );