You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2008/12/11 16:32:12 UTC

svn commit: r725712 [6/9] - in /directory: apacheds/trunk/ apacheds/trunk/all/ apacheds/trunk/bootstrap-plugin/src/main/java/org/apache/directory/server/core/bootstrap/plugin/ apacheds/trunk/core-avl/src/main/java/org/apache/directory/server/core/avltr...

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/ReferralAwareRequestHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/ReferralAwareRequestHandler.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/ReferralAwareRequestHandler.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/ReferralAwareRequestHandler.java Thu Dec 11 07:32:04 2008
@@ -24,13 +24,11 @@
 import javax.naming.NameNotFoundException;
 import javax.naming.NamingException;
 
-import org.apache.directory.server.core.ReferralManager;
 import org.apache.directory.server.core.entry.ClonedServerEntry;
 import org.apache.directory.server.core.entry.ServerAttribute;
 import org.apache.directory.server.ldap.LdapSession;
 import org.apache.directory.shared.ldap.codec.util.LdapURLEncodingException;
 import org.apache.directory.shared.ldap.constants.SchemaConstants;
-import org.apache.directory.shared.ldap.entry.EntryAttribute;
 import org.apache.directory.shared.ldap.entry.Value;
 import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.message.LdapResult;
@@ -78,11 +76,18 @@
         // to the handling without pre-processing the request
         if ( req.getControls().containsKey( ManageDsaITControl.CONTROL_OID ) )
         {
+            // If the ManageDsaIT control is present, we will
+            // consider that the user wants to get entry which
+            // are referrals as plain entry. We have to return
+            // SearchResponseEntry elements instead of 
+            // SearchResponseReference elements.
             LOG.debug( "ManageDsaITControl detected." );
             handleIgnoringReferrals( session, req );
         }
         else
         {
+            // No ManageDsaIT control. If the found entries is a referral,
+            // we will return SearchResponseReference elements.
             LOG.debug( "ManageDsaITControl NOT detected." );
     
             switch ( req.getType() )
@@ -176,243 +181,6 @@
     
     
     /**
-     * Handles processing with referrals without ManageDsaIT control.
-     */
-    private void handleWithReferrals( LdapSession session, LdapDN reqTargetDn, T req ) throws NamingException
-    {
-        LdapResult result = req.getResultResponse().getLdapResult();
-        ClonedServerEntry entry = null;
-        boolean isReferral = false;
-        boolean isparentReferral = false;
-        ReferralManager referralManager= session.getCoreSession().getDirectoryService().getReferralManager();
-        
-        reqTargetDn.normalize( session.getCoreSession().getDirectoryService().getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
-        
-        // Check if the entry itself is a referral
-        referralManager.lockRead();
-        
-        isReferral = referralManager.isReferral( reqTargetDn );
-        
-        if ( !isReferral )
-        {
-            // Check if the entry has a parent which is a referral
-            isparentReferral = referralManager.hasParentReferral( reqTargetDn );
-        }
-        
-        referralManager.unlock();
-        
-        if ( !isReferral && !isparentReferral )
-        {
-            // This is not a referral and it does not have a parent which 
-            // is a referral : standard case, just deal with the request
-            LOG.debug( "Entry {} is NOT a referral.", reqTargetDn );
-            handleIgnoringReferrals( session, req );
-            return;
-        }
-        else
-        {
-            // -------------------------------------------------------------------
-            // Lookup Entry
-            // -------------------------------------------------------------------
-            
-            // try to lookup the entry but ignore exceptions when it does not   
-            // exist since entry may not exist but may have an ancestor that is a 
-            // referral - would rather attempt a lookup that fails then do check 
-            // for existence than have to do another lookup to get entry info
-    
-            try
-            {
-                entry = session.getCoreSession().lookup( reqTargetDn );
-                LOG.debug( "Entry for {} was found: ", reqTargetDn, entry );
-            }
-            catch ( NameNotFoundException e )
-            {
-                /* ignore */
-                LOG.debug( "Entry for {} not found.", reqTargetDn );
-            }
-            catch ( Exception e )
-            {
-                /* serious and needs handling */
-                handleException( session, req, e );
-                return;
-            }
-            
-            // -------------------------------------------------------------------
-            // Handle Existing Entry
-            // -------------------------------------------------------------------
-            
-            if ( entry != null )
-            {
-                try
-                {
-                    if ( isEntryReferral( entry ) )
-                    {
-                        LOG.debug( "Entry is a referral: {}", entry );
-                        
-                        if ( req instanceof SearchRequest )
-                        {
-                            handleReferralEntryForSearch( session, ( SearchRequest ) req, entry );
-                        }
-                        else
-                        {
-                            handleReferralEntry( session, reqTargetDn, req, entry );
-                        }
-                        return;
-                    }
-                    else
-                    {
-                        LOG.debug( "Entry is NOT a referral: {}", entry );
-                        handleIgnoringReferrals( session, req );
-                        return;
-                    }
-                }
-                catch ( Exception e )
-                {
-                    handleException( session, req, e );
-                }
-            }
-    
-            // -------------------------------------------------------------------
-            // Handle Non-existing Entry
-            // -------------------------------------------------------------------
-            
-            // if the entry is null we still have to check for a referral ancestor
-            // also the referrals need to be adjusted based on the ancestor's ref
-            // values to yield the correct path to the entry in the target DSAs
-            
-            if ( entry == null )
-            {
-                ClonedServerEntry referralAncestor = null;
-    
-                try
-                {
-                    referralAncestor = getFarthestReferralAncestor( session, reqTargetDn );
-                }
-                catch ( Exception e )
-                {
-                    handleException( session, req, e );
-                    return;
-                }
-    
-                if ( referralAncestor == null )
-                {
-                    result.setErrorMessage( "Entry not found." );
-                    result.setResultCode( ResultCodeEnum.NO_SUCH_OBJECT );
-                    session.getIoSession().write( req.getResultResponse() );
-                    return;
-                }
-                  
-                // if we get here then we have a valid referral ancestor
-                try
-                {
-                    Referral referral = null;
-                    
-                    if ( req instanceof SearchRequest )
-                    {
-                        referral = getReferralOnAncestorForSearch( session, ( SearchRequest ) req, referralAncestor );
-                    }
-                    else
-                    {
-                        referral = getReferralOnAncestor( session, reqTargetDn, req, referralAncestor );
-                    }
-                    
-                    result.setResultCode( ResultCodeEnum.REFERRAL );
-                    result.setReferral( referral );
-                    session.getIoSession().write( req.getResultResponse() );
-                }
-                catch ( Exception e )
-                {
-                    handleException( session, req, e );
-                }
-            }
-        }
-    }
-
-    
-    /**
-     * Handles processing a referral response on a target entry which is a 
-     * referral.  It will for any request that returns an LdapResult in it's 
-     * response.
-     *
-     * @param session the session to use for processing
-     * @param reqTargetDn the dn of the target entry of the request
-     * @param req the request
-     * @param entry the entry associated with the request
-     */
-    private void handleReferralEntry( LdapSession session, LdapDN reqTargetDn, T req, ClonedServerEntry entry )
-    {
-        LdapResult result = req.getResultResponse().getLdapResult();
-        ReferralImpl refs = new ReferralImpl();
-        result.setReferral( refs );
-        result.setResultCode( ResultCodeEnum.REFERRAL );
-        result.setErrorMessage( "Encountered referral attempting to handle request." );
-        result.setMatchedDn( reqTargetDn );
-
-        EntryAttribute refAttr = entry.getOriginalEntry().get( SchemaConstants.REF_AT );
-        for ( Value<?> refval : refAttr )
-        {
-            refs.addLdapUrl( ( String ) refval.get() );
-        }
-
-        session.getIoSession().write( req.getResultResponse() );
-    }
-    
-    
-    /**
-     * Handles processing a referral response on a target entry which is a 
-     * referral.  It will for any request that returns an LdapResult in it's 
-     * response.
-     *
-     * @param session the session to use for processing
-     * @param reqTargetDn the dn of the target entry of the request
-     * @param req the request
-     * @param entry the entry associated with the request
-     */
-    private void handleReferralEntryForSearch( LdapSession session, SearchRequest req, ClonedServerEntry entry )
-        throws Exception
-    {
-        LdapResult result = req.getResultResponse().getLdapResult();
-        ReferralImpl referral = new ReferralImpl();
-        result.setReferral( referral );
-        result.setResultCode( ResultCodeEnum.REFERRAL );
-        result.setErrorMessage( "Encountered referral attempting to handle request." );
-        result.setMatchedDn( req.getBase() );
-
-        EntryAttribute refAttr = entry.getOriginalEntry().get( SchemaConstants.REF_AT );
-        for ( Value<?> refval : refAttr )
-        {
-            String refstr = ( String ) refval.get();
-            
-            // need to add non-ldap URLs as-is
-            if ( ! refstr.startsWith( "ldap" ) )
-            {
-                referral.addLdapUrl( refstr );
-                continue;
-            }
-            
-            // parse the ref value and normalize the DN  
-            LdapURL ldapUrl = new LdapURL();
-            try
-            {
-                ldapUrl.parse( refstr.toCharArray() );
-            }
-            catch ( LdapURLEncodingException e )
-            {
-                LOG.error( "Bad URL ({}) for ref in {}.  Reference will be ignored.", refstr, entry );
-                continue;
-            }
-            
-            ldapUrl.setForceScopeRendering( true );
-            ldapUrl.setAttributes( req.getAttributes() );
-            ldapUrl.setScope( req.getScope().getJndiScope() );
-            referral.addLdapUrl( ldapUrl.toString() );
-        }
-
-        session.getIoSession().write( req.getResultResponse() );
-    }
-    
-    
-    /**
      * Handles processing with referrals without ManageDsaIT control and with 
      * an ancestor that is a referral.  The original entry was not found and 
      * the walk of the ancestry returned a referral.
@@ -668,4 +436,10 @@
      * @param req the request to be handled
      */
     public abstract void handleIgnoringReferrals( LdapSession session, T req );
+
+
+    /**
+     * Handles processing with referrals without ManageDsaIT control.
+     */
+    public abstract void handleWithReferrals( LdapSession session, LdapDN reqTargetDn, T req ) throws NamingException;
 }

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/SearchHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/SearchHandler.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/SearchHandler.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/SearchHandler.java Thu Dec 11 07:32:04 2008
@@ -23,6 +23,7 @@
 import java.util.concurrent.TimeUnit;
 
 import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.ReferralManager;
 import org.apache.directory.server.core.entry.ClonedServerEntry;
 import org.apache.directory.server.core.entry.ServerStringValue;
 import org.apache.directory.server.core.event.EventType;
@@ -30,6 +31,7 @@
 import org.apache.directory.server.core.filtering.EntryFilteringCursor;
 import org.apache.directory.server.core.partition.PartitionNexus;
 import org.apache.directory.server.ldap.LdapSession;
+import org.apache.directory.server.ldap.handlers.controls.PagedSearchCookie;
 import org.apache.directory.shared.ldap.codec.util.LdapURLEncodingException;
 import org.apache.directory.shared.ldap.constants.SchemaConstants;
 import org.apache.directory.shared.ldap.entry.EntryAttribute;
@@ -43,6 +45,7 @@
 import org.apache.directory.shared.ldap.message.Response;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.filter.SearchScope;
+import org.apache.directory.shared.ldap.message.Referral;
 import org.apache.directory.shared.ldap.message.SearchRequest;
 import org.apache.directory.shared.ldap.message.SearchResponseDone;
 import org.apache.directory.shared.ldap.message.SearchResponseEntry;
@@ -50,17 +53,21 @@
 import org.apache.directory.shared.ldap.message.SearchResponseReference;
 import org.apache.directory.shared.ldap.message.SearchResponseReferenceImpl;
 import org.apache.directory.shared.ldap.message.control.ManageDsaITControl;
+import org.apache.directory.shared.ldap.message.control.PagedSearchControl;
 import org.apache.directory.shared.ldap.message.control.PersistentSearchControl;
 import org.apache.directory.shared.ldap.name.LdapDN;
 import org.apache.directory.shared.ldap.schema.AttributeType;
 import org.apache.directory.shared.ldap.util.LdapURL;
+import org.apache.directory.shared.ldap.util.StringTools;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static org.apache.directory.server.ldap.LdapService.NO_SIZE_LIMIT;
 import static org.apache.directory.server.ldap.LdapService.NO_TIME_LIMIT;
 
+import javax.naming.NameNotFoundException;
 import javax.naming.NamingException;
+import javax.naming.ldap.PagedResultsControl;
 
 
 /**
@@ -176,18 +183,18 @@
             
             while ( cursor.next() )
             {
-            	if ( hasRootDSE )
-            	{
-            		// This is an error ! We should never find more than one rootDSE !
-            	    LOG.error( "Got back more than one entry for search on RootDSE which means " +
-            	    		"Cursor is not functioning properly!" );
-            	}
-            	else
-            	{
-            		hasRootDSE = true;
-	                ClonedServerEntry entry = cursor.get();
-	                session.getIoSession().write( generateResponse( session, req, entry ) );
-            	}
+                if ( hasRootDSE )
+                {
+                    // This is an error ! We should never find more than one rootDSE !
+                    LOG.error( "Got back more than one entry for search on RootDSE which means " +
+                            "Cursor is not functioning properly!" );
+                }
+                else
+                {
+                    hasRootDSE = true;
+                    ClonedServerEntry entry = cursor.get();
+                    session.getIoSession().write( generateResponse( session, req, entry ) );
+                }
             }
     
             // write the SearchResultDone message
@@ -195,7 +202,7 @@
         }
         finally
         {
-        	// Close the cursor now.
+            // Close the cursor now.
             if ( cursor != null )
             {
                 try
@@ -279,7 +286,7 @@
         // Don't bother setting size limits for administrators that don't ask for it
         if ( session.getCoreSession().isAnAdministrator() && req.getSizeLimit() == NO_SIZE_LIMIT )
         {
-            return NO_SIZE_LIMIT;
+            return Integer.MAX_VALUE;
         }
         
         // Don't bother setting size limits for administrators that don't ask for it
@@ -295,7 +302,7 @@
          */
         if ( ldapService.getMaxSizeLimit() == NO_SIZE_LIMIT && req.getSizeLimit() == NO_SIZE_LIMIT )
         {
-            return NO_SIZE_LIMIT;
+            return Integer.MAX_VALUE;
         }
         
         /*
@@ -303,7 +310,7 @@
          * is configured to limit the search size then we limit by the max size
          * allowed by the configuration 
          */
-        if ( req.getSizeLimit() == 0 )
+        if ( req.getSizeLimit() == NO_SIZE_LIMIT )
         {
             return ldapService.getMaxSizeLimit();
         }
@@ -332,6 +339,95 @@
     }
     
     
+    private SearchResponseDone readResults( LdapSession session, SearchRequest req, 
+        LdapResult ldapResult,  EntryFilteringCursor cursor, int sizeLimit, boolean isPaged, 
+        PagedSearchCookie cookieInstance, PagedResultsControl pagedResultsControl ) throws Exception
+    {
+        req.addAbandonListener( new SearchAbandonListener( ldapService, cursor ) );
+        setTimeLimitsOnCursor( req, session, cursor );
+        LOG.debug( "using {} for size limit", sizeLimit );
+        int cookieValue = 0;
+        
+        int count = 0;
+        
+        while ( (count < sizeLimit ) && cursor.next() )
+        {
+            if ( session.getIoSession().isClosing() )
+            {
+                break;
+            }
+            
+            ClonedServerEntry entry = cursor.get();
+            session.getIoSession().write( generateResponse( session, req, entry ) );
+            count++;
+        }
+        
+        // DO NOT WRITE THE RESPONSE - JUST RETURN IT
+        ldapResult.setResultCode( ResultCodeEnum.SUCCESS );
+
+        if ( count < sizeLimit )
+        {
+            // That means we don't have anymore entry
+            if ( isPaged )
+            {
+                // If we are here, it means we have returned all the entries
+                // We have to remove the cookie from the session
+                cookieValue = cookieInstance.getCookieValue();
+                PagedSearchCookie psCookie = 
+                    (PagedSearchCookie)session.getIoSession().removeAttribute( cookieValue );
+                
+                // Close the cursor if there is one
+                if ( psCookie != null )
+                {
+                    cursor = psCookie.getCursor();
+                    
+                    if ( cursor != null )
+                    {
+                        cursor.close();
+                    }
+                }
+                
+                pagedResultsControl = new PagedResultsControl( 0, true );
+                req.getResultResponse().add( pagedResultsControl );
+            }
+
+            return ( SearchResponseDone ) req.getResultResponse();
+        }
+        else
+        {
+            // We have reached the limit
+            if ( isPaged )
+            {
+                // We stop here. We have to add a ResponseControl
+                // DO NOT WRITE THE RESPONSE - JUST RETURN IT
+                ldapResult.setResultCode( ResultCodeEnum.SUCCESS );
+                req.getResultResponse().add( pagedResultsControl );
+                
+                // Stores the cursor into the session
+                cookieInstance.setCursor( cursor );
+                return ( SearchResponseDone ) req.getResultResponse();
+            }
+            else
+            {
+                int serverLimit = session.getCoreSession().getDirectoryService().getMaxSizeLimit();
+                
+                if ( serverLimit == 0 )
+                {
+                    serverLimit = Integer.MAX_VALUE;
+                }
+                
+                // DO NOT WRITE THE RESPONSE - JUST RETURN IT
+                if ( count > serverLimit ) 
+                {
+                    // Special case if the user has requested more elements than the limit
+                    ldapResult.setResultCode( ResultCodeEnum.SIZE_LIMIT_EXCEEDED );
+                }
+                
+                return ( SearchResponseDone ) req.getResultResponse();
+            }
+        }
+    }
+    
     /**
      * Conducts a simple search across the result set returning each entry 
      * back except for the search response done.  This is calculated but not
@@ -346,67 +442,152 @@
     private SearchResponseDone doSimpleSearch( LdapSession session, SearchRequest req ) 
         throws Exception
     {
-        /*
-         * Iterate through all search results building and sending back responses
-         * for each search result returned.
-         */
+        LdapResult ldapResult = req.getResultResponse().getLdapResult();
+        PagedResultsControl pagedResultsControl = null;
         EntryFilteringCursor cursor = null;
-        
-        try
-        {
-            LdapResult ldapResult = req.getResultResponse().getLdapResult();
-            cursor = session.getCoreSession().search( req );
-            req.addAbandonListener( new SearchAbandonListener( ldapService, cursor ) );
-            setTimeLimitsOnCursor( req, session, cursor );
-            final int sizeLimit = getSearchSizeLimits( req, session );
-            LOG.debug( "using {} for size limit", sizeLimit );
+        int sizeLimit = getSearchSizeLimits( req, session );
+        boolean isPaged = false;
+        PagedSearchCookie cookieInstance = null;
+
+        // Check that the PagedSearchControl is present or not.
+        // Check if we are using the Paged Search Control
+        Object control = req.getControls().get( PagedSearchControl.CONTROL_OID );
+        PagedSearchControl pagedSearchControl = null;
+        
+        if ( control != null )
+        {
+            pagedSearchControl = ( PagedSearchControl )control;
+        }
+        
+        if ( pagedSearchControl != null )
+        {
+            // We have the following cases :
+            // 1) The SIZE is above the size-limit : the request is treated as if it
+            // was a simple search
+            // 2) The cookie is empty : this is a new request
+            // 3) The cookie is not empty, but the request is not the same : this is 
+            // a new request (we have to discard the cookie and do a new search from
+            // the beginning)
+            // 4) The cookie is not empty and the request is the same, we return
+            // the next SIZE elements
+            // 5) The SIZE is 0 and the cookie is the same than the previous one : this
+            // is a abandon request for this paged search.
+            int size = pagedSearchControl.getSize();
+            byte [] cookie= pagedSearchControl.getCookie();
             
-            // Position the cursor at the beginning
-            cursor.beforeFirst();
-
-            if ( sizeLimit == NO_SIZE_LIMIT )
+            // Case 5
+            if ( size == 0 )
             {
-                while ( cursor.next() )
+                // Remove the cookie from the session, if it's not null
+                if ( !StringTools.isEmpty( cookie ) )
                 {
-                    if ( session.getIoSession().isClosing() )
+                    int cookieValue = pagedSearchControl.getCookieValue();
+                    PagedSearchCookie psCookie = 
+                        (PagedSearchCookie)session.getIoSession().removeAttribute( cookieValue );
+                    pagedResultsControl = new PagedResultsControl( 0, psCookie.getCookie(), true );
+                    
+                    // Close the cursor
+                    cursor = psCookie.getCursor();
+                    
+                    if ( cursor != null )
                     {
-                        break;
+                        cursor.close();
                     }
-                    ClonedServerEntry entry = cursor.get();
-                    session.getIoSession().write( generateResponse( session, req, entry ) );
                 }
+                else
+                {
+                    pagedResultsControl = new PagedResultsControl( 0, true );
+                }
+                
+                // and return
+                // DO NOT WRITE THE RESPONSE - JUST RETURN IT
+                ldapResult.setResultCode( ResultCodeEnum.SUCCESS );
+                req.getResultResponse().add( pagedResultsControl );
+                return ( SearchResponseDone ) req.getResultResponse();
+            }
+            
+            if ( sizeLimit < size )
+            {
+                // Case 1
+                cursor = session.getCoreSession().search( req );
             }
             else
             {
-                int count = 0;
-                while ( cursor.next() )
+                isPaged = true;
+                sizeLimit = size;
+                
+                // Now, depending on the cookie, we will deal with case 2, 3 and 4
+                if ( StringTools.isEmpty( cookie ) )
                 {
-                    if ( session.getIoSession().isClosing() )
-                    {
-                        break;
-                    }
-                    if ( count < sizeLimit )
+                    // Case 2 : create the cookie
+                    cookieInstance = new PagedSearchCookie( req );
+                    cookie = cookieInstance.getCookie();
+                    int cookieValue = cookieInstance.getCookieValue();
+
+                    session.getIoSession().setAttribute( cookieValue, cookieInstance );
+                    pagedResultsControl = new PagedResultsControl( 0, cookie, true );
+                }
+                else
+                {
+                    int cookieValue = pagedSearchControl.getCookieValue();
+                    cookieInstance = 
+                        (PagedSearchCookie)session.getIoSession().getAttribute( cookieValue );
+                    
+                    if ( cookieInstance.hasSameRequest( req, session ) )
                     {
-                        ClonedServerEntry entry = cursor.get();
-                        session.getIoSession().write( generateResponse( session, req, entry ) );
-                        count++;
+                        // Case 4 : continue the search
+                        cursor = cookieInstance.getCursor();
+                        
+                        // get the cookie
+                        cookie = cookieInstance.getCookie();
+                        isPaged = true;
+                        sizeLimit = size;
+                        pagedResultsControl = new PagedResultsControl( 0, cookie, true );
                     }
                     else
                     {
-                        // DO NOT WRITE THE RESPONSE - JUST RETURN IT
-                        ldapResult.setResultCode( ResultCodeEnum.SIZE_LIMIT_EXCEEDED );
-                        return ( SearchResponseDone ) req.getResultResponse();
-                    }  
+                        // case 3 : create a new cursor
+                        // We have to close the cursor
+                        cursor = cookieInstance.getCursor();
+                        
+                        if ( cursor != null )
+                        {
+                            cursor.close();
+                        }
+                        
+                        // Now create a new cookie and stores it into the session
+                        cookieInstance = new PagedSearchCookie( req );
+                        cookie = cookieInstance.getCookie();
+                        cookieValue = cookieInstance.getCookieValue();
+
+                        session.getIoSession().setAttribute( cookieValue, cookieInstance );
+                        pagedResultsControl = new PagedResultsControl( 0, cookie, true );
+                    }
                 }
             }
-    
-            // DO NOT WRITE THE RESPONSE - JUST RETURN IT
-            ldapResult.setResultCode( ResultCodeEnum.SUCCESS );
-            return ( SearchResponseDone ) req.getResultResponse();
+        }
+        
+        // Check that we have a cursor or not. 
+        if ( cursor == null )
+        {
+            // No cursor : do a search.
+            cursor = session.getCoreSession().search( req );
+
+            // Position the cursor at the beginning
+            cursor.beforeFirst();
+        }
+        
+        /*
+         * Iterate through all search results building and sending back responses
+         * for each search result returned.
+         */
+        try
+        {
+            readResults( session, req, ldapResult, cursor, sizeLimit, isPaged, cookieInstance, pagedResultsControl );
         }
         finally
         {
-            if ( cursor != null )
+            if ( ( cursor != null ) && !isPaged )
             {
                 try
                 {
@@ -418,6 +599,8 @@
                 }
             }
         }
+        
+        return ( SearchResponseDone ) req.getResultResponse();
     }
     
 
@@ -438,8 +621,9 @@
         EntryAttribute ref = entry.getOriginalEntry().get( SchemaConstants.REF_AT );
         boolean hasManageDsaItControl = req.getControls().containsKey( ManageDsaITControl.CONTROL_OID );
 
-        if ( ref != null && ! hasManageDsaItControl )
+        if ( ( ref != null ) && ! hasManageDsaItControl )
         {
+            // The entry is a referral.
             SearchResponseReference respRef;
             respRef = new SearchResponseReferenceImpl( req.getMessageId() );
             respRef.setReferral( new ReferralImpl() );
@@ -469,9 +653,11 @@
                     case SUBTREE:
                         ldapUrl.setScope( SearchScope.SUBTREE.getJndiScope() );
                         break;
+                        
                     case ONELEVEL: // one level here is object level on remote server
                         ldapUrl.setScope( SearchScope.OBJECT.getJndiScope() );
                         break;
+                        
                     default:
                         throw new IllegalStateException( "Unexpected base scope." );
                 }
@@ -483,11 +669,19 @@
         }
         else 
         {
+            // The entry is not a referral, or the ManageDsaIt control is set
             SearchResponseEntry respEntry;
             respEntry = new SearchResponseEntryImpl( req.getMessageId() );
             respEntry.setEntry( entry );
             respEntry.setObjectName( entry.getDn() );
             
+            // Filter the userPassword if the server mandate to do so
+            if ( session.getCoreSession().getDirectoryService().isPasswordHidden() )
+            {
+                // Remove the userPassord attribute from the entry.
+                respEntry.getEntry().removeAttributes( SchemaConstants.USER_PASSWORD_AT );
+            }
+            
             return respEntry;
         }
     }
@@ -583,9 +777,6 @@
 
         try
         {
-            // modify the filter to affect continuation support
-            modifyFilter( session, req );
-            
             // ===============================================================
             // Handle search in rootDSE differently.
             // ===============================================================
@@ -596,6 +787,9 @@
                 return;
             }
 
+            // modify the filter to affect continuation support
+            modifyFilter( session, req );
+            
             // ===============================================================
             // Handle psearch differently
             // ===============================================================
@@ -663,6 +857,191 @@
 
 
     /**
+     * Handles processing with referrals without ManageDsaIT control.
+     */
+    public void handleWithReferrals( LdapSession session, LdapDN reqTargetDn, SearchRequest req ) throws NamingException
+    {
+        LdapResult result = req.getResultResponse().getLdapResult();
+        ClonedServerEntry entry = null;
+        boolean isReferral = false;
+        boolean isparentReferral = false;
+        ReferralManager referralManager = session.getCoreSession().getDirectoryService().getReferralManager();
+        
+        reqTargetDn.normalize( session.getCoreSession().getDirectoryService().getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
+        
+        // Check if the entry itself is a referral
+        referralManager.lockRead();
+        
+        isReferral = referralManager.isReferral( reqTargetDn );
+        
+        if ( !isReferral )
+        {
+            // Check if the entry has a parent which is a referral
+            isparentReferral = referralManager.hasParentReferral( reqTargetDn );
+        }
+        
+        referralManager.unlock();
+        
+        if ( !isReferral && !isparentReferral )
+        {
+            // This is not a referral and it does not have a parent which 
+            // is a referral : standard case, just deal with the request
+            LOG.debug( "Entry {} is NOT a referral.", reqTargetDn );
+            handleIgnoringReferrals( session, req );
+            return;
+        }
+        else
+        {
+            // -------------------------------------------------------------------
+            // Lookup Entry
+            // -------------------------------------------------------------------
+            
+            // try to lookup the entry but ignore exceptions when it does not   
+            // exist since entry may not exist but may have an ancestor that is a 
+            // referral - would rather attempt a lookup that fails then do check 
+            // for existence than have to do another lookup to get entry info
+            try
+            {
+                entry = session.getCoreSession().lookup( reqTargetDn );
+                LOG.debug( "Entry for {} was found: ", reqTargetDn, entry );
+            }
+            catch ( NameNotFoundException e )
+            {
+                /* ignore */
+                LOG.debug( "Entry for {} not found.", reqTargetDn );
+            }
+            catch ( Exception e )
+            {
+                /* serious and needs handling */
+                handleException( session, req, e );
+                return;
+            }
+            
+            // -------------------------------------------------------------------
+            // Handle Existing Entry
+            // -------------------------------------------------------------------
+            
+            if ( entry != null )
+            {
+                try
+                {
+                    LOG.debug( "Entry is a referral: {}", entry );
+                    
+                    handleReferralEntryForSearch( session, ( SearchRequest ) req, entry );
+
+                    return;
+                }
+                catch ( Exception e )
+                {
+                    handleException( session, req, e );
+                }
+            }
+    
+            // -------------------------------------------------------------------
+            // Handle Non-existing Entry
+            // -------------------------------------------------------------------
+            
+            // if the entry is null we still have to check for a referral ancestor
+            // also the referrals need to be adjusted based on the ancestor's ref
+            // values to yield the correct path to the entry in the target DSAs
+            
+            else
+            {
+                // The entry is null : it has a parent referral.
+                ClonedServerEntry referralAncestor = null;
+    
+                try
+                {
+                    referralAncestor = getFarthestReferralAncestor( session, reqTargetDn );
+                }
+                catch ( Exception e )
+                {
+                    handleException( session, req, e );
+                    return;
+                }
+    
+                if ( referralAncestor == null )
+                {
+                    result.setErrorMessage( "Entry not found." );
+                    result.setResultCode( ResultCodeEnum.NO_SUCH_OBJECT );
+                    session.getIoSession().write( req.getResultResponse() );
+                    return;
+                }
+                  
+                // if we get here then we have a valid referral ancestor
+                try
+                {
+                    Referral referral = getReferralOnAncestorForSearch( session, ( SearchRequest ) req, referralAncestor );
+                    
+                    result.setResultCode( ResultCodeEnum.REFERRAL );
+                    result.setReferral( referral );
+                    session.getIoSession().write( req.getResultResponse() );
+                }
+                catch ( Exception e )
+                {
+                    handleException( session, req, e );
+                }
+            }
+        }
+    }
+    
+    
+    /**
+     * Handles processing a referral response on a target entry which is a 
+     * referral.  It will for any request that returns an LdapResult in it's 
+     * response.
+     *
+     * @param session the session to use for processing
+     * @param reqTargetDn the dn of the target entry of the request
+     * @param req the request
+     * @param entry the entry associated with the request
+     */
+    private void handleReferralEntryForSearch( LdapSession session, SearchRequest req, ClonedServerEntry entry )
+        throws Exception
+    {
+        LdapResult result = req.getResultResponse().getLdapResult();
+        ReferralImpl referral = new ReferralImpl();
+        result.setReferral( referral );
+        result.setResultCode( ResultCodeEnum.REFERRAL );
+        result.setErrorMessage( "Encountered referral attempting to handle request." );
+        result.setMatchedDn( req.getBase() );
+
+        EntryAttribute refAttr = entry.getOriginalEntry().get( SchemaConstants.REF_AT );
+        
+        for ( Value<?> refval : refAttr )
+        {
+            String refstr = ( String ) refval.get();
+            
+            // need to add non-ldap URLs as-is
+            if ( ! refstr.startsWith( "ldap" ) )
+            {
+                referral.addLdapUrl( refstr );
+                continue;
+            }
+            
+            // parse the ref value and normalize the DN  
+            LdapURL ldapUrl = new LdapURL();
+            try
+            {
+                ldapUrl.parse( refstr.toCharArray() );
+            }
+            catch ( LdapURLEncodingException e )
+            {
+                LOG.error( "Bad URL ({}) for ref in {}.  Reference will be ignored.", refstr, entry );
+                continue;
+            }
+            
+            ldapUrl.setForceScopeRendering( true );
+            ldapUrl.setAttributes( req.getAttributes() );
+            ldapUrl.setScope( req.getScope().getJndiScope() );
+            referral.addLdapUrl( ldapUrl.toString() );
+        }
+
+        session.getIoSession().write( req.getResultResponse() );
+    }
+    
+    
+    /**
      * Determines if a search request is on the RootDSE of the server.
      * 
      * It is a RootDSE search if :

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/UnbindHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/UnbindHandler.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/UnbindHandler.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/UnbindHandler.java Thu Dec 11 07:32:04 2008
@@ -44,7 +44,7 @@
         try
         {
             session.getCoreSession().unbind( request );
-            session.getIoSession().close();
+            session.getIoSession().close( true );
             ldapService.getLdapSessionManager().removeLdapSession( session.getIoSession() );
         }
         catch ( Throwable t )

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/AbstractMechanismHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/AbstractMechanismHandler.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/AbstractMechanismHandler.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/AbstractMechanismHandler.java Thu Dec 11 07:32:04 2008
@@ -22,8 +22,8 @@
 import javax.security.sasl.SaslServer;
 
 import org.apache.directory.server.ldap.LdapSession;
-import org.apache.mina.common.IoFilterChain;
-import org.apache.mina.common.IoSession;
+import org.apache.mina.core.filterchain.IoFilterChain;
+import org.apache.mina.core.session.IoSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/AbstractSaslCallbackHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/AbstractSaslCallbackHandler.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/AbstractSaslCallbackHandler.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/AbstractSaslCallbackHandler.java Thu Dec 11 07:32:04 2008
@@ -34,7 +34,7 @@
 import org.apache.directory.shared.ldap.name.LdapDN;
 import org.apache.directory.shared.ldap.util.ExceptionUtils;
 import org.apache.directory.shared.ldap.util.StringTools;
-import org.apache.mina.common.IoSession;
+import org.apache.mina.core.session.IoSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/SaslFilter.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/SaslFilter.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/SaslFilter.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/SaslFilter.java Thu Dec 11 07:32:04 2008
@@ -25,9 +25,11 @@
 import javax.security.sasl.SaslServer;
 
 import org.apache.directory.shared.ldap.constants.SaslQoP;
-import org.apache.mina.common.ByteBuffer;
-import org.apache.mina.common.IoFilterAdapter;
-import org.apache.mina.common.IoSession;
+import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.mina.core.filterchain.IoFilterAdapter;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.core.write.DefaultWriteRequest;
+import org.apache.mina.core.write.WriteRequest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -95,14 +97,14 @@
             /*
              * Get the buffer as bytes.  First 4 bytes are length as int.
              */
-            ByteBuffer buf = ( ByteBuffer ) message;
+            IoBuffer buf = ( IoBuffer ) message;
             int bufferLength = buf.getInt();
             byte[] bufferBytes = new byte[bufferLength];
             buf.get( bufferBytes );
 
             log.debug( "Will use SASL to unwrap received message of length:  {}", bufferLength );
             byte[] token = saslServer.unwrap( bufferBytes, 0, bufferBytes.length );
-            nextFilter.messageReceived( session, ByteBuffer.wrap( token ) );
+            nextFilter.messageReceived( session, IoBuffer.wrap( token ) );
         }
         else
         {
@@ -134,14 +136,14 @@
         String qop = ( String ) saslServer.getNegotiatedProperty( Sasl.QOP );
         boolean hasSecurityLayer = ( qop != null && ( qop.equals( SaslQoP.QOP_AUTH_INT ) || qop.equals( SaslQoP.QOP_AUTH_CONF ) ) );
 
-        ByteBuffer saslLayerBuffer = null;
+        IoBuffer saslLayerBuffer = null;
 
         if ( hasSecurityLayer )
         {
             /*
              * Get the buffer as bytes.
              */
-            ByteBuffer buf = ( ByteBuffer ) writeRequest.getMessage();
+            IoBuffer buf = ( IoBuffer ) writeRequest.getMessage();
             int bufferLength = buf.remaining();
             byte[] bufferBytes = new byte[bufferLength];
             buf.get( bufferBytes );
@@ -153,14 +155,14 @@
             /*
              * Prepend 4 byte length.
              */
-            saslLayerBuffer = ByteBuffer.allocate( 4 + saslLayer.length );
+            saslLayerBuffer = IoBuffer.allocate( 4 + saslLayer.length );
             saslLayerBuffer.putInt( saslLayer.length );
             saslLayerBuffer.put( saslLayer );
             saslLayerBuffer.position( 0 );
             saslLayerBuffer.limit( 4 + saslLayer.length );
 
             log.debug( "Sending encrypted token of length {}.", saslLayerBuffer.limit() );
-            nextFilter.filterWrite( session, new WriteRequest( saslLayerBuffer, writeRequest.getFuture() ) );
+            nextFilter.filterWrite( session, new DefaultWriteRequest( saslLayerBuffer, writeRequest.getFuture() ) );
         }
         else
         {

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/ntlm/NtlmProvider.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/ntlm/NtlmProvider.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/ntlm/NtlmProvider.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/ntlm/NtlmProvider.java Thu Dec 11 07:32:04 2008
@@ -19,8 +19,7 @@
  */
 package org.apache.directory.server.ldap.handlers.bind.ntlm;
 
-
-import org.apache.mina.common.IoSession;
+import org.apache.mina.core.session.IoSession;
 
 
 /**

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/controls/PagedSearchCookie.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/controls/PagedSearchCookie.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/controls/PagedSearchCookie.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/controls/PagedSearchCookie.java Thu Dec 11 07:32:04 2008
@@ -19,108 +19,301 @@
  */
 package org.apache.directory.server.ldap.handlers.controls;
 
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.server.core.filtering.EntryFilteringCursor;
+import org.apache.directory.server.ldap.LdapSession;
+import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
+import org.apache.directory.shared.asn1.ber.tlv.Value;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.message.SearchRequest;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.util.StringTools;
 
 /**
+ * The structure which stores the informations relative to the pagedSearch control.
+ * They are associated to a cookie, stored into the session and associated to an 
+ * instance of this class.
  * 
- * A container for the Page search cookie. We store multiple informations :
- *  - 
- *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
+ * @version $Rev:  $
  */
 public class PagedSearchCookie
 {
-    /** The total number of entries already returned */ 
-    private int cumulativeSize;
+    /** The previous search request */
+    private SearchRequest previousSearchRequest;
+    
+    /** The current position in the cursor */
+    private int currentPosition;
+    
+    /** The cookie key */
+    private byte[] cookie;
+    
+    /** The integer value for the cookie */
+    private int cookieValue;
+    
+    /** The associated cursor for the current search request */
+    private EntryFilteringCursor cursor;
+    
+    /**
+     * Creates a new instance of this class, storing the Searchrequest into it.
+     */
+    public PagedSearchCookie( SearchRequest searchRequest )
+    {
+        previousSearchRequest = searchRequest;
+        currentPosition = 0;
+        
+        // We compute a key for this cookie. It combines the search request
+        // and some time seed, in order to avoid possible collisions, as
+        // a user may send more than one PagedSearch on the same session.
+        cookieValue = (int)(System.nanoTime()*17) + searchRequest.getMessageId();
+        
+        cookie = Value.getBytes( cookieValue );
+    }
+    
     
-    /** The original MessageId */
-    private int messageId;
     /**
+     * Compute a new key for this cookie, based on the current searchRequest 
+     * hashCode and the current position. This value will be stored into the
+     * session, and will permit the retrieval of this instance.
      * 
-     * Creates a new instance of PagedSearchCookie.
-     *
+     * @return The new cookie's key
      */
-    public PagedSearchCookie()
+    public byte[] getCookie()
     {
-        cumulativeSize = 0;
-        messageId = -1;
+        return cookie;
     }
 
-
+    
+    public int getCookieValue()
+    {
+        return cookieValue;
+    }
+    
+    
     /**
-     * 
-     * Creates a new instance of PagedSearchCookie,
-     * deserializing the cookie.
-     * 
-     * @throws BufferUnderflowException if the buffer is not large enough to 
-     * contain correct values
-     *
+     * Compute a new cookie, if the previous one already exists. This
+     * is unlikely, as we are based on some time seed, but just in case, 
+     * this method will generate a new one.
+     * @return The new cookie
      */
-    public PagedSearchCookie( byte[] cookie ) throws BufferUnderflowException
+    public byte[] getNewCookie()
     {
-        ByteBuffer bb = ByteBuffer.allocate( cookie.length );
-        bb.put( cookie );
+        cookieValue = cookieValue + (int)(System.nanoTime()*17);
+        cookie = Value.getBytes( cookieValue );
         
-        cumulativeSize = bb.getInt();
-        messageId = bb.getInt();
+        return cookie;
     }
-
-
+    
+    
     /**
-     * @return The current number of entries returned since the first request 
+     * Build a set of OIDs from the list of attributes we have in the search request
      */
-    public int getCumulativeSize()
+    private Set<String> buildAttributeSet( SearchRequest request, LdapSession session, 
+        AttributeTypeRegistry atRegistry )
     {
-        return cumulativeSize;
+        Set<String> requestSet = new HashSet<String>();
+        
+        // Build the set of attributeType from the attributes
+        for ( String attribute:request.getAttributes() )
+        {
+            try
+            {
+                AttributeType at = atRegistry.lookup( attribute );
+                requestSet.add( at.getOid() );
+            }
+            catch ( NamingException ne )
+            {
+                // Deal with special attributes : '*', '+' and '1.1'
+                if ( attribute.equals( SchemaConstants.ALL_OPERATIONAL_ATTRIBUTES ) ||
+                     attribute.equals( SchemaConstants.ALL_USER_ATTRIBUTES ) ||
+                     attribute.equals( SchemaConstants.NO_ATTRIBUTE ) )
+                {
+                    requestSet.add( attribute );
+                }
+                
+                // Otherwise, don't add the attribute to the set
+            }
+        }
+        
+        return requestSet;
     }
+    
+    /**
+     * Compare the previous search request and the new one, and return 
+     * true if they are equal. We compare every field but the MessageID.
+     * 
+     * @param request The new SearchRequest
+     * @return true if both request are equal.
+     */
+    public boolean hasSameRequest( SearchRequest request, LdapSession session )
+    {
+        // Compares the scope
+        if ( request.getScope() != previousSearchRequest.getScope() )
+        {
+            return false;
+        }
+        
+        // Compares the sizeLimit
+        if ( request.getSizeLimit() != previousSearchRequest.getSizeLimit() )
+        {
+            return false;
+        }
+
+        // Compares the timeLimit
+        if ( request.getTimeLimit() != previousSearchRequest.getTimeLimit() )
+        {
+            return false;
+        }
+        
+        // Compares the TypesOnly
+        if ( request.getTypesOnly() != previousSearchRequest.getTypesOnly() )
+        {
+            return false;
+        }
+        
+        // Compares the deref aliases mode
+        if ( request.getDerefAliases() != previousSearchRequest.getDerefAliases() )
+        {
+            return false;
+        }
+        
+        AttributeTypeRegistry atRegistry = 
+            session.getLdapServer().getDirectoryService().getRegistries().getAttributeTypeRegistry();
 
+        // Compares the attributes
+        if ( request.getAttributes() == null )
+        {
+            if ( previousSearchRequest.getAttributes() != null )
+            {
+                return false;
+            }
+        }
+        else
+        {
+            if ( previousSearchRequest.getAttributes() == null )
+            {
+                return false;
+            }
+            else
+            {
+                // We have to normalize the attributes in order to compare them
+                if ( request.getAttributes().size() != previousSearchRequest.getAttributes().size() )
+                {
+                    return false;
+                }
+                
+                // Build the set of attributeType from both requests
+                Set<String> requestSet = buildAttributeSet( request, session, atRegistry );
+                Set<String> previousRequestSet = buildAttributeSet( previousSearchRequest, session, atRegistry );
+                
+                // Check that both sets have the same size again after having converted
+                // the attributes to OID
+                if ( requestSet.size() != previousRequestSet.size() )
+                {
+                    return false;
+                }
+                
+                for ( String attribute:requestSet )
+                {
+                    previousRequestSet.remove( attribute );
+                }
+                
+                // The other set must be empty
+                if ( !previousRequestSet.isEmpty() )
+                {
+                    return false;
+                }
+            }
+        }
+        
+        // Compare the baseDN
+        try
+        {
+            request.getBase().normalize( atRegistry.getNormalizerMapping() );
+            
+            if ( !previousSearchRequest.getBase().isNormalized() )
+            {
+                previousSearchRequest.getBase().normalize( atRegistry.getNormalizerMapping() );
+            }
+            
+            if ( !request.getBase().equals( previousSearchRequest.getBase() ) )
+            {
+                return false;
+            }
+        }
+        catch ( NamingException ne )
+        {
+            return false;
+        }
+        
+        // Compare the filters
+        // Here, we assume the user hasn't changed the filter's order or content,
+        // as the filter is not normalized. This is a real problem, as the normalization
+        // phase is done in the interceptor chain, which is a bad decision wrt what we
+        // do here.
+        return true; //request.getFilter().equals( previousSearchRequest.getFilter() );
+    }
 
+    
     /**
-     * Increment the cumulativeSize field with the number of
-     * entries returned with the last request
-     *
-     * @param size
+     * @return The current position in the cursor. This value is updated
+     * after each successful search request. 
      */
-    public void incrementCumulativeSize()
+    public int getCurrentPosition()
     {
-        cumulativeSize ++;
+        return currentPosition;
     }
+
     
+    /**
+     * Set the new current position, incrementing it with the 
+     * number of returned entries.
+     * 
+     * @param returnedEntries The number of returned entries
+     */
+    public void incrementCurrentPosition( int returnedEntries )
+    {
+        this.currentPosition += returnedEntries;
+    }
+
     
     /**
-     * @return The cookie associated messageId
+     * @return The previous search request
      */
-    public int getMessageId()
+    public SearchRequest getPreviousSearchRequest()
     {
-        return messageId;
+        return previousSearchRequest;
     }
 
 
     /**
-     * Assign the message ID to this cookie
-     *
-     * @param messageId The request message ID
+     * @return The associated cursor
      */
-    public void setMessageId( int messageId )
+    public EntryFilteringCursor getCursor()
     {
-        this.messageId = messageId;
+        return cursor;
     }
 
+
+    /**
+     * Set the new cursor for this search request
+     * @param cursor The associated cursor
+     */
+    public void setCursor( EntryFilteringCursor cursor )
+    {
+        this.cursor = cursor;
+    }
+    
     
     /**
-     * Serialize the cookie 
-     *
-     * @return A byte array containing the data returned to the client
+     * @see Object#toString()
      */
-    public byte[] serialize()
+    public String toString()
     {
-        ByteBuffer bb = ByteBuffer.allocate( 12 );
-        
-        bb.putInt( cumulativeSize );
-        bb.putInt( messageId );
-        
-        return bb.array();
+        return "PagedSearch cookie:" + StringTools.dumpBytes( cookie );
     }
 }

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/GracefulShutdownHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/GracefulShutdownHandler.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/GracefulShutdownHandler.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/GracefulShutdownHandler.java Thu Dec 11 07:32:04 2008
@@ -36,9 +36,9 @@
 import org.apache.directory.shared.ldap.message.extended.GracefulShutdownRequest;
 import org.apache.directory.shared.ldap.message.extended.GracefulShutdownResponse;
 import org.apache.directory.shared.ldap.message.extended.NoticeOfDisconnect;
-import org.apache.mina.common.IoAcceptor;
-import org.apache.mina.common.IoSession;
-import org.apache.mina.common.WriteFuture;
+import org.apache.mina.core.future.WriteFuture;
+import org.apache.mina.core.service.IoAcceptor;
+import org.apache.mina.core.session.IoSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -91,7 +91,7 @@
 
         IoAcceptor acceptor = ( IoAcceptor ) requestor.getIoSession().getService();
         List<IoSession> sessions = new ArrayList<IoSession>(
-                acceptor.getManagedSessions( requestor.getIoSession().getServiceAddress() ) );
+                acceptor.getManagedSessions().values() );
         GracefulShutdownRequest gsreq = ( GracefulShutdownRequest ) req;
 
         // build the graceful disconnect message with replicationContexts
@@ -142,7 +142,7 @@
     {
         GracefulShutdownResponse msg = new GracefulShutdownResponse( messageId, ResultCodeEnum.SUCCESS );
         WriteFuture future = requestor.write( msg );
-        future.join();
+        future.awaitUninterruptibly();
         if ( future.isWritten() )
         {
             if ( LOG.isInfoEnabled() )
@@ -154,7 +154,7 @@
         {
             LOG.error( "Failed to write GracefulShutdownResponse to client: " + requestor.getRemoteAddress() );
         }
-        requestor.close();
+        requestor.close( true );
     }
 
 
@@ -254,7 +254,7 @@
             try
             {
                 future.join( 1000 );
-                sessionIt.next().close();
+                sessionIt.next().close( true );
             }
             catch ( Exception e )
             {

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/StartTlsHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/StartTlsHandler.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/StartTlsHandler.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/StartTlsHandler.java Thu Dec 11 07:32:04 2008
@@ -44,8 +44,8 @@
 import org.apache.directory.shared.ldap.message.ExtendedResponseImpl;
 import org.apache.directory.shared.ldap.message.LdapResult;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
-import org.apache.mina.common.IoFilterChain;
-import org.apache.mina.filter.SSLFilter;
+import org.apache.mina.core.filterchain.IoFilterChain;
+import org.apache.mina.filter.ssl.SslFilter;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -82,15 +82,15 @@
         LOG.info( "Handling StartTLS request." );
         
         IoFilterChain chain = session.getIoSession().getFilterChain();
-        SSLFilter sslFilter = ( SSLFilter ) chain.get( "sslFilter" );
+        SslFilter sslFilter = ( SslFilter ) chain.get( "sslFilter" );
         if( sslFilter == null )
         {
-            sslFilter = new SSLFilter( sslContext );
+            sslFilter = new SslFilter( sslContext );
             chain.addFirst( "sslFilter", sslFilter );
         }
         else
         {
-            sslFilter.startSSL( session.getIoSession() );
+            sslFilter.startSsl( session.getIoSession() );
         }
         
         ExtendedResponse res = new ExtendedResponseImpl( req.getMessageId() );
@@ -100,7 +100,7 @@
         res.setResponse( new byte[ 0 ] );
 
         // Send a response.
-        session.getIoSession().setAttribute( SSLFilter.DISABLE_ENCRYPTION_ONCE );
+        session.getIoSession().setAttribute( SslFilter.DISABLE_ENCRYPTION_ONCE );
         session.getIoSession().write( res );
     }
     
@@ -157,7 +157,7 @@
         KeyManagerFactory keyManagerFactory = null;
         try
         {
-            keyManagerFactory = KeyManagerFactory.getInstance( "SunX509" );
+            keyManagerFactory = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm() );
         }
         catch ( Exception e )
         {

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/ssl/LdapsInitializer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/ssl/LdapsInitializer.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/ssl/LdapsInitializer.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/ssl/LdapsInitializer.java Thu Dec 11 07:32:04 2008
@@ -29,9 +29,9 @@
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManager;
 
-import org.apache.mina.common.DefaultIoFilterChainBuilder;
-import org.apache.mina.common.IoFilterChainBuilder;
-import org.apache.mina.filter.SSLFilter;
+import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
+import org.apache.mina.core.filterchain.IoFilterChainBuilder;
+import org.apache.mina.filter.ssl.SslFilter;
 
 
 /**
@@ -51,10 +51,12 @@
         {
             // Set up key manager factory to use our key store
             String algorithm = Security.getProperty( "ssl.KeyManagerFactory.algorithm" );
+
             if ( algorithm == null )
             {
-                algorithm = "SunX509";
+                algorithm = KeyManagerFactory.getDefaultAlgorithm();
             }
+            
             KeyManagerFactory kmf = KeyManagerFactory.getInstance( algorithm );
             kmf.init( ks, null );
 
@@ -69,7 +71,7 @@
         }
 
         DefaultIoFilterChainBuilder chain = new DefaultIoFilterChainBuilder();
-        chain.addLast( "sslFilter", new SSLFilter( sslCtx ) );
+        chain.addLast( "sslFilter", new SslFilter( sslCtx ) );
         return chain;
     }
 }

Modified: directory/apacheds/trunk/protocol-ldap/src/test/java/org/apache/directory/server/ldap/SettingAlternativeHandlersTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/test/java/org/apache/directory/server/ldap/SettingAlternativeHandlersTest.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/test/java/org/apache/directory/server/ldap/SettingAlternativeHandlersTest.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/test/java/org/apache/directory/server/ldap/SettingAlternativeHandlersTest.java Thu Dec 11 07:32:04 2008
@@ -43,7 +43,7 @@
 import org.apache.directory.shared.ldap.message.ModifyRequest;
 import org.apache.directory.shared.ldap.message.SearchRequest;
 import org.apache.directory.shared.ldap.message.UnbindRequest;
-import org.apache.mina.common.IoSession;
+import org.apache.mina.core.session.IoSession;
 
 
 /**

Modified: directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/NtpServer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/NtpServer.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/NtpServer.java (original)
+++ directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/NtpServer.java Thu Dec 11 07:32:04 2008
@@ -20,10 +20,17 @@
 package org.apache.directory.server.ntp;
 
 
+import org.apache.directory.server.ntp.protocol.NtpProtocolCodecFactory;
 import org.apache.directory.server.ntp.protocol.NtpProtocolHandler;
 import org.apache.directory.server.protocol.shared.AbstractProtocolService;
-import org.apache.mina.transport.socket.nio.DatagramAcceptorConfig;
-import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
+import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
+import org.apache.mina.core.service.IoHandler;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.transport.socket.DatagramAcceptor;
+import org.apache.mina.transport.socket.DatagramSessionConfig;
+import org.apache.mina.transport.socket.SocketAcceptor;
+import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
+import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
 
 import java.io.IOException;
 import java.net.InetSocketAddress;
@@ -66,23 +73,63 @@
 
     
     /**
+     * Start the NTPServer. We initialize the Datagram and Socket, if necessary.
+     * 
+     * Note that we don't have any filter in the chain, everything is done
+     * in the handler.
      * @throws IOException if there are issues binding
      */
     public void start() throws IOException
     {
-        //If appropriate, the udp and tcp servers could be enabled with boolean flags.
-        if ( getDatagramAcceptor() != null )
+        IoHandler ntpProtocolHandler = new NtpProtocolHandler();
+        
+        // Create the chain for the NTP server
+        DefaultIoFilterChainBuilder ntpChain = new DefaultIoFilterChainBuilder();
+        ntpChain.addLast( "codec", new ProtocolCodecFilter( NtpProtocolCodecFactory.getInstance() ) );
+        
+        if ( getUdpPort() > 0 )
         {
-            DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig();
-            getDatagramAcceptor().bind( new InetSocketAddress( getIpPort() ), new NtpProtocolHandler(), udpConfig );
+            // We have to create a DatagramAcceptor
+            DatagramAcceptor acceptor = new  NioDatagramAcceptor();
+            setDatagramAcceptor( (NioDatagramAcceptor)acceptor );
+        
+            // Set the handler
+            acceptor.setHandler( ntpProtocolHandler );
+    
+            // Allow the port to be reused even if the socket is in TIME_WAIT state
+            ((DatagramSessionConfig)acceptor.getSessionConfig()).setReuseAddress( true );
+    
+            // Inject the chain
+            acceptor.setFilterChainBuilder( ntpChain );
+                
+            // Start the listener
+            acceptor.bind( new InetSocketAddress( getUdpPort() ) );
         }
-
-        if ( getSocketAcceptor() != null )
+        
+        if ( getTcpPort() > 0 )
         {
-            SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig();
-            tcpConfig.setDisconnectOnUnbind( false );
-            tcpConfig.setReuseAddress( true );
-            getSocketAcceptor().bind( new InetSocketAddress( getIpPort() ), new NtpProtocolHandler(), tcpConfig );
+            // It's a SocketAcceptor
+            SocketAcceptor acceptor = new NioSocketAcceptor();
+            
+            // Set the handler
+            acceptor.setHandler( ntpProtocolHandler );
+
+            // Disable the disconnection of the clients on unbind
+            acceptor.setCloseOnDeactivation( false );
+            
+            // Allow the port to be reused even if the socket is in TIME_WAIT state
+            acceptor.setReuseAddress( true );
+            
+            // No Nagle's algorithm
+            acceptor.getSessionConfig().setTcpNoDelay( true );
+            
+            // Inject the chain
+            acceptor.setFilterChainBuilder( ntpChain );
+
+            setSocketAcceptor( acceptor );
+            
+            // Start the listener
+            acceptor.bind( new InetSocketAddress( getTcpPort() ) );
         }
     }
 
@@ -99,4 +146,27 @@
             getSocketAcceptor().unbind( new InetSocketAddress( getIpPort() ));
         }
     }
+    
+    
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        
+        sb.append( "NTPServer[" ).append( getServiceName() ).append( "] :" ).append( '\n' );
+        
+        if ( getUdpPort() > 0 )
+        {
+            sb.append( "  Listening on UDP:" ).append( getUdpPort() ).append( '\n' );
+        }
+
+        if ( getTcpPort() > 0 )
+        {
+            sb.append( "  Listening on TCP:" ).append( getTcpPort() ).append( '\n' );
+        }
+        
+        return sb.toString();
+    }
 }

Modified: directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpDecoder.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpDecoder.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpDecoder.java (original)
+++ directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpDecoder.java Thu Dec 11 07:32:04 2008
@@ -22,8 +22,8 @@
 
 
 import org.apache.directory.server.ntp.io.NtpMessageDecoder;
-import org.apache.mina.common.ByteBuffer;
-import org.apache.mina.common.IoSession;
+import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.mina.core.session.IoSession;
 import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
 import org.apache.mina.filter.codec.ProtocolDecoderOutput;
 
@@ -34,7 +34,7 @@
  */
 public class NtpDecoder extends ProtocolDecoderAdapter
 {
-    public void decode( IoSession session, ByteBuffer in, ProtocolDecoderOutput out )
+    public void decode( IoSession session, IoBuffer in, ProtocolDecoderOutput out )
     {
         NtpMessageDecoder decoder = new NtpMessageDecoder();
         out.write( decoder.decode( in.buf() ) );

Modified: directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpEncoder.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpEncoder.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpEncoder.java (original)
+++ directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpEncoder.java Thu Dec 11 07:32:04 2008
@@ -23,8 +23,8 @@
 
 import org.apache.directory.server.ntp.io.NtpMessageEncoder;
 import org.apache.directory.server.ntp.messages.NtpMessage;
-import org.apache.mina.common.ByteBuffer;
-import org.apache.mina.common.IoSession;
+import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.mina.core.session.IoSession;
 import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
 import org.apache.mina.filter.codec.ProtocolEncoderOutput;
 
@@ -39,7 +39,7 @@
     {
         NtpMessageEncoder encoder = new NtpMessageEncoder();
 
-        ByteBuffer buf = ByteBuffer.allocate( 1024 );
+        IoBuffer buf = IoBuffer.allocate( 1024 );
         encoder.encode( buf.buf(), ( NtpMessage ) message );
 
         buf.flip();

Modified: directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpProtocolCodecFactory.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpProtocolCodecFactory.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpProtocolCodecFactory.java (original)
+++ directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpProtocolCodecFactory.java Thu Dec 11 07:32:04 2008
@@ -21,6 +21,7 @@
 package org.apache.directory.server.ntp.protocol;
 
 
+import org.apache.mina.core.session.IoSession;
 import org.apache.mina.filter.codec.ProtocolCodecFactory;
 import org.apache.mina.filter.codec.ProtocolDecoder;
 import org.apache.mina.filter.codec.ProtocolEncoder;
@@ -52,14 +53,14 @@
     }
 
 
-    public ProtocolEncoder getEncoder()
+    public ProtocolEncoder getEncoder( IoSession session )
     {
         // Create a new encoder.
         return new NtpEncoder();
     }
 
 
-    public ProtocolDecoder getDecoder()
+    public ProtocolDecoder getDecoder( IoSession session )
     {
         // Create a new decoder.
         return new NtpDecoder();

Modified: directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpProtocolHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpProtocolHandler.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpProtocolHandler.java (original)
+++ directory/apacheds/trunk/protocol-ntp/src/main/java/org/apache/directory/server/ntp/protocol/NtpProtocolHandler.java Thu Dec 11 07:32:04 2008
@@ -24,71 +24,42 @@
 import org.apache.directory.server.ntp.NtpService;
 import org.apache.directory.server.ntp.messages.NtpMessage;
 import org.apache.directory.server.ntp.service.NtpServiceImpl;
-import org.apache.mina.common.IdleStatus;
-import org.apache.mina.common.IoHandler;
-import org.apache.mina.common.IoSession;
-import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.core.service.IoHandlerAdapter;
+import org.apache.mina.core.session.IoSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 
 /**
+ * The NTP protocol handler. It implements the {@link IoHandler#messageReceived} method,
+ * which returns the NTP reply. The {@link IoHandler#exceptionCaught} is also implemented,
+ * all the other methods are handled by the {@link IoHandlerAdapter} class.<br/>
+ * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class NtpProtocolHandler implements IoHandler
+public class NtpProtocolHandler extends IoHandlerAdapter
 {
     /** the log for this class */
     private static final Logger log = LoggerFactory.getLogger( NtpProtocolHandler.class );
 
+    /** The NtpService instance */
     private NtpService ntpService = new NtpServiceImpl();
 
 
-    public void sessionCreated( IoSession session ) throws Exception
-    {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "{} CREATED", session.getRemoteAddress() );
-        }
-
-        session.getFilterChain().addFirst( "codec", new ProtocolCodecFilter( NtpProtocolCodecFactory.getInstance() ) );
-    }
-
-
-    public void sessionOpened( IoSession session )
-    {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "{} OPENED", session.getRemoteAddress() );
-        }
-    }
-
-
-    public void sessionClosed( IoSession session )
-    {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "{} CLOSED", session.getRemoteAddress() );
-        }
-    }
-
-
-    public void sessionIdle( IoSession session, IdleStatus status )
-    {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "{} IDLE ({})", session.getRemoteAddress(), status );
-        }
-    }
-
-
+    /**
+     * {@inheritDoc}
+     */
     public void exceptionCaught( IoSession session, Throwable cause )
     {
         log.error( session.getRemoteAddress() + " EXCEPTION", cause );
-        session.close();
+        session.close( true );
     }
 
 
+    /**
+     * {@inheritDoc}
+     */
     public void messageReceived( IoSession session, Object message )
     {
         if ( log.isDebugEnabled() )
@@ -100,13 +71,4 @@
 
         session.write( reply );
     }
-
-
-    public void messageSent( IoSession session, Object message )
-    {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "{} SENT:  {}", session.getRemoteAddress(), message );
-        }
-    }
 }

Modified: directory/apacheds/trunk/protocol-ntp/src/test/java/org/apache/directory/server/ntp/NtpITest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ntp/src/test/java/org/apache/directory/server/ntp/NtpITest.java?rev=725712&r1=725711&r2=725712&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ntp/src/test/java/org/apache/directory/server/ntp/NtpITest.java (original)
+++ directory/apacheds/trunk/protocol-ntp/src/test/java/org/apache/directory/server/ntp/NtpITest.java Thu Dec 11 07:32:04 2008
@@ -21,13 +21,15 @@
 
 
 import java.net.InetAddress;
+import java.util.concurrent.Executors;
 
 import junit.framework.Assert;
 import junit.framework.TestCase;
 import org.apache.commons.net.ntp.NTPUDPClient;
 import org.apache.commons.net.ntp.TimeInfo;
-import org.apache.directory.server.protocol.shared.DatagramAcceptor;
 import org.apache.directory.server.unit.AbstractServerTest;
+import org.apache.mina.filter.executor.ExecutorFilter;
+import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
 import org.apache.mina.util.AvailablePortFinder;
 
 
@@ -48,7 +50,9 @@
      */
     public void setUp() throws Exception
     {
-        DatagramAcceptor datagramAcceptor = new DatagramAcceptor( null );
+        NioDatagramAcceptor datagramAcceptor = new NioDatagramAcceptor( null );
+        datagramAcceptor.getFilterChain().addLast( "executor", new ExecutorFilter( Executors.newCachedThreadPool() ) );
+        //datagramAcceptor.getFilterChain().addlast( "decoder", )
         ntpConfig = new NtpServer();
         ntpConfig.setDatagramAcceptor( datagramAcceptor );
         ntpConfig.setEnabled( true );
@@ -70,7 +74,7 @@
         InetAddress host = InetAddress.getByName( null );
 
         NTPUDPClient ntp = new NTPUDPClient();
-        ntp.setDefaultTimeout( 5000 );
+        ntp.setDefaultTimeout( 500000 );
 
         TimeInfo timeInfo = ntp.getTime( host, port );
         long returnTime = timeInfo.getReturnTime();