You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by fe...@apache.org on 2010/08/14 23:19:49 UTC

svn commit: r985583 [1/2] - in /directory/sandbox/felixk/apacheds-docs/src: advanced-user-guide/ advanced-user-guide/data/ advanced-user-guide/data/unit-tests/ advanced-user-guide/images/ basic-user-guide/ main/resources/css/

Author: felixk
Date: Sat Aug 14 21:19:48 2010
New Revision: 985583

URL: http://svn.apache.org/viewvc?rev=985583&view=rev
Log:
Start with advanced-user-guide

Added:
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/data/EmbeddedADS.java   (with props)
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/data/pom.xml   (with props)
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/data/unit-tests/
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/data/unit-tests/pom.xml   (with props)
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/images/ApacheDS_WebApp_UML.png   (with props)
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/images/DirectoryStudio1.png   (with props)
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/images/DirectoryStudio2.png   (with props)
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/images/DirectoryStudio3.png   (with props)
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/images/RootDseServletInBrowser.png   (with props)
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/images/TomcatManagerAppInBrowser.png   (with props)
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/images/WebSphereAdminConsoleInBrowser.png   (with props)
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/images/smile.gif   (with props)
Modified:
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-architecture.xml
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-attributes-entries-schemas.xml
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-community.xml
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-embedding-apacheds.xml
    directory/sandbox/felixk/apacheds-docs/src/basic-user-guide/chapter-basic-security.xml
    directory/sandbox/felixk/apacheds-docs/src/basic-user-guide/chapter-basic-user-guide.xml
    directory/sandbox/felixk/apacheds-docs/src/basic-user-guide/chapter-how-to-begin.xml
    directory/sandbox/felixk/apacheds-docs/src/main/resources/css/common_20091029.css

Modified: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-architecture.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-architecture.xml?rev=985583&r1=985582&r2=985583&view=diff
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-architecture.xml (original)
+++ directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-architecture.xml Sat Aug 14 21:19:48 2010
@@ -157,10 +157,10 @@
                 <para>One might ask when is the call made against the actual nexus. This happens using a special
                   Interceptor which resides at the end of the chain. It actually makes the call against the nexus and
                   returns the results.</para>
-                <note>
+                <important>
                   <para>Interceptors can be seen as Servlet Filters : they can be added, removed, bypassed either by
                     configuration or, for embeded servers, on the fly.</para>
-                </note>
+                </important>
               </entry>
               <entry>
                 <para>The following picture describe the Interceptors mechanisms :</para>

Modified: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-attributes-entries-schemas.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-attributes-entries-schemas.xml?rev=985583&r1=985582&r2=985583&view=diff
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-attributes-entries-schemas.xml (original)
+++ directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-attributes-entries-schemas.xml Sat Aug 14 21:19:48 2010
@@ -85,7 +85,7 @@
         contrast to the 1.0 release, ApacheDS 1.5.0 comes with a completely redesigned schema subsystem. It enables
         dynamic schema updates, like the creation of new attribute types or object classes at runtime (i.e. without
         restarting the server).</para>
-      <note>
+      <important>
         <title>Is it always necessary to define my own schema elements?</title>
         <para>
           No. ApacheDS comes with a comprehensive set of predefined, standardized schema elements (like
@@ -93,7 +93,7 @@
           ). It is quite common to solely use the predefined schema. The same holds true for other directory servers, by
           the way.
         </para>
-      </note>
+      </important>
       <para>In the following text the addition of user defined schema elements to the schema is described in tutorial
         style.</para>
     </section>

Modified: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml?rev=985583&r1=985582&r2=985583&view=diff
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml (original)
+++ directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml Sat Aug 14 21:19:48 2010
@@ -559,9 +559,9 @@ $ ldapsearch -H ldap://ldap.example.com 
   <section
     id="Writing a custom authenticator">
     <title>Writing a custom authenticator</title>
-    <note>
+    <important>
       <para>This page is out of date</para>
-    </note>
+    </important>
     <section
       id="Using custom authenticators">
       <title>Using custom authenticators</title>
@@ -665,12 +665,12 @@ server.authenticator.properties.yourauth
             role="bold">entryACI</emphasis>
           attribute contain ACIItems.
         </para>
-        <note>
+        <important>
           <para>There is one exception to the rule of consulting entryACI attributes within ApacheDS: add operations do
             not consult the entryACI within the entry being added. This is a security precaution. If allowed users can
             arbitrarily add entries where they wanted by putting entryACI into the new entry being added. This could
             comprimise the DSA.</para>
-        </note>
+        </important>
       </section>
       <section
         id="Prescriptive ACI">
@@ -974,11 +974,11 @@ server.authenticator.properties.yourauth
       <section
         id="Enable Authenticated Users to Browse and Read Entries in a Subtree">
         <title>Enable Authenticated Users to Browse and Read Entries in a Subtree</title>
-        <note>
+        <important>
           <title>The first time is always the hardest!</title>
           <para>We presume this is your first encounter and so many bases will be covered this time around. Every other
             trail will build on this information. So expect a little less to read as you gain momentum.</para>
-        </note>
+        </important>
         <para>Since the entire directory is locked down for all but the superuser, you're going to want to grant read
           and browse access to users for certain regions of the DIT. This will probably be the first thing you'll want
           to do after turning on access controls.</para>
@@ -1142,11 +1142,11 @@ server.authenticator.properties.yourauth
             <title>precedence</title>
             <para>Precendence is used to determine the ACI to apply when two or more ACIItem's applied to an entry
               conflict. The ACIItem with the highest precedence is applied over other conflicting ACIItems.</para>
-            <note>
+            <important>
               <title>Denials Overpower Grants</title>
               <para>When two or more conflicting ACIItems are encountered with the same precedence the ACIItems with
                 denials overpower ACIItems with grants.</para>
-            </note>
+            </important>
             <para>Right now the use of this field may not mean too much to you. We're dealing with a very simple
               situation with a single access control area. Later as you add more subentries their subtreeSpecifications
               may define collections that intersect. When this happens two or more conflicting ACIItems may apply to the
@@ -1318,12 +1318,12 @@ server.authenticator.properties.yourauth
           membership within
           the group.
         </para>
-        <note>
+        <important>
           <para>Although such group entries can be added anywhere within the DIT to be recognized by the Authorization
             subsystem, a recommended convention exists. Use the 'ou=groups' container under a namingContext/partition
             within the server to localize groups. Most of the time group information can be stored under
             'ou=groups,ou=system'.</para>
-        </note>
+        </important>
         <para>
           Just like the
           <emphasis
@@ -1371,11 +1371,11 @@ server.authenticator.properties.yourauth
             linkend="The Administrative Model" />
           .
         </para>
-        <note>
+        <important>
           <para>For this purpose a subtree is not refined. Meaning it does not evaluate refinement filters. This is to
             restrict the information needed to make a determination to just the DN of the requestor and not the entry of
             the requestor.</para>
-        </note>
+        </important>
       </section>
     </section>
     <section

Modified: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-community.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-community.xml?rev=985583&r1=985582&r2=985583&view=diff
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-community.xml (original)
+++ directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-community.xml Sat Aug 14 21:19:48 2010
@@ -302,7 +302,7 @@ mvn eclipse:eclipse
           role="bold">JDK 5</emphasis>
         installed on your computer. A working internet connection is also mandatory.
       </para>
-      <note>
+      <important>
         <para>
           If the build hangs or you get an out of memory exception please increase the heap space:
           <itemizedlist>
@@ -325,7 +325,7 @@ mvn clean install
             </listitem>
           </itemizedlist>
         </para>
-      </note>
+      </important>
       <section
         id="Maven">
         <title>Maven</title>
@@ -379,7 +379,7 @@ svn co https://svn.apache.org/repos/asf/
       <section
         id="Enabling Snapshot Repositories">
         <title>Enabling Snapshot Repositories</title>
-        <note>
+        <important>
           <para>The following information is only needed if one want to setup its own maven repo. There is no need to
             define a settings.xml file for generic usage.</para>
           <para>Before building the trunks, you must configure Maven 2 to use the snapshot repository for Apache.
@@ -422,7 +422,7 @@ svn co https://svn.apache.org/repos/asf/
   </profiles>
 </settings>
         ]]></programlisting>
-        </note>
+        </important>
         <para>You may either specify the profile at the command-line, each time you use 'mvn', or you may configure the
           profile to always be active.</para>
         <para>To use a profile at the command-line:</para>

Modified: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-embedding-apacheds.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-embedding-apacheds.xml?rev=985583&r1=985582&r2=985583&view=diff
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-embedding-apacheds.xml (original)
+++ directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-embedding-apacheds.xml Sat Aug 14 21:19:48 2010
@@ -19,13 +19,1758 @@
   <section
     id="Embedding ApacheDS into an application">
     <title>Embedding ApacheDS into an application</title>
+    <info>
+      <title>ApacheDS 1.5.5</title>
+      <para>This site was updated for ApacheDS 1.5.5.</para>
+    </info>
+    <para>The idea is to use the server directly without having to communicate with a remote server, eliminating all the
+      network layer. This is one of the reason ADS has been developed in Java: to allow such usage.</para>
+    <para>will go through a very simple example step by step to show you how this can be done.</para>
+    <section
+      id="Setting up the environment">
+      <title>Setting up the environment</title>
+      <para>We first need to define a base for our project. We use Maven (2.0.9 or above) to build our project, so the
+        structure we will use looks like this:</para>
+      <programlisting><![CDATA[
+.
+|-- pom.xml
+`-- src
+    `-- main
+        `-- java
+            `-- org
+                `-- apache
+                    `-- directory
+                        `-- EmbeddedADS.java
+        ]]></programlisting>
+      <para>
+        You could download both files here:
+        <itemizedlist>
+          <listitem>
+            <para>
+              <link
+                xlink:href="data/EmbeddedADS.java"></link>
+            </para>
+          </listitem>
+          <listitem>
+            <para>
+              <link
+                xlink:href="data/pom.xml">pom.xml</link>
+            </para>
+          </listitem>
+        </itemizedlist>
+      </para>
+      <important>
+        <para>If you don't want to use Maven you need to add the following dependencies to your classpath in order to
+          compile and run this sample.</para>
+        <itemizedlist>
+          <listitem>
+            <para>apacheds-all-1.5.5.jar</para>
+          </listitem>
+          <listitem>
+            <para>slf4j-api-1.5.6.jar</para>
+          </listitem>
+          <listitem>
+            <para>slf4j-log4j12-1.5.6.jar</para>
+          </listitem>
+          <listitem>
+            <para>log4j-1.2.14.jar</para>
+          </listitem>
+        </itemizedlist>
+      </important>
+    </section>
+    <section
+      id="Creating the application">
+      <title>Creating the application</title>
+      <para>So let's start with the code. It's quite simple: we define a class, add a main() method, and initialize the
+        server, before using it. In the code snippet below, we have removed all the initialization part to keep only the
+        main() method.</para>
+      <programlisting><![CDATA[
+package org.apache.directory;
+
+/**
+ * A simple example exposing how to embed Apache Directory Server
+ * into an application.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class EmbeddedADS
+{
+    /** The directory service */
+    private DirectoryService service;
+
+    ...
+
+    /**
+     * Creates a new instance of EmbeddedADS. It initializes the directory service.
+     *
+     * @throws Exception If something went wrong
+     */
+    public EmbeddedADS() throws Exception
+    {
+        init();
+    }
+
+    /**
+     * Main class. We just do a lookup on the server to check that it's available.
+     *
+     * @param args Not used. 
+     */
+    public static void main( String[] args ) //throws Exception 
+    {
+        try
+        {
+            // Create the server
+            EmbeddedADS ads = new EmbeddedADS();
+            
+            // Read an entry
+            Entry result = ads.service.getAdminSession().lookup( new LdapDN( "dc=apache,dc=org" ) );
+            
+            // And print it if available
+            System.out.println( "Found entry : " + result );
+        }
+        catch ( Exception e )
+        {
+            // Ok, we have something wrong going on ...
+            e.printStackTrace();
+        }
+    }
+}
+    ]]></programlisting>
+      <para>As you can see, we first initialize the server, and immediately do a lookup to check that we can read an
+        entry from it.</para>
+      <para>Let's focus on the initialization part now.</para>
+    </section>
+    <section
+      id="Initializing the server">
+      <title>Initializing the server</title>
+      <para>
+        This is done in the
+        <emphasis
+          role="bold">init()</emphasis>
+        method. It will create the DirectoryService global object (
+        <emphasis
+          role="bold">service</emphasis>
+        ), and create a partition in which we will store the entries.
+      </para>
+      <important>
+        <para>A partition is a storage point, associated with a DN, root point for this partition. It's a bit like a
+          mounting point on Unix.
+          We also need a context entry associated to this DN.</para>
+      </important>
+      <para>
+        Here, we will create the
+        <emphasis
+          role="bold">apache</emphasis>
+        partition, associated with the 'dc=apache,dc=org' DN.
+      </para>
+      <para>Here is the code for this method :</para>
+      <programlisting><![CDATA[
+    ...
+
+    /**
+     * Initialize the server. It creates the partition, adds the index, and
+     * injects the context entries for the created partitions.
+     *
+     * @throws Exception if there were some problems while initializing the system
+     */
+    private void init() throws Exception
+    {
+        // Initialize the LDAP service
+        service = new DefaultDirectoryService();
+        
+        // Disable the ChangeLog system
+        service.getChangeLog().setEnabled( false );
+
+        // Create a new partition named 'apache'.
+        Partition apachePartition = addPartition( "apache", "dc=apache,dc=org" );
+        
+        // Index some attributes on the apache partition
+        addIndex( apachePartition, "objectClass", "ou", "uid" );
+        
+        // And start the service
+        service.startup();
+        
+        // Inject the apache root entry if it does not already exist
+        if ( !service.getAdminSession().exists( apachePartition.getSuffixDn() ) )
+        {
+            LdapDN dnApache = new LdapDN( "dc=Apache,dc=Org" );
+            ServerEntry entryApache = service.newEntry( dnApache );
+            entryApache.add( "objectClass", "top", "domain", "extensibleObject" );
+            entryApache.add( "dc", "Apache" );
+            service.getAdminSession().add( entryApache );
+        }
+        
+        // We are all done !
+    }
+
+    ...
+      ]]></programlisting>
+      <para>
+        We disabled the
+        <emphasis
+          role="bold">ChangeLog</emphasis>
+        service because it's useless in our case. As you can see, the steps to initialize the server are:
+      </para>
+      <itemizedlist>
+        <listitem>
+          <para>create a new DirectoryService instance</para>
+        </listitem>
+        <listitem>
+          <para>add a partition</para>
+        </listitem>
+        <listitem>
+          <para>add some index</para>
+        </listitem>
+        <listitem>
+          <para>start the service</para>
+        </listitem>
+        <listitem>
+          <para>add the context entry</para>
+        </listitem>
+      </itemizedlist>
+      <para>One important point: as the data are remanent, we have to check that the added context entry does not exist
+        already before adding it.</para>
+      <para>
+        Some helper methods have been used :
+        <emphasis
+          role="bold">addPartition</emphasis>
+        and
+        <emphasis
+          role="bold">addIndex</emphasis>
+        . Here they are :
+      </para>
+      <programlisting><![CDATA[
+   ...
+
+    /**
+     * Add a new partition to the server
+     *
+     * @param partitionId The partition Id
+     * @param partitionDn The partition DN
+     * @return The newly added partition
+     * @throws Exception If the partition can't be added
+     */
+    private Partition addPartition( String partitionId, String partitionDn ) throws Exception
+    {
+        // Create a new partition named 'foo'.
+        Partition partition = new JdbmPartition();
+        partition.setId( partitionId );
+        partition.setSuffix( partitionDn );
+        service.addPartition( partition );
+        
+        return partition;
+    }
+    
+    
+    /**
+     * Add a new set of index on the given attributes
+     *
+     * @param partition The partition on which we want to add index
+     * @param attrs The list of attributes to index
+     */
+    private void addIndex( Partition partition, String... attrs )
+    {
+        // Index some attributes on the apache partition
+        HashSet<Index<?, ServerEntry>> indexedAttributes = new HashSet<Index<?, ServerEntry>>();
+        
+        for ( String attribute:attrs )
+        {
+            indexedAttributes.add( new JdbmIndex<String,ServerEntry>( attribute ) );
+        }
+        
+        ((JdbmPartition)partition).setIndexedAttributes( indexedAttributes );
+    }
+
+    ...
+      ]]></programlisting>
+      <para>That's it! (the attached code will contain the needed imports)</para>
+    </section>
+    <section
+      id="Building the sample">
+      <title>Building the sample</title>
+      <para>Using Maven this is easy:</para>
+      <screen><![CDATA[
+$ mvn clean compile
+[INFO] Scanning for projects...
+[INFO] ------------------------------------------------------------------------
+[INFO] Building ApacheDS embedded sample
+[INFO]    task-segment: [clean, compile]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] Deleting directory /tmp/EmbeddedADS/target
+[INFO] [resources:resources {execution: default-resources}]
+[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
+[INFO] skip non existing resourceDirectory /tmp/EmbeddedADS/src/main/resources
+[INFO] [compiler:compile {execution: default-compile}]
+[INFO] Compiling 1 source file to /tmp/EmbeddedADS/target/classes
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 2 seconds
+[INFO] Finished at: Sat Nov 28 20:02:23 CET 2009
+[INFO] Final Memory: 17M/76M
+[INFO] ------------------------------------------------------------------------
+    ]]></screen>
+      <para>
+        The resulting jar can be found in the
+        <emphasis
+          role="bold">target</emphasis>
+        directory.
+      </para>
+    </section>
+    <section
+      id="Running the sample">
+      <title>Running the sample</title>
+      <para>Using Maven this is easy:</para>
+      <screen><![CDATA[
+$ mvn exec:java -Dexec.mainClass=org.apache.directory.EmbeddedADS
+[INFO] Scanning for projects...
+[INFO] Searching repository for plugin with prefix: 'exec'.
+[INFO] ------------------------------------------------------------------------
+[INFO] Building ApacheDS embedded sample
+[INFO]    task-segment: [exec:java]
+[INFO] ------------------------------------------------------------------------
+[INFO] Preparing exec:java
+[INFO] No goals needed for project - skipping
+[INFO] [exec:java {execution: default-cli}]
+    ]]></screen>
+      <para>When the main method is run, you should obtain something like :</para>
+      <screen><![CDATA[
+log4j:WARN No appenders could be found for logger (org.apache.directory.server.schema.registries.DefaultNormalizerRegistry).
+log4j:WARN Please initialize the log4j system properly.
+Found entry : ServerEntry
+    dn[n]: dc=Apache,dc=Org
+    objectClass: extensibleObject
+    objectClass: domain
+    objectClass: top
+    dc: Apache
+    ]]></screen>
+      <para>That's it!</para>
+    </section>
   </section>
   <section
     id="Using ApacheDS for unit tests">
     <title>Using ApacheDS for unit tests</title>
+    <warning>
+      <para>This page describes how to define your own unit tests, using ApacheDS 1.5.6.</para>
+    </warning>
+    <para>The idea is to use ADS as an embedded server for Ldap junit tests. We will build an environment in which it
+      will be convenient to test Ldap applications.</para>
+    <para>We also want to avoid launching the server for every test, as it's an expensive operation. We have built
+      ApacheDS so that you can start a server, inject some data, launch a test, then revert the data and go on to
+      another test. At the end of the tests, the server is stopped.</para>
+    <section
+      id="First steps">
+      <title>First steps</title>
+      <para>We have two choices : either we launch the server totally embedded, without having to communicate with it
+        using the Ldap Protocol, or we want to use the server as a remote server, with Ldap protocol in the middle (it
+        can be useful if one want to test specific applications). In both cases, the server is started and stopped by
+        the unit test.</para>
+      <para>We will simply launch only one server (if one want to test referrals, it might be necessary to initialize 2
+        or more servers)</para>
+      <important>
+        <para>We are using JUnit 4.7</para>
+      </important>
+      <para>
+        We have to define a layout for the files and directory we will use in this tutorial. Let's use the
+        <emphasis
+          role="bold">maven</emphasis>
+        layout :
+      </para>
+      <programlisting><![CDATA[
+/
+|
++--src
+    |
+    +--test
+        |
+        +--java      : we will put all the sources into this directory
+        |
+        +--resources : we will put the resources files into this directory
+      ]]></programlisting>
+    </section>
+    <section
+      id="Creating a blank test">
+      <title>Creating a blank test</title>
+      <para>So let's define the framework we need for a simple unit test, using a server which will be invoked through
+        socket (the first free port above 1023 will be used). This first test will do a search operation on a server.
+      </para>
+      <programlisting><![CDATA[
+package org.apache.directory.server.test;
+
+import static org.apache.directory.server.integ.ServerIntegrationUtils.getWiredContext;
+import static org.junit.Assert.assertTrue;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.LdapContext;
+
+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.apache.directory.server.ldap.LdapServer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+@RunWith(FrameworkRunner.class)
+@CreateLdapServer(
+    transports =
+      { 
+        @CreateTransport(protocol = "LDAP") 
+      })
+public class SearchTests extends AbstractLdapTestUnit
+{
+    public static LdapServer ldapServer;
+
+    @Test
+    public void testSearchAllAttrs() throws Exception
+    {
+        LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer, null ).lookup( "ou=system" );
+
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+        controls.setReturningAttributes( new String[]
+            { "+", "*" } );
+
+        NamingEnumeration<SearchResult> res = ctx.search( "", "(ObjectClass=*)", controls );
+
+        assertTrue( res.hasMore() );
+
+        while ( res.hasMoreElements() )
+        {
+            SearchResult result = ( SearchResult ) res.next();
+
+            System.out.println( result.getName() );
+        }
+    }
+}
+    ]]></programlisting>
+      <para>In order to have this test running, you will need to declare some libraries. The best solution is clearly to
+        define a pom.xml file for that purpose. Here it is :</para>
+      <programlisting><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" 
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.directory.server</groupId>
+  <artifactId>apacheds-unit-test</artifactId>
+  <version>1.5.5-SNAPSHOT</version>
+  <name>ApacheDS Server Unit</name>
+  <packaging>jar</packaging>  
+
+  <description>
+    Unit test for ApacheDS Server JNDI Provider
+  </description>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.7</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>1.2.14</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <version>1.5.10</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-all</artifactId>
+      <version>1.5.6-SNAPSHOT</version>
+    </dependency>  
+
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-server-integ</artifactId>
+      <version>1.5.6-SNAPSHOT</version>
+    </dependency>  
+
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-core-integ</artifactId>
+      <version>1.5.6-SNAPSHOT</version>
+    </dependency>  
+
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>1.4</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>2.0.2</version>
+          <configuration>
+            <source>1.5</source>
+            <target>1.5</target>
+
+            <optimize>true</optimize>
+            <showDeprecations>true</showDeprecations>
+            <encoding>ISO-8859-1</encoding>
+          </configuration>
+        </plugin>
+        <plugin>
+          <artifactId>maven-surefire-plugin</artifactId>
+          <configuration>
+            <argLine>-Xmx1024m</argLine>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
+    ]]></programlisting>
+      <para>Is that it ? Pretty much. All you have to do now is to run the test, using a Java 5 JVM and Maven 2.0.9 :
+      </para>
+      <screen><![CDATA[
+#user:~/ws-ads-1.5.4/UnitTest$ mvn test
+[INFO] Scanning for projects...
+[INFO] ------------------------------------------------------------------------
+[INFO] Building ApacheDS Server Unit
+[INFO]    task-segment: [test]
+[INFO] ------------------------------------------------------------------------
+[INFO] [resources:resources]
+[INFO] Using default encoding to copy filtered resources.
+[INFO] [compiler:compile]
+[INFO] No sources to compile
+[INFO] [resources:testResources]
+[INFO] Using default encoding to copy filtered resources.
+[INFO] [compiler:testCompile]
+[INFO] Nothing to compile - all classes are up to date
+[INFO] [surefire:test]
+[INFO] Surefire report directory: /home/elecharny/ws-ads-1.5.4/UnitTest/target/surefire-reports
+
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+Running SimpleTest
+log4j:WARN No appenders could be found for logger (org.apache.directory.server.integ.SiRunner).
+log4j:WARN Please initialize the log4j system properly.
+Ldap service started.
+Ldap service stopped.
+Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.114 sec
+
+Results :
+
+Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
+
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 10 seconds
+[INFO] Finished at: Fri Nov 21 15:40:32 CET 2008
+[INFO] Final Memory: 11M/83M
+[INFO] ------------------------------------------------------------------------
+#user:~/ws-ads-1.5.4/UnitTest$ 
+    ]]></screen>
+      <para>You have written your very first test using the test framework provided in ADS 1.5.5 !</para>
+      <para>Here are the test files :</para>
+      <itemizedlist>
+        <listitem>
+          <para>
+            <link
+              xlink:href="data/unit-tests/SearchTests.java">SearchTests.java</link>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            <link
+              xlink:href="data/unit-tests/pom.xml">pom.xml</link>
+          </para>
+        </listitem>
+      </itemizedlist>
+      <section
+        id="Test description">
+        <title>Test description</title>
+        <para>Ok, we have a running test, but when it comes to write your own, you need a bit more information. Let's
+          try to explain the different parts of this test.</para>
+        <section
+          id="Annotations">
+          <title>Annotations</title>
+          <para>The first interesting part is the annotations we are using. As we said, the server is launched
+            automatically, and we are using the ChangeLog mechanism to restore the base in a pristine state between each
+            test. This is done with annotations.</para>
+          <table
+            id="Test Annotations table">
+            <title>Test Annotations</title>
+            <tgroup
+              cols="4">
+              <thead>
+                <row>
+                  <entry>Annotation</entry>
+                  <entry>Parameter</entry>
+                  <entry>Default value</entry>
+                  <entry>Description</entry>
+                </row>
+              </thead>
+              <tbody>
+                <row>
+                  <entry>@RunWith</entry>
+                  <entry>FrameworkRunner.class</entry>
+                  <entry>none</entry>
+                  <entry>
+                    Run the test with the defined Runner, instead of the default JUNIT one.<?linebreak?>
+                    This is mandatory to add this annotation, as it determinate the way the server
+                    will be clean when
+                    each test has run
+                  </entry>
+                </row>
+                <row>
+                  <entry>@CreateLdapServer</entry>
+                  <entry>transports</entry>
+                  <entry>none</entry>
+                  <entry>Create the LdapServer that will be used for the tests</entry>
+                </row>
+                <row>
+                  <entry>@CreateTransports</entry>
+                  <entry>protocol</entry>
+                  <entry>none</entry>
+                  <entry>Define the transport to use</entry>
+                </row>
+                <row>
+                  <entry>@ApplyLdifs</entry>
+                  <entry>A list of entries in a LDIF format</entry>
+                  <entry>none</entry>
+                  <entry>
+                    This is one of the most interesting new feature :<?linebreak?>
+                    you can define the data you need to be present when the server is started, they will be injected
+                    before the first test is run (it will also depend on the CleanupLevel).
+                  </entry>
+                </row>
+                <row>
+                  <entry>@ApplyLdifFiles</entry>
+                  <entry>A list of files containing LDIF entries</entry>
+                  <entry>none</entry>
+                  <entry>Give sthe list of files to be injected
+                    into the server before the tests are run.</entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </table>
+        </section>
+        <section
+          id="Server startup">
+          <title>Server startup</title>
+          <para>As you can see in the test, there is no place where you tell the server to be started. This is done by
+            the FrameworkRunner. When the tests are all done, the server is also automatically shutdown, and all the
+            created files are removed.</para>
+          <para>
+            The initialization will update a static
+            <emphasis
+              role="bold">ldapServer</emphasis>
+            instance which is declared in the inherited
+            AbstractLdapTestUnit class.
+          </para>
+          <para>You just have to focus on writing your own tests !</para>
+        </section>
+        <section
+          id="Writing your own test using JNDI">
+          <title>Writing your own test using JNDI</title>
+          <para>All the LDAP operation are supported, you just have to use the JNDI API to write your tests. The only
+            difference is the way you get a context : you have to use one of those methods :</para>
+          <programlisting><![CDATA[
+/**
+ * Creates a JNDI LdapContext with a connection over the wire using the 
+ * SUN LDAP provider.  The connection is made using the administrative 
+ * user as the principalDN.  The context is to the rootDSE.
+ *
+ * @param ldapServer the LDAP server to get the connection to
+ * @return an LdapContext as the administrative user to the RootDSE
+ * @throws Exception if there are problems creating the context
+ */
+public static LdapContext getWiredContext( LdapServer ldapServer )
+
+/**
+ * Creates a JNDI LdapContext with a connection over the wire using the 
+ * SUN LDAP provider.  The connection is made using the administrative 
+ * user as the principalDN.  The context is to the rootDSE.
+ *
+ * @param ldapServer the LDAP server to get the connection to
+ * @return an LdapContext as the administrative user to the RootDSE
+ * @throws Exception if there are problems creating the context
+ */
+public static LdapContext getWiredContext( LdapServer ldapServer, Control[] controls )
+
+/**
+ * Creates a JNDI LdapContext with a connection over the wire using the 
+ * SUN LDAP provider.  The connection is made using the administrative 
+ * user as the principalDN.  The context is to the rootDSE.
+ *
+ * @param ldapServer the LDAP server to get the connection to
+ * @return an LdapContext as the administrative user to the RootDSE
+ * @throws Exception if there are problems creating the context
+ */
+public static LdapContext getWiredContext( LdapServer ldapServer, String principalDn, String password )
+        ]]></programlisting>
+          <para>That's it ! Everything else is just pure JNDI</para>
+        </section>
+        <section
+          id="Writing your own tests using the Netscape API">
+          <title>Writing your own tests using the Netscape API</title>
+          <para>If you don't like JNDI, or prefer to use the Netscape API (LdapSdk-4.1), you have two major differences
+            :</para>
+          <itemizedlist>
+            <listitem>
+              <para>first you have to add this API jar into the dependencies in the pom.xml file</para>
+            </listitem>
+            <listitem>
+              <para>second you will use the getWiredConnection() method instead of the getWiredContext().</para>
+            </listitem>
+          </itemizedlist>
+          <para>The API is :</para>
+          <programlisting><![CDATA[
+public static LDAPConnection getWiredConnection( LdapServer ldapServer )
+public static LDAPConnection getWiredConnection( LdapServer ldapServer, 
+                               String principalDn, String password )
+        ]]></programlisting>
+          <para>Both methods are similar to the getWiredContext which has been described before, except that they return
+            a LdapConnection instance.</para>
+          <warning>
+            <para>Starting here, the document has to be reviewed...</para>
+          </warning>
+        </section>
+      </section>
+    </section>
+    <section
+      id="Creating our own partition">
+      <title>Creating our own partition</title>
+      <para>
+        At the moment, we have created a server which is not totally empty : one partition is created by default, the
+        system partition. We won't use it for our tests, so we will need to create our own partition to play with.
+        Let's
+        call it 'o=sevenseas' (
+        <emphasis
+          role="bold">o</emphasis>
+        stands for
+        <emphasis
+          role="bold">organization</emphasis>
+        )
+      </para>
+      <para>The setUp() method will be completed with all the needed instruction to create a new partition</para>
+      <programlisting><![CDATA[
+import java.io.File;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+
+import org.apache.directory.server.core.configuration.MutablePartitionConfiguration;
+import org.apache.directory.server.unit.AbstractServerTest;
+...
+
+    /**
+     * Initialize the server.
+     */
+    public void setUp() throws Exception
+    {
+        // Add partition 'sevenSeas'
+        MutablePartitionConfiguration pcfg = new MutablePartitionConfiguration();
+        pcfg.setName( "sevenSeas" );
+        pcfg.setSuffix( "o=sevenseas" );
+
+        // Create some indices
+        Set<String> indexedAttrs = new HashSet<String>();
+        indexedAttrs.add( "objectClass" );
+        indexedAttrs.add( "o" );
+        pcfg.setIndexedAttributes( indexedAttrs );
+
+        // Create a first entry associated to the partition
+        Attributes attrs = new BasicAttributes( true );
+
+        // First, the objectClass attribute
+        Attribute attr = new BasicAttribute( "objectClass" );
+        attr.add( "top" );
+        attr.add( "organization" );
+        attrs.put( attr );
+
+        // The the 'Organization' attribute
+        attr = new BasicAttribute( "o" );
+        attr.add( "sevenseas" );
+        attrs.put( attr );
+
+        // Associate this entry to the partition
+        pcfg.setContextEntry( attrs );
+
+        // As we can create more than one partition, we must store
+        // each created partition in a Set before initialization
+        Set<MutablePartitionConfiguration> pcfgs = new HashSet<MutablePartitionConfiguration>();
+        pcfgs.add( pcfg );
+
+        configuration.setContextPartitionConfigurations( pcfgs );
+
+        // Create a working directory
+        File workingDirectory = new File( "server-work" );
+        configuration.setWorkingDirectory( workingDirectory );
+
+        // Now, let's call the upper class which is responsible for the
+        // partitions creation
+        super.setUp();
+   }
+        ]]></programlisting>
+      <para>
+        Ok, now the partition
+        <emphasis
+          role="bold">sevenseas</emphasis>
+        should be created. How can we be sure of that ? let's write a test to replace the emptytest() method :
+      </para>
+      <programlisting><![CDATA[
+/**
+     * Test that the partition has been correctly created
+     */
+    public void testPartition() throws NamingException
+    {
+        Hashtable<Object, Object> env = new Hashtable<Object, Object>( configuration.toJndiEnvironment() );
+
+        // Create a new context pointing to the overseas partition
+        env.put( Context.PROVIDER_URL, "o=sevenSeas" );
+        env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
+        env.put( Context.SECURITY_CREDENTIALS, "secret" );
+        env.put( Context.SECURITY_AUTHENTICATION, "simple" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.directory.server.jndi.ServerContextFactory" );
+
+        // Let's open a connection on this partition
+        InitialContext initialContext = new InitialContext( env );
+
+        // We should be able to read it
+        DirContext appRoot = ( DirContext ) initialContext.lookup( "" );
+        assertNotNull( appRoot );
+
+        // Let's get the entry associated to the top level
+        Attributes attributes = appRoot.getAttributes( "" );
+        assertNotNull( attributes );
+        assertEquals( "sevenseas", attributes.get( "o" ).get() );
+
+        Attribute attribute = attributes.get( "objectClass" );
+        assertNotNull( attribute );
+        assertTrue( attribute.contains( "top" ) );
+        assertTrue( attribute.contains( "organization" ) );
+        // Ok, everything is fine
+    }
+      ]]></programlisting>
+      <para>The test should succeed. Is that all ? Well, almost. As you can see, a working space has been created (
+        "server-work", at the end of the setup). Do we have to take care of this working space? No. It has been cleaned
+        by the super class !</para>
+      <para>So everything is fine, the partition is up and running, you are ready to add more tests.</para>
+      <para>One line in the logs is interesting :</para>
+      <screen><![CDATA[
+3879 [main] INFO org.apache.directory.server.jndi.ServerContextFactory -
+LDIF load directory not specified.  No LDIF files will be loaded.
+      ]]></screen>
+      <para>The setup has tried to load an LDIF file to inject some data into the partition, but as we didn't specify
+        any Ldif file to be loaded, nothing has been done. let's add some data !</para>
+    </section>
+    <section
+      id="Adding some data into the partition">
+      <title>Adding some data into the partition</title>
+      <para>
+        The
+        <emphasis
+          role="bold">AbstractServerTest</emphasis>
+        class provide a method called
+        <emphasis
+          role="bold">importLdif( InputStream in )</emphasis>
+        . It allows you to inject
+        some entries into the newly created partition. How d we use it?
+      </para>
+      <para>
+        First, we need to have a valid LDIF file containing your entries. We will create two branches in our
+        <emphasis
+          role="bold">sevenseas</emphasis>
+        organization :
+      </para>
+      <itemizedlist>
+        <listitem>
+          <para>one for groups</para>
+        </listitem>
+        <listitem>
+          <para>one for people</para>
+        </listitem>
+      </itemizedlist>
+      <para>Here is the ldif file we will create :</para>
+      <programlisting><![CDATA[
+dn: ou=groups,o=sevenSeas
+objectClass: organizationalUnit
+objectClass: top
+ou: groups
+description: Contains entries which describe groups (crews, for instance)
+
+dn: ou=people,o=sevenSeas
+objectClass: organizationalUnit
+objectClass: top
+ou: people
+description: Contains entries which describe persons (seamen)
+          ]]></programlisting>
+      <para>Save it as a text file into a directory where we will be able to read it directly. But where?</para>
+      <para>
+        We have created the test into a directory src/test/java/org/apache/directory/demo. This is the
+        <emphasis
+          role="bold">maven</emphasis>
+        way to
+        organized the sources, as seen before. Let's create another directory for the resources :
+        src/test/resources/org/apache/directory/demo. Tis is the place where we will save the ldif file.
+      </para>
+      <para>
+        Now, to let the server know about the ldif file, just add this line after the call to the
+        <emphasis
+          role="bold">setup()</emphasis>
+        method :
+      </para>
+      <programlisting><![CDATA[
+...
+        // Now, let's call the upper class which is responsible for the
+        // partitions creation
+        super.setUp();
+
+        // Load a demo ldif file
+        importLdif( this.getClass().getResourceAsStream( "demo.ldif" ) );
+    }
+          ]]></programlisting>
+      <important>
+        <para>This is important to add the import after the setup : you can't import data while the partition has not
+          been created ...</para>
+      </important>
+      <para>
+        The
+        <emphasis
+          role="bold">getResourceAsStream</emphasis>
+        call will automatically read the file from the resources directory, based on the current class package.
+      </para>
+      <para>How can we be sure that the data has been imported ? Let's do a search request !</para>
+    </section>
+    <section
+      id="Cleanup the code">
+      <title>Cleanup the code</title>
+      <para>Before that, let's do some cleanup. The context creation is something we will have to do in each test. We
+        should create a common method called every time to avoid duplicating this code. Let's create this method :
+      </para>
+      <programlisting><![CDATA[
+/**
+     * Create a context pointing to a partition
+     */
+    private DirContext createContext( String partition ) throws NamingException
+    {
+        // Create a environment container
+        Hashtable<Object, Object> env =
+            new Hashtable<Object, Object>( configuration.toJndiEnvironment() );
+
+        // Create a new context pointing to the partition
+        env.put( Context.PROVIDER_URL, partition );
+        env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
+        env.put( Context.SECURITY_CREDENTIALS, "secret" );
+        env.put( Context.SECURITY_AUTHENTICATION, "simple" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY,
+                    "org.apache.directory.server.jndi.ServerContextFactory" );
+
+        // Let's open a connection on this partition
+        InitialContext initialContext = new InitialContext( env );
+
+        // We should be able to read it
+        DirContext appRoot = ( DirContext ) initialContext.lookup( "" );
+        assertNotNull( appRoot );
+
+        return appRoot;
+    }
+    ]]></programlisting>
+      <para>This method is added into the body of the test class. This method is very simple and quite straightforward :
+        we just create an initial context pointing to the requested partition, and return a directory context on this
+        partition. It takes a parameter, the partition name.</para>
+      <para>Let's modify the test partition method :</para>
+      <programlisting><![CDATA[
+/**
+     * Test that the partition has been correctly created
+     */
+    public void testPartition() throws NamingException
+    {
+        DirContext appRoot = createContext( "o=sevenSeas" );
+
+        // Let's get the entry associated to the top level
+        Attributes attributes = appRoot.getAttributes( "" );
+        ...
+    ]]></programlisting>
+      <para>We just replaced the first lines by a call to the newly created createContext() method.</para>
+      <para>If you launch the unit test, it should still be ok.</para>
+    </section>
+    <section
+      id="Searching for entries">
+      <title>Searching for entries</title>
+      <para>This is really simple. What we will do is to search for the imported entries. Let's go directly to the code.
+        We will add a new unit test</para>
+      <programlisting><![CDATA[
+/**
+     * Test that the ldif data has correctly been imported
+     */
+    public void testImport() throws NamingException
+    {
+        // Searching for all
+        Set<String> result = searchDNs( "(ObjectClass=*)", "o=sevenSeas", "",
+                                          SearchControls.ONELEVEL_SCOPE );
+
+        assertTrue( result.contains( "ou=groups,o=sevenSeas" ) );
+        assertTrue( result.contains( "ou=people,o=sevenSeas" ) );
+    }
+    ]]></programlisting>
+      <para>Here, we are looking for all the entries starting at the top level of the partition, within the level. We
+        should only get two entries.</para>
+      <para>It's not enough : the searchDNs() method does not exist. It is a private method we have created to avoid
+        duplicating some code all over the unit tests. Here is its code :</para>
+      <programlisting><![CDATA[
+/**
+     * Performs a single level search from a root base and
+     * returns the set of DNs found.
+     */
+    private Set<String> searchDNs( String filter, String partition, String base, int scope )
+       throws NamingException
+    {
+        DirContext appRoot = createContext( partition );
+
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope( scope );
+        NamingEnumeration result = appRoot.search( base, filter, controls );
+
+        // collect all results
+        HashSet<String> entries = new HashSet<String>();
+
+        while ( result.hasMore() )
+        {
+            SearchResult entry = ( SearchResult ) result.next();
+            entries.add( entry.getName() );
+        }
+
+        return entries;
+    }
+    ]]></programlisting>
+      <para>As for the test partiton, we call the createContext() method, then we just do some JNDI magic :</para>
+      <itemizedlist>
+        <listitem>
+          <para>creating a SearchControl,</para>
+        </listitem>
+        <listitem>
+          <para>setting the scope,</para>
+        </listitem>
+        <listitem>
+          <para>calling the search</para>
+        </listitem>
+        <listitem>
+          <para>and gathering the returned DN if any</para>
+        </listitem>
+      </itemizedlist>
+      <para>If the test is successful, you get the imported DNs !</para>
+    </section>
+    <section
+      id="Adding your own schema">
+      <title>Adding your own schema</title>
+      <warning>
+        <title>Work in progress</title>
+        <para>This paragraph is totally outdated. It should be rewriten from scratch !</para>
+      </warning>
+      <para>
+        Ok, let's go deeper into the server configuration. Working with default schema is fine, but some point, you may
+        want to use your own ObjectClasses and AttributeTypes. let's assume you have created them, and that you have
+        been throw the process of generating the class files for it (this process is described in
+        <link
+          xlink:href="http://directory.apache.org/apacheds/DIRxSRVx10/custom-schema.html">Custom Schema</link>
+        ) into a new package (org.apache.directory.demo.schema) where all the generated files will be put.
+      </para>
+      <para>You will just have to add those lines at the end of the setUp() method (just before the call to the super()
+        method) :</para>
+      <programlisting><![CDATA[
+...
+import org.apache.directory.server.core.configuration.MutablePartitionConfiguration;
+import org.apache.directory.server.core.schema.bootstrap.AbstractBootstrapSchema;
+import org.apache.directory.server.unit.AbstractServerTest;
+
+import org.apache.directory.demo.schema.DemoSchema;
+
+...
+        ...
+        ///
+        /// add the Demo schema
+        ///
+        Set<AbstractBootstrapSchema> schemas = configuration.getBootstrapSchemas();
+        schemas.add( new DemoSchema() );
+
+        configuration.setBootstrapSchemas(schemas);
+
+
+        // Now, let's call the upper class which is responsible for the
+        // partitions creation
+        super.setUp();
+    }
+      ]]></programlisting>
+      <para>If we launch the test, nothing special will happen, except that the test will succeed. That's not very
+        impressive...</para>
+    </section>
+    <section
+      id="Conclusion">
+      <title>Conclusion</title>
+      <para>
+        Ok, this tutorial was a short one, but you get everything you need to play with Apache Directory Server as a
+        Unit Test Engine for your Ldap application. Just create your own partition, define your schema, import your ldif
+        file, and add all the tests you need. it's as simple as explained
+        <inlinemediaobject>
+          <imageobject>
+            <imagedata
+              fileref="images/smile.gif" />
+          </imageobject>
+        </inlinemediaobject>
+      </para>
+      <para>If you have any problem, just feel free to post a mail to users@directory.apache.org, we will be there to
+        help !</para>
+    </section>
+    <section
+      id="Resources Unit Tests">
+      <title>Resources</title>
+      <link
+        xlink:href="http://directory.apache.org/community%26resources/embedding-apacheds.html">Embedding ApacheDS - Conference Materials</link>
+    </section>
   </section>
   <section
     id="Embedding ApacheDS as a Web Application">
     <title>Embedding ApacheDS as a Web Application</title>
+    <tip>
+      <title>ApacheDS 1.5.5</title>
+      <para>This site was updated for ApacheDS 1.5.5.</para>
+    </tip>
+    <para>My initial aim was to demonstrate embedding ApacheDS in a very simple, but nevertheless impressive way. I
+      thought about embedding the server in Apache Tomcat first. But then I got a better plan: Creating a standard web
+      application which wraps ApacheDS and can be deployed on any compliant application server. ApacheDS in a
+      war-archive!</para>
+    <itemizedlist>
+      <listitem>
+        <para>
+          <xref
+            linkend="Solution Outline" />
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          <xref
+            linkend="Step 1: The web component which starts and stops the server" />
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          <xref
+            linkend="Packaging and Deploying the WebApp" />
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          <xref
+            linkend="Step 2: Adding functionality: A servlet which displays the Root DSE" />
+        </para>
+      </listitem>
+    </itemizedlist>
+    <note>
+      <title>Version check</title>
+      <para>Although the concepts depicted below apply to all version of ApacheDS (even before 1.0), the configuration
+        for starting and stopping the embedded server uses the style introduced with ApacheDS 1.5.5. Be sure that you
+        use this version of the server, or a later one.</para>
+    </note>
+    <section
+      id="Solution Outline">
+      <title>Solution Outline</title>
+      <important>
+        <title>Proof of concept character</title>
+        <para>Although it works well, please note that this is just an example on how to embed ApacheDS in an
+          application! If you plan to run the server as LDAP production system, this is not the first option to
+          consider. Some more steps have to be done, especially in the area of configuration.</para>
+      </important>
+      <para>The solution is quite simple. A web application carries all the necessary jar files for ApacheDS within the
+        lib-directory of the WEB-INF folder. When the web application is started by the servlet container, appropriate
+        code has to be executed to start ApacheDS. And the server has to be stopped, if the web application goes down
+        (for
+        instance if the server shuts down). There are (at least) two standard compliant ways to acomplish this:
+      </para>
+      <itemizedlist>
+        <listitem>
+          <para>A Servlet (automatically started with the web application, using the lifecycle methods init and destroy)
+          </para>
+        </listitem>
+        <listitem>
+          <para>A ServletContextListener</para>
+        </listitem>
+      </itemizedlist>
+      <para>In the following we have choosen the second option.</para>
+      <section
+        id="A Servlet Context Listener to start and stop ApacheDS">
+        <title>A Servlet Context Listener to start and stop ApacheDS</title>
+        <para>
+          A servlet context listener receives notifications about changes to the servlet context of the web
+          application
+          it is part of. Documentation of the ServletContextListener interface can be found
+          <link
+            xlink:href="http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletContextListener.html">here</link>
+          . To receive
+          notification events, the implementation class must be configured in the deployment descriptor for
+          the web
+          application. The two life cycle methods
+          <emphasis>contextInitialized</emphasis>
+          and
+          <emphasis>contextDestroyed</emphasis>
+          are suitable to start
+          and stop
+          ApacheDS.
+        </para>
+      </section>
+      <section
+        id="A client within">
+        <title>A client within</title>
+        <para>After the server has been started from the Listener, it will be accessible from the outside via the
+          network using LDAP. In order to demonstrate how to interact with the server from within the VM, a simple
+          servlet is shown. It allows you to communicate with the embedded server via web browser. This is so simple,
+          because the server already lives within a web application, only a servlet has to added to act as an entry
+          point. Our sample servlet will display the Root DSE of the server.</para>
+        <para>The following class diagram visualizes the complete example. The gray elements will be developed in two
+          steps and use Servlet and ApacheDS API.</para>
+        <figure
+          id="ApacheDS as a Web Application figure">
+          <title>ApacheDS as a Web Application</title>
+          <mediaobject>
+            <imageobject>
+              <imagedata
+                fileref="images/ApacheDS_WebApp_UML.png" />
+            </imageobject>
+          </mediaobject>
+        </figure>
+      </section>
+    </section>
+    <section
+      id="Step 1: The web component which starts and stops the server">
+      <title>Step 1: The web component which starts and stops the server</title>
+      <para>The ApacheDS core is comprised of JavaBeans components, and can easily be instantiated started and stopped
+        with simple Java code. This is done by the following listener.</para>
+      <para>
+        The class
+        <link
+          xlink:href="http://svn.apache.org/repos/asf/directory/samples/trunk/apacheds-archetype-webapp/src/main/resources/archetype-resources/src/main/java/StartStopListener.java">StartStopListener</link>
+        implements
+        <emphasis>ServletContextListener</emphasis>
+        and therefore contains the following two life cycle methods:
+      </para>
+      <itemizedlist>
+        <listitem>
+          <para>
+            <emphasis>contextInitialized()</emphasis>
+            is executed if the web application is started by the servlet container, it starts ApacheDS embedded
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            <emphasis>contextDestroyed()</emphasis>
+            is executed if the web application is stopped by the servlet container, it stops the embedded server
+          </para>
+        </listitem>
+      </itemizedlist>
+      <para>
+        The
+        <emphasis>contextInitialized</emphasis>
+        method creates a
+        <emphasis>DefaultDirectoryService</emphasis>
+        object. It configures the LDAP protocol and
+        determines an appropriate working directory for the server. This
+        directory is need to persist the partition data
+        (entries). Our example uses a simple yet portable way for this
+        task: the context attribute
+        <emphasis>javax.servlet.context.tempdir</emphasis>
+        .
+      </para>
+      <para>Afterwards the method starts network protocol and directory service.</para>
+      <para>Finally the DirectoryService component is stored in the application context of the web application. This is
+        done in order to provided it to embedded clients in the same web app (see the servlet below for an example).
+      </para>
+      <para>The method contextDestroyed simply stops the protocol and shuts down the service.</para>
+      <programlisting>
+        <emphasis
+          role="bold">StartStopListener.java</emphasis>
+        <![CDATA[
+package org.apache.directory.samples.embed.webapp;
+
+import java.io.File;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.directory.server.core.DefaultDirectoryService;
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.ldap.LdapServer;
+import org.apache.directory.server.protocol.shared.transport.TcpTransport;
+
+/**
+ * A Servlet context listener to start and stop ApacheDS.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class StartStopListener implements ServletContextListener
+{
+    private DirectoryService directoryService;
+
+    private LdapServer ldapServer;
+
+    /**
+     * Startup ApacheDS embedded.
+     */
+    public void contextInitialized( ServletContextEvent evt )
+    {
+        try
+        {
+            directoryService = new DefaultDirectoryService();
+            directoryService.setShutdownHookEnabled( true );
+
+            ldapServer = new LdapServer();
+            ldapServer.setDirectoryService( directoryService );
+            ldapServer.setAllowAnonymousAccess( true );
+
+            // Set LDAP port to 10389
+            TcpTransport ldapTransport = new TcpTransport( 10389 );
+            ldapServer.setTransports( ldapTransport );
+
+            // Determine an appropriate working directory
+            ServletContext servletContext = evt.getServletContext();
+            File workingDir = ( File ) servletContext.getAttribute( "javax.servlet.context.tempdir" );
+            directoryService.setWorkingDirectory( workingDir );
+
+            directoryService.startup();
+            ldapServer.start();
+
+            // Store directoryService in context to provide it to servlets etc.
+            servletContext.setAttribute( DirectoryService.JNDI_KEY, directoryService );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+    /**
+     * Shutdown ApacheDS embedded.
+     */
+    public void contextDestroyed( ServletContextEvent evt )
+    {
+        try
+        {
+            ldapServer.stop();
+            directoryService.shutdown();
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+}
+        ]]></programlisting>
+      <section
+        id="Deployment descriptor">
+        <title>Deployment descriptor</title>
+        <para>In order to execute the listener code, the class has to be defined in the deployment descriptor of a web
+          application, as depicted below:</para>
+        <programlisting>
+          <emphasis
+            role="bold">web.xml</emphasis>
+        <![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+"http://java.sun.com/dtd/web-app_2_3.dtd">
+<web-app>
+  <display-name>ApacheDS embedded in a WebApp</display-name>
+  <description>
+    A simple yet portable way to run ApacheDS within a servlet
+    container
+  </description>
+
+  <listener>
+    <listener-class>
+      org.apache.directory.samples.embed.webapp.StartStopListener
+    </listener-class>
+  </listener>
+</web-app>
+          ]]></programlisting>
+      </section>
+    </section>
+    <section
+      id="Packaging and Deploying the WebApp">
+      <title>Packaging and Deploying the WebApp</title>
+      <para>A standard web archive (war-File) is needed in order to deploy the application to a servlet container. The
+        easiest way to create such a web archive including all dependencies is to use an Maven archetype we provide.
+      </para>
+      <section
+        id="Creating the WebApp using the ApacheDS Maven Archetype">
+        <title>Creating the WebApp using the ApacheDS Maven Archetype</title>
+        <para>We assume you have Java Subversion and Maven 2.0.9 installed on your system.</para>
+        <para>To use the archetype you'll need to check it out and install it to your local repository:</para>
+        <screen><![CDATA[
+svn co http://svn.apache.org/repos/asf/directory/samples/trunk/apacheds-archetype-webapp
+cd apacheds-archetype-webapp
+mvn install
+      ]]></screen>
+        <para>Then change to your preferred location to create the new project and execute following command: </para>
+        <screen><![CDATA[
+mvn archetype:generate -DarchetypeGroupId=org.apache.directory.samples \
+                       -DarchetypeArtifactId=apacheds-archetype-webapp \
+                       -DarchetypeVersion=1.5.5-SNAPSHOT \
+                       -DgroupId=org.apache.directory.samples.embed.webapp \
+                       -DartifactId=ApacheDS -Dversion=1.0-SNAPSHOT 
+      ]]></screen>
+        <para>Then change to the created directory and run the following command:</para>
+        <screen><![CDATA[
+mvn package 
+      ]]></screen>
+        <para>
+          This creates an
+          <emphasis>ApacheDS.war</emphasis>
+          file below the target folder.
+        </para>
+      </section>
+      <section
+        id="Run on embedded Jetty">
+        <title>Run on embedded Jetty</title>
+        <para>The fastest way to run the web application is to use the Maven Jetty plugin:</para>
+        <screen><![CDATA[
+mvn jetty:run
+      ]]></screen>
+      </section>
+      <section
+        id="Deploying on Apache Tomcat">
+        <title>Deploying on Apache Tomcat</title>
+        <para>
+          In order to run the application within Tomcat, simply put the
+          <emphasis>ApacheDS.war</emphasis>
+          file in the
+          <emphasis>webapps</emphasis>
+          directory
+          of your Tomcat installation and start the server. If you have the manager application enabled (as
+          described
+          <link
+            xlink:href="http://tomcat.apache.org/tomcat-6.0-doc/manager-howto.html">here</link>
+          ), you can see and "manage" (start/stop) ApacheDS within its list view:
+        </para>
+        <figure
+          id="Tomcat Manager App in Browser figure">
+          <title>Tomcat Manager App in Browser</title>
+          <mediaobject>
+            <imageobject>
+              <imagedata
+                fileref="images/TomcatManagerAppInBrowser.png" />
+            </imageobject>
+          </mediaobject>
+        </figure>
+      </section>
+      <section
+        id="Connecting to ApacheDS from the outside">
+        <title>Connecting to ApacheDS from the outside</title>
+        <para>ApacheDS is up and running within the servlet container. Besides the administration tool listing, it seems
+          to be invisible. But because we have configured network access via port 10389, you can easily access the
+          server with an arbitrary LDAP client from outside.</para>
+        <para>
+          One option is a command line tool like
+          <emphasis>ldapsearch</emphasis>
+          (see
+          <link
+            xlink:href="http://directory.apache.org/apacheds/1.5/apacheds-v15-basic-users-guide.html">ApacheDS Basic User's Guide</link>
+          for details on how to
+          connect to ApacheDS with such tools in general). Here is an example how to connect as
+          administrator (simple
+          bind) and fetch the Root DSE of our embedded ApacheDS instance:
+        </para>
+        <screen><![CDATA[
+$ ldapsearch -h localhost -p 10389 -D "uid=admin,ou=system" -w secret \\
+    -b "" -s base "(objectClass=*)" * +
+version: 1
+dn:
+supportedControl: 2.16.840.1.113730.3.4.3
+supportedControl: 2.16.840.1.113730.3.4.7
+supportedControl: 1.3.6.1.4.1.4203.1.10.1
+supportedControl: 2.16.840.1.113730.3.4.2
+supportedControl: 1.3.6.1.4.1.18060.0.0.1
+namingContexts: ou=system
+namingContexts: ou=schema
+supportedLDAPVersion: 3
+objectClass: extensibleObject
+objectClass: top
+supportedFeatures: 1.3.6.1.4.1.4203.1.5.1
+supportedExtension: 1.3.6.1.4.1.1466.20036
+subschemaSubentry: cn=schema
+vendorName: Apache Software Foundation
+vendorVersion: 1.5.4
+$
+        ]]></screen>
+        <para>
+          Another choice are graphical LDAP clients (see
+          <link
+            xlink:href="http://directory.apache.org/apacheds/1.5/apacheds-v15-basic-users-guide.html">ApacheDS Basic User's Guide</link>
+          for details on how to connect to ApacheDS with such tools in general).
+        </para>
+        <para>
+          With our popular Eclipse RCP application
+          <link
+            xlink:href="http://directory.apache.org/studio/">Directory studio</link>
+          for instance, connecting goes like this:
+          In the Connections view, select "New connection ...". Within a wizard
+          dialog, you provide the connection data (host
+          name, port, bind DN and password).
+        </para>
+        <figure
+          id="New LDAP Connection Directory Studio 1 figure">
+          <title>New LDAP Connection Directory Studio 1</title>
+          <mediaobject>
+            <imageobject>
+              <imagedata
+                fileref="images/DirectoryStudio1.png" />
+            </imageobject>
+          </mediaobject>
+        </figure>
+        <figure
+          id="New LDAP Connection Directory Studio 2 figure">
+          <title>New LDAP Connection Directory Studio 2</title>
+          <mediaobject>
+            <imageobject>
+              <imagedata
+                fileref="images/DirectoryStudio2.png" />
+            </imageobject>
+          </mediaobject>
+        </figure>
+        <para>After successfully connecting to the embedded ApacheDS, you can browse the tree, add and manipulate
+          entries and so on. If you check the connection properties, you can study the Root DSE as well.</para>
+        <figure
+          id="Properties New LDAP Connection Directory Studio figure">
+          <title>Properties New LDAP Connection Directory Studio</title>
+          <mediaobject>
+            <imageobject>
+              <imagedata
+                fileref="images/DirectoryStudio3.png" />
+            </imageobject>
+          </mediaobject>
+        </figure>
+      </section>
+      <section
+        id="Other Web Application Servers">
+        <title>Other Web Application Servers</title>
+        <para>The web application described here has been successfully deployed on</para>
+        <itemizedlist>
+          <listitem>
+            <para>
+              Apache Tomcat 5.5.20 and 6.0.18 (
+              <link
+                xlink:href="http://tomcat.apache.org/">Homepage</link>
+              )
+            </para>
+          </listitem>
+          <listitem>
+            <para>
+              IBM WebSphere Application Server 6.1 (
+              <link
+                xlink:href="http://www.ibm.com/software/webservers/appserv/was/">Homepage</link>
+              )
+            </para>
+          </listitem>
+          <listitem>
+            <para>
+              Jetty 6.1.0 (
+              <link
+                xlink:href="http://jetty.mortbay.org/">Homepage</link>
+              )
+            </para>
+          </listitem>
+        </itemizedlist>
+        <para>Here is a screen shot of the web based administration console of WebSphere Application Server 6.1 with the
+          ApacheDS.war deployed and running, no changes in the deployment archive were needed.</para>
+        <figure
+          id="WebSphere Admin Console figure">
+          <title>WebSphere Admin Console</title>
+          <mediaobject>
+            <imageobject>
+              <imagedata
+                fileref="images/WebSphereAdminConsoleInBrowser.png" />
+            </imageobject>
+          </mediaobject>
+        </figure>
+      </section>
+    </section>
+    <section
+      id="Step 2: Adding functionality: A servlet which displays the Root DSE">
+      <title>Step 2: Adding functionality: A servlet which displays the Root DSE</title>
+      <para>To finish with, here is a simple example on how to access the server internally (Note: the servlet was
+        already created by the maven archetype).</para>
+      <para>The following servlet, which will be deployed together with the other class in the web archive, connects to
+        ApacheDS directly, i.e. via the internal JNDI provider. No network access is needed. In the doGet method it
+        performs a search operation against the Root DSE of the server, as the examples above do.</para>
+      <programlisting>
+        <emphasis
+          role="bold">RootDseServlet.java</emphasis><![CDATA[
+package org.apache.directory.samples.embed.webapp;
+
+import java.io.PrintWriter;
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.jndi.CoreContextFactory;
+
+/**
+ * A servlet which displays the Root DSE of the embedded server.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory
+ *         Project</a>
+ */
+public class RootDseServlet extends HttpServlet {
+
+    private static final long serialVersionUID = 1L;
+
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+            throws ServletException {
+
+        try {
+            resp.setContentType("text/plain");
+            PrintWriter out = resp.getWriter();
+
+            out.println("*** ApacheDS RootDSE ***\n");
+
+            DirContext ctx = new InitialDirContext(this.createEnv());
+
+            SearchControls ctls = new SearchControls();
+            ctls.setReturningAttributes(new String[] { "*", "+" });
+            ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
+
+            NamingEnumeration<SearchResult> result = ctx.search("",
+                    "(objectClass=*)", ctls);
+            if (result.hasMore()) {
+                SearchResult entry = result.next();
+                Attributes as = entry.getAttributes();
+
+                NamingEnumeration<String> ids = as.getIDs();
+                while (ids.hasMore()) {
+                    String id = ids.next();
+                    Attribute attr = as.get(id);
+                    for (int i = 0; i < attr.size(); ++i) {
+                        out.println(id + ": " + attr.get(i));
+                    }
+                }
+            }
+            ctx.close();
+
+            out.flush();
+        } catch (Exception e) {
+            throw new ServletException(e);
+        }
+    }
+
+    /**
+     * Creates an environment configuration for JNDI access.
+     */
+    protected Hashtable<Object, Object> createEnv() {
+
+        // Fetch directory servive from servlet context
+        ServletContext servletContext = this.getServletContext();
+        DirectoryService directoryService = (DirectoryService) servletContext
+                .getAttribute(DirectoryService.JNDI_KEY);
+
+        Hashtable<Object, Object> env = new Hashtable<Object, Object>();
+        env.put(DirectoryService.JNDI_KEY, directoryService);
+        env.put(Context.PROVIDER_URL, "");
+        env.put(Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class
+                .getName());
+
+        env.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
+        env.put(Context.SECURITY_CREDENTIALS, "secret");
+        env.put(Context.SECURITY_AUTHENTICATION, "simple");
+
+        return env;
+    }
+}
+      ]]></programlisting>
+      <para>
+        In order to make the servlet available to clients, it has to be declared in the deployment descriptor
+        <emphasis>web.xml</emphasis>
+        , here are the additions (a servlet named
+        <emphasis>RootDseServlet</emphasis>
+        for the class above, and a URL mapping)
+      </para>
+      <programlisting>
+        <emphasis
+          role="bold">web.xml, extended</emphasis><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+"http://java.sun.com/dtd/web-app_2_3.dtd">
+<web-app>
+
+  ...
+  <servlet>
+    <servlet-name>RootDseServlet</servlet-name>
+    <servlet-class>
+      org.apache.directory.samples.embed.webapp.RootDseServlet
+    </servlet-class>
+  </servlet>
+
+   <servlet-mapping>
+     <servlet-name>RootDseServlet</servlet-name>
+     <url-pattern>/RootDse</url-pattern>
+   </servlet-mapping>
+</web-app>
+      ]]></programlisting>
+      <para>
+        Redeploy the web application. If you point to your tomcat server with the appropriate URL (
+        <link
+          xlink:href="http://localhost:8080/ApacheDS/RootDse">http://localhost:8080/ApacheDS/RootDse</link>
+        ), you'll see the content of the Root DSE as depicted below:
+      </para>
+      <figure
+        id="RootDSE Servlet in a Browser figure">
+        <title>RootDSE Servlet in a Browser</title>
+        <mediaobject>
+          <imageobject>
+            <imagedata
+              fileref="images/RootDseServletInBrowser.png" />
+          </imageobject>
+        </mediaobject>
+      </figure>
+    </section>
   </section>
 </chapter>