/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *  
 *    http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License. 
 *  
 */
package org.apache.directory.server.ldap;


import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreSpi;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.directory.server.core.api.DirectoryService;
import org.apache.directory.server.core.api.partition.PartitionNexus;
import org.apache.directory.server.core.security.CoreKeyStoreSpi;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.server.ldap.handlers.AbandonHandler;
import org.apache.directory.server.ldap.handlers.AddHandler;
import org.apache.directory.server.ldap.handlers.BindHandler;
import org.apache.directory.server.ldap.handlers.CompareHandler;
import org.apache.directory.server.ldap.handlers.DeleteHandler;
import org.apache.directory.server.ldap.handlers.ExtendedHandler;
import org.apache.directory.server.ldap.handlers.LdapRequestHandler;
import org.apache.directory.server.ldap.handlers.ModifyDnHandler;
import org.apache.directory.server.ldap.handlers.ModifyHandler;
import org.apache.directory.server.ldap.handlers.SearchHandler;
import org.apache.directory.server.ldap.handlers.UnbindHandler;
import org.apache.directory.server.ldap.handlers.bind.MechanismHandler;
import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
import org.apache.directory.server.ldap.handlers.ssl.LdapsInitializer;
import org.apache.directory.server.ldap.replication.consumer.ReplicationConsumer;
import org.apache.directory.server.ldap.replication.provider.ReplicationRequestHandler;
import org.apache.directory.server.protocol.shared.DirectoryBackedService;
import org.apache.directory.server.protocol.shared.transport.TcpTransport;
import org.apache.directory.server.protocol.shared.transport.Transport;
import org.apache.directory.server.protocol.shared.transport.UdpTransport;
import org.apache.directory.shared.ldap.codec.api.LdapApiServiceFactory;
import org.apache.directory.shared.ldap.extras.controls.SyncDoneValue;
import org.apache.directory.shared.ldap.extras.controls.SyncInfoValue;
import org.apache.directory.shared.ldap.extras.controls.SyncRequestValue;
import org.apache.directory.shared.ldap.extras.controls.SyncStateValue;
import org.apache.directory.shared.ldap.model.constants.SaslQoP;
import org.apache.directory.shared.ldap.model.exception.LdapConfigurationException;
import org.apache.directory.shared.ldap.model.message.AbandonRequest;
import org.apache.directory.shared.ldap.model.message.AddRequest;
import org.apache.directory.shared.ldap.model.message.BindRequest;
import org.apache.directory.shared.ldap.model.message.CompareRequest;
import org.apache.directory.shared.ldap.model.message.DeleteRequest;
import org.apache.directory.shared.ldap.model.message.ExtendedRequest;
import org.apache.directory.shared.ldap.model.message.ExtendedResponse;
import org.apache.directory.shared.ldap.model.message.ModifyDnRequest;
import org.apache.directory.shared.ldap.model.message.ModifyRequest;
import org.apache.directory.shared.ldap.model.message.SearchRequest;
import org.apache.directory.shared.ldap.model.message.UnbindRequest;
import org.apache.directory.shared.ldap.model.message.controls.Cascade;
import org.apache.directory.shared.ldap.model.message.controls.EntryChange;
import org.apache.directory.shared.ldap.model.message.controls.ManageDsaIT;
import org.apache.directory.shared.ldap.model.message.controls.PagedResults;
import org.apache.directory.shared.ldap.model.message.controls.PersistentSearch;
import org.apache.directory.shared.ldap.model.message.controls.Subentries;
import org.apache.directory.shared.ldap.model.message.extended.NoticeOfDisconnect;
import org.apache.directory.shared.util.Strings;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.filterchain.IoFilterChainBuilder;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IoEventType;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.executor.UnorderedThreadPoolExecutor;
import org.apache.mina.handler.demux.MessageHandler;
import org.apache.mina.transport.socket.AbstractSocketSessionConfig;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * An LDAP protocol provider implementation which dynamically associates
 * handlers.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class LdapServer extends DirectoryBackedService
{
    private static final long serialVersionUID = 3757127143811666817L;

    /** logger for this class */
    private static final Logger LOG = LoggerFactory.getLogger( LdapServer.class.getName() );

    /** Value (0) for configuration where size limit is unlimited. */
    public static final long NO_SIZE_LIMIT = 0;

    /** Value (0) for configuration where time limit is unlimited. */
    public static final int NO_TIME_LIMIT = 0;

    /** the constant service name of this ldap protocol provider **/
    public static final String SERVICE_NAME = "ldap";

    /** The default maximum size limit. */
    private static final long MAX_SIZE_LIMIT_DEFAULT = 100;

    /** The default maximum time limit. */
    private static final int MAX_TIME_LIMIT_DEFAULT = 10000;

    /** The default service pid. */
    private static final String SERVICE_PID_DEFAULT = "org.apache.directory.server.ldap";

    /** The default service name. */
    private static final String SERVICE_NAME_DEFAULT = "ApacheDS LDAP Service";

    /** the session manager for this LdapServer */
    private LdapSessionManager ldapSessionManager = new LdapSessionManager();

    /** a set of supported controls */
    private Set<String> supportedControls;

    /** 
     * The maximum size limit. 
     * @see {@link LdapServer#MAX_SIZE_LIMIT_DEFAULT }
     */
    private long maxSizeLimit = MAX_SIZE_LIMIT_DEFAULT;

    /** 
     * The maximum time limit.
     * @see {@link LdapServer#MAX_TIME_LIMIT_DEFAULT }
     */
    private int maxTimeLimit = MAX_TIME_LIMIT_DEFAULT;

    /** If LDAPS is activated : the external Keystore file, if defined */
    private String keystoreFile;

    /** If LDAPS is activated : the certificate password */
    private String certificatePassword;

    /** The extended operation handlers. */
    private final Collection<ExtendedOperationHandler> extendedOperationHandlers = new ArrayList<ExtendedOperationHandler>();

    /** The supported authentication mechanisms. */
    private Map<String, MechanismHandler> saslMechanismHandlers = new HashMap<String, MechanismHandler>();

    /** The name of this host, validated during SASL negotiation. */
    private String saslHost = "ldap.example.com";

    /** The service principal, used by GSSAPI. */
    private String saslPrincipal = "ldap/ldap.example.com@EXAMPLE.COM";

    /** The quality of protection (QoP), used by DIGEST-MD5 and GSSAPI. */
    private Set<String> saslQop;
    private String saslQopString;

    /** The list of realms serviced by this host. */
    private List<String> saslRealms;

    /** The protocol handlers */
    private LdapRequestHandler<AbandonRequest> abandonHandler;
    private LdapRequestHandler<AddRequest> addHandler;
    private LdapRequestHandler<BindRequest> bindHandler;
    private LdapRequestHandler<CompareRequest> compareHandler;
    private LdapRequestHandler<DeleteRequest> deleteHandler;
    private ExtendedHandler extendedHandler;
    private LdapRequestHandler<ModifyRequest> modifyHandler;
    private LdapRequestHandler<ModifyDnRequest> modifyDnHandler;
    private LdapRequestHandler<SearchRequest> searchHandler;
    private LdapRequestHandler<UnbindRequest> unbindHandler;

    /** the underlying provider codec factory */
    private ProtocolCodecFactory codecFactory = LdapApiServiceFactory.getSingleton().getProtocolCodecFactory();

    /** the MINA protocol handler */
    private final LdapProtocolHandler handler = new LdapProtocolHandler( this );

    /** tracks start state of the server */
    private boolean started;

    /** 
     * Whether or not confidentiality (TLS secured connection) is required: 
     * disabled by default. 
     */
    private boolean confidentialityRequired;

    private KeyStore keyStore = null;

    private List<IoFilterChainBuilder> chainBuilders = new ArrayList<IoFilterChainBuilder>();

    private ReplicationRequestHandler replicationReqHandler;

    private List<ReplicationConsumer> replConsumers;


    /**
     * Creates an LDAP protocol provider.
     */
    public LdapServer()
    {
        super.setEnabled( true );
        super.setServiceId( SERVICE_PID_DEFAULT );
        super.setServiceName( SERVICE_NAME_DEFAULT );

        saslQop = new HashSet<String>();
        saslQop.add( SaslQoP.AUTH.getValue() );
        saslQop.add( SaslQoP.AUTH_INT.getValue() );
        saslQop.add( SaslQoP.AUTH_CONF.getValue() );
        saslQopString = SaslQoP.AUTH.getValue() + ',' + SaslQoP.AUTH_INT.getValue() + ','
            + SaslQoP.AUTH_CONF.getValue();

        saslRealms = new ArrayList<String>();
        saslRealms.add( "example.com" );

        this.supportedControls = new HashSet<String>();
        this.supportedControls.add( PersistentSearch.OID );
        this.supportedControls.add( EntryChange.OID );
        this.supportedControls.add( Subentries.OID );
        this.supportedControls.add( ManageDsaIT.OID );
        this.supportedControls.add( Cascade.OID );
        this.supportedControls.add( PagedResults.OID );
        // Replication controls
        this.supportedControls.add( SyncDoneValue.OID );
        this.supportedControls.add( SyncInfoValue.OID );
        this.supportedControls.add( SyncRequestValue.OID );
        this.supportedControls.add( SyncStateValue.OID );
    }


    /**
     * Install the LDAP request handlers.
     */
    private void installDefaultHandlers()
    {
        if ( getAbandonHandler() == null )
        {
            setAbandonHandler( new AbandonHandler() );
        }

        if ( getAddHandler() == null )
        {
            setAddHandler( new AddHandler() );
        }

        if ( getBindHandler() == null )
        {
            BindHandler handler = new BindHandler();
            handler.setSaslMechanismHandlers( saslMechanismHandlers );
            setBindHandler( handler );
        }

        if ( getCompareHandler() == null )
        {
            setCompareHandler( new CompareHandler() );
        }

        if ( getDeleteHandler() == null )
        {
            setDeleteHandler( new DeleteHandler() );
        }

        if ( getExtendedHandler() == null )
        {
            setExtendedHandler( new ExtendedHandler() );
        }

        if ( getModifyHandler() == null )
        {
            setModifyHandler( new ModifyHandler() );
        }

        if ( getModifyDnHandler() == null )
        {
            setModifyDnHandler( new ModifyDnHandler() );
        }

        if ( getSearchHandler() == null )
        {
            setSearchHandler( new SearchHandler() );
        }

        if ( getUnbindHandler() == null )
        {
            setUnbindHandler( new UnbindHandler() );
        }
    }

    private static class AdsKeyStore extends KeyStore
    {
        public AdsKeyStore( KeyStoreSpi keyStoreSpi, Provider provider, String type )
        {
            super( keyStoreSpi, provider, type );
        }
    }


    /**
     * loads the digital certificate either from a keystore file or from the admin entry in DIT
     */
    // This will suppress PMD.EmptyCatchBlock warnings in this method
    @SuppressWarnings("PMD.EmptyCatchBlock")
    private void loadKeyStore() throws Exception
    {
        if ( Strings.isEmpty( keystoreFile ) )
        {
            Provider provider = Security.getProvider( "SUN" );
            LOG.debug( "provider = {}", provider );
            CoreKeyStoreSpi coreKeyStoreSpi = new CoreKeyStoreSpi( getDirectoryService() );
            keyStore = new KeyStore( coreKeyStoreSpi, provider, "JKS" )
            {
            };

            try
            {
                keyStore.load( null, null );
            }
            catch ( Exception e )
            {
                // nothing really happens with this keystore
            }
        }
        else
        {
            keyStore = KeyStore.getInstance( KeyStore.getDefaultType() );
            FileInputStream fis = null;
            try
            {
                fis = new FileInputStream( keystoreFile );
                keyStore.load( fis, null );
            }
            finally
            {
                if ( fis != null )
                {
                    fis.close();
                }
            }
        }
    }


    /**
     * reloads the SSL context by replacing the existing SslFilter
     * with a new SslFilter after reloading the keystore.
     * 
     * Note: should be called to reload the keystore after changing the digital certificate.
     */
    public void reloadSslContext() throws Exception
    {
        if ( !started )
        {
            return;
        }

        LOG.info( "reloading SSL context..." );

        loadKeyStore();

        String sslFilterName = "sslFilter";
        for ( IoFilterChainBuilder chainBuilder : chainBuilders )
        {
            DefaultIoFilterChainBuilder dfcb = ( ( DefaultIoFilterChainBuilder ) chainBuilder );
            if ( dfcb.contains( sslFilterName ) )
            {
                DefaultIoFilterChainBuilder newChain = ( DefaultIoFilterChainBuilder ) LdapsInitializer.init( keyStore,
                    certificatePassword );
                dfcb.replace( sslFilterName, newChain.get( sslFilterName ) );
                newChain = null;
            }
        }

        StartTlsHandler handler = ( StartTlsHandler ) getExtendedOperationHandler( StartTlsHandler.EXTENSION_OID );
        if ( handler != null )
        {
            //FIXME dirty hack. IMO StartTlsHandler's code requires a cleanup
            // cause the keystore loading and sslcontext creation code is duplicated
            // both in the LdapService as well as StatTlsHandler
            handler.setLdapServer( this );
        }

        LOG.info( "reloaded SSL context successfully" );
    }


    /**
     * @throws IOException if we cannot bind to the specified port
     * @throws Exception if the LDAP server cannot be started
     */
    public void start() throws Exception
    {
        if ( !isEnabled() )
        {
            return;
        }

        for ( Transport transport : transports )
        {
            if ( !( transport instanceof TcpTransport ) )
            {
                LOG.warn( "Cannot listen on an UDP transport : {}", transport );
                continue;
            }

            IoFilterChainBuilder chain;

            if ( transport.isSSLEnabled() )
            {
                loadKeyStore();
                chain = LdapsInitializer.init( keyStore, certificatePassword );
            }
            else
            {
                chain = new DefaultIoFilterChainBuilder();
            }

            // Inject the codec into the chain
            ( ( DefaultIoFilterChainBuilder ) chain ).addLast( "codec", new ProtocolCodecFilter( this
                .getProtocolCodecFactory() ) );

            // Now inject an ExecutorFilter for the write operations
            // We use the same number of thread than the number of IoProcessor
            // (NOTE : this has to be double checked)
            ( ( DefaultIoFilterChainBuilder ) chain ).addLast( "executor", new ExecutorFilter(
                new UnorderedThreadPoolExecutor( transport.getNbThreads() ), IoEventType.MESSAGE_RECEIVED ) );

            /*
            // Trace all the incoming and outgoing message to the console
            ( ( DefaultIoFilterChainBuilder ) chain ).addLast( "logger", new IoFilterAdapter()
                {
                    public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception 
                    {
                        System.out.println( ">>> Message received : " + message );
                        nextFilter.messageReceived(session, message);
                    }

                    public void filterWrite(NextFilter nextFilter, IoSession session,
                            WriteRequest writeRequest) throws Exception 
                    {
                        System.out.println( "<<< Message sent : " + writeRequest.getMessage() );
                        nextFilter.filterWrite(session, writeRequest);
                    }
                });
            */

            startNetwork( transport, chain );
        }

        /*
         * The server is now initialized, we can
         * install the default requests handlers, which need 
         * access to the DirectoryServer instance.
         */
        installDefaultHandlers();

        PartitionNexus nexus = getDirectoryService().getPartitionNexus();

        for ( ExtendedOperationHandler h : extendedOperationHandlers )
        {
            LOG.info( "Added Extended Request Handler: " + h.getOid() );
            h.setLdapServer( this );
            nexus.registerSupportedExtensions( h.getExtensionOids() );
        }

        nexus.registerSupportedSaslMechanisms( saslMechanismHandlers.keySet() );

        // Install the replication handler if we have one
        startReplicationProducer();

        // And start the replication consumers on this server
        startReplicationConsumers();

        started = true;

        LOG.info( "Ldap service started." );
    }


    /**
     * Install the replication handler if we have one
     */
    public void startReplicationProducer()
    {
        if ( replicationReqHandler != null )
        {
            replicationReqHandler.start( this );
            ( ( SearchHandler ) getSearchHandler() ).setReplicationReqHandler( replicationReqHandler );
        }
    }


    /**
     * {@inheritDoc}
     */
    public void stop()
    {
        try
        {
            for ( Transport transport : transports )
            {
                if ( !( transport instanceof TcpTransport ) )
                {
                    continue;
                }

                // we should unbind the service before we begin sending the notice
                // of disconnect so new connections are not formed while we process
                List<WriteFuture> writeFutures = new ArrayList<WriteFuture>();

                // If the socket has already been unbound as with a successful
                // GracefulShutdownRequest then this will complain that the service
                // is not bound - this is ok because the GracefulShutdown has already
                // sent notices to to the existing active sessions
                List<IoSession> sessions;

                try
                {
                    sessions = new ArrayList<IoSession>( getSocketAcceptor( transport ).getManagedSessions().values() );
                }
                catch ( IllegalArgumentException e )
                {
                    LOG.warn( "Seems like the LDAP service (" + getPort() + ") has already been unbound." );
                    return;
                }

                getSocketAcceptor( transport ).dispose();

                if ( LOG.isInfoEnabled() )
                {
                    LOG.info( "Unbind of an LDAP service (" + getPort() + ") is complete." );
                    LOG.info( "Sending notice of disconnect to existing clients sessions." );
                }

                // Send Notification of Disconnection messages to all connected clients.
                if ( sessions != null )
                {
                    for ( IoSession session : sessions )
                    {
                        writeFutures.add( session.write( NoticeOfDisconnect.UNAVAILABLE ) );
                    }
                }

                // And close the connections when the NoDs are sent.
                Iterator<IoSession> sessionIt = sessions.iterator();

                for ( WriteFuture future : writeFutures )
                {
                    future.await( 1000L );
                    sessionIt.next().close( true );
                }

                if ( replicationReqHandler != null )
                {
                    replicationReqHandler.stop();
                }
            }

            stopConsumers();
        }
        catch ( Exception e )
        {
            LOG.warn( "Failed to sent NoD.", e );
        }

        started = false;
        LOG.info( "Ldap service stopped." );
    }


    private void startNetwork( Transport transport, IoFilterChainBuilder chainBuilder ) throws Exception
    {
        if ( transport.getBackLog() < 0 )
        {
            // Set the backlog to the default value when it's below 0
            transport.setBackLog( 50 );
        }

        chainBuilders.add( chainBuilder );

        try
        {
            SocketAcceptor acceptor = getSocketAcceptor( transport );

            // Now, configure the acceptor
            // Disable the disconnection of the clients on unbind
            acceptor.setCloseOnDeactivation( false );

            // No Nagle's algorithm
            acceptor.getSessionConfig().setTcpNoDelay( true );

            // Inject the chain
            acceptor.setFilterChainBuilder( chainBuilder );

            // Inject the protocol handler
            acceptor.setHandler( getHandler() );

            ( ( AbstractSocketSessionConfig ) acceptor.getSessionConfig() ).setReadBufferSize( 64 * 1024 );
            ( ( AbstractSocketSessionConfig ) acceptor.getSessionConfig() ).setSendBufferSize( 64 * 1024 );

            // Bind to the configured address
            acceptor.bind();

            // We are done !
            started = true;

            if ( LOG.isInfoEnabled() )
            {
                LOG.info( "Successful bind of an LDAP Service (" + transport.getPort() + ") is completed." );
            }
        }
        catch ( IOException e )
        {
            String msg = I18n.err( I18n.ERR_171, transport.getPort() );
            LdapConfigurationException lce = new LdapConfigurationException( msg );
            lce.setCause( e );
            LOG.error( msg, e );
            throw lce;
        }
    }


    /**
     * starts the replication consumers
     */
    public void startReplicationConsumers() throws Exception
    {
        if ( replConsumers != null )
        {
            for ( final ReplicationConsumer consumer : replConsumers )
            {
                Runnable consumerTask = new Runnable()
                {
                    public void run()
                    {
                        try
                        {
                            LOG.info( "starting the replication consumer with config {}", consumer );
                            consumer.init( getDirectoryService() );
                            consumer.start();
                        }
                        catch ( Exception e )
                        {
                            LOG.error( "Failed to start the consumer with config {}", consumer );
                            throw new RuntimeException( e );
                        }
                    }
                };

                Thread consumerThread = new Thread( consumerTask );
                consumerThread.setDaemon( true );
                consumerThread.start();
            }
        }
    }


    /**
     * stops the replication consumers
     */
    private void stopConsumers()
    {
        if ( replConsumers != null )
        {
            for ( ReplicationConsumer consumer : replConsumers )
            {
                LOG.info( "stopping the consumer with id {}", consumer.getId() );
                consumer.stop();
            }
        }
    }


    public String getName()
    {
        return SERVICE_NAME;
    }


    public IoHandler getHandler()
    {
        return handler;
    }


    public LdapSessionManager getLdapSessionManager()
    {
        return ldapSessionManager;
    }


    public ProtocolCodecFactory getProtocolCodecFactory()
    {
        return codecFactory;
    }


    // ------------------------------------------------------------------------
    // Configuration Methods
    // ------------------------------------------------------------------------

    /**
     * Registers the specified {@link ExtendedOperationHandler} to this
     * protocol provider to provide a specific LDAP extended operation.
     *
     * @param eoh an extended operation handler
     * @throws Exception on failure to add the handler
     */
    public void addExtendedOperationHandler( ExtendedOperationHandler eoh ) throws Exception
    {
        if ( started )
        {
            eoh.setLdapServer( this );
            PartitionNexus nexus = getDirectoryService().getPartitionNexus();
            nexus.registerSupportedExtensions( eoh.getExtensionOids() );
        }
        else
        {
            extendedOperationHandlers.add( eoh );
        }
    }


    /**
     * Deregisteres an {@link ExtendedOperationHandler} with the specified <tt>oid</tt>
     * from this protocol provider.
     *
     * @param oid the numeric identifier for the extended operation associated with
     * the handler to remove
     */
    public void removeExtendedOperationHandler( String oid )
    {
        // need to do something like this to make this work right
        //            DefaultPartitionNexus nexus = getDirectoryService().getPartitionNexus();
        //            nexus.unregisterSupportedExtensions( eoh.getExtensionOids() );

        ExtendedOperationHandler handler = null;
        for ( ExtendedOperationHandler h : extendedOperationHandlers )
        {
            if ( h.getOid().equals( oid ) )
            {
                handler = h;
                break;
            }
        }
        extendedOperationHandlers.remove( handler );
    }


    /**
     * Returns an {@link ExtendedOperationHandler} with the specified <tt>oid</tt>
     * which is registered to this protocol provider.
     *
     * @param oid the oid of the extended request of associated with the extended
     * request handler
     * @return the exnteded operation handler
     */
    public ExtendedOperationHandler<ExtendedRequest<ExtendedResponse>, ExtendedResponse>
        getExtendedOperationHandler( String oid )
    {
        for ( ExtendedOperationHandler<ExtendedRequest<ExtendedResponse>, ExtendedResponse> h : extendedOperationHandlers )
        {
            if ( h.getOid().equals( oid ) )
            {
                return h;
            }
        }

        return null;
    }


    /**
     * Sets the mode for this LdapServer to accept requests with or without a
     * TLS secured connection via either StartTLS extended operations or using
     * LDAPS.
     * 
     * @param confidentialityRequired true to require confidentiality
     */
    public void setConfidentialityRequired( boolean confidentialityRequired )
    {
        this.confidentialityRequired = confidentialityRequired;
    }


    /**
     * Gets whether or not TLS secured connections are required to perform 
     * operations on this LdapServer.
     * 
     * @return true if TLS secured connections are required, false otherwise
     */
    public boolean isConfidentialityRequired()
    {
        return confidentialityRequired;
    }


    /**
     * Returns <tt>true</tt> if LDAPS is enabled.
     *
     * @return True if LDAPS is enabled.
     */
    public boolean isEnableLdaps( Transport transport )
    {
        return transport.isSSLEnabled();
    }


    /**
     * Sets the maximum size limit in number of entries to return for search.
     *
     * @param maxSizeLimit the maximum number of entries to return for search
     */
    public void setMaxSizeLimit( long maxSizeLimit )
    {
        this.maxSizeLimit = maxSizeLimit;
    }


    /**
     * Returns the maximum size limit in number of entries to return for search.
     *
     * @return The maximum size limit.
     */
    public long getMaxSizeLimit()
    {
        return maxSizeLimit;
    }


    /**
     * Sets the maximum time limit in milliseconds to conduct a search.
     *
     * @param maxTimeLimit the maximum length of time in milliseconds for search
     */
    public void setMaxTimeLimit( int maxTimeLimit )
    {
        this.maxTimeLimit = maxTimeLimit;
    }


    /**
     * Returns the maximum time limit in milliseconds to conduct a search.
     *
     * @return The maximum time limit in milliseconds for search
     */
    public int getMaxTimeLimit()
    {
        return maxTimeLimit;
    }


    /**
     * Gets the {@link ExtendedOperationHandler}s.
     *
     * @return A collection of {@link ExtendedOperationHandler}s.
     */
    public Collection<ExtendedOperationHandler> getExtendedOperationHandlers()
    {
        return new ArrayList<ExtendedOperationHandler>( extendedOperationHandlers );
    }


    /**
     * Sets the {@link ExtendedOperationHandler}s.
     *
     * @param handlers A collection of {@link ExtendedOperationHandler}s.
     */
    public void setExtendedOperationHandlers( Collection<ExtendedOperationHandler> handlers )
    {
        this.extendedOperationHandlers.clear();
        this.extendedOperationHandlers.addAll( handlers );
    }


    /**
     * Returns the FQDN of this SASL host, validated during SASL negotiation.
     *
     * @return The FQDN of this SASL host, validated during SASL negotiation.
     */
    public String getSaslHost()
    {
        return saslHost;
    }


    /**
     * Sets the FQDN of this SASL host, validated during SASL negotiation.
     *
     * @param saslHost The FQDN of this SASL host, validated during SASL negotiation.
     */
    public void setSaslHost( String saslHost )
    {
        this.saslHost = saslHost;
    }


    /**
     * Returns the Kerberos principal name for this LDAP service, used by GSSAPI.
     *
     * @return The Kerberos principal name for this LDAP service, used by GSSAPI.
     */
    public String getSaslPrincipal()
    {
        return saslPrincipal;
    }


    /**
     * Sets the Kerberos principal name for this LDAP service, used by GSSAPI.
     *
     * @param saslPrincipal The Kerberos principal name for this LDAP service, used by GSSAPI.
     */
    public void setSaslPrincipal( String saslPrincipal )
    {
        this.saslPrincipal = saslPrincipal;
    }


    /**
     * Returns the quality-of-protection, used by DIGEST-MD5 and GSSAPI.
     *
     * @return The quality-of-protection, used by DIGEST-MD5 and GSSAPI.
     */
    public String getSaslQopString()
    {
        return saslQopString;
    }


    /**
     * Returns the Set of quality-of-protection, used by DIGEST-MD5 and GSSAPI.
     *
     * @return The quality-of-protection, used by DIGEST-MD5 and GSSAPI.
     */
    public Set<String> getSaslQop()
    {
        return saslQop;
    }


    /**
     * Returns the realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI.
     *
     * @return The realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI.
     */
    public List<String> getSaslRealms()
    {
        return saslRealms;
    }


    /**
     * Sets the realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI.
     *
    * @param saslRealms The realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI.
     */
    public void setSaslRealms( List<String> saslRealms )
    {
        this.saslRealms = saslRealms;
    }


    /**
     */
    public Map<String, MechanismHandler> getSaslMechanismHandlers()
    {
        return saslMechanismHandlers;
    }


    public void setSaslMechanismHandlers( Map<String, MechanismHandler> saslMechanismHandlers )
    {
        this.saslMechanismHandlers = saslMechanismHandlers;
    }


    public MechanismHandler addSaslMechanismHandler( String mechanism, MechanismHandler handler )
    {
        return this.saslMechanismHandlers.put( mechanism, handler );
    }


    public MechanismHandler removeSaslMechanismHandler( String mechanism )
    {
        return this.saslMechanismHandlers.remove( mechanism );
    }


    public MechanismHandler getMechanismHandler( String mechanism )
    {
        return this.saslMechanismHandlers.get( mechanism );
    }


    public Set<String> getSupportedMechanisms()
    {
        return saslMechanismHandlers.keySet();
    }


    public void setDirectoryService( DirectoryService directoryService )
    {
        super.setDirectoryService( directoryService );
    }


    public Set<String> getSupportedControls()
    {
        return supportedControls;
    }


    /**
     */
    public void setSupportedControls( Set<String> supportedControls )
    {
        this.supportedControls = supportedControls;
    }


    public MessageHandler<AbandonRequest> getAbandonHandler()
    {
        return abandonHandler;
    }


    /**
     * @param abandonHandler The AbandonRequest handler
     */
    public void setAbandonHandler( LdapRequestHandler<AbandonRequest> abandonHandler )
    {
        this.handler.removeReceivedMessageHandler( AbandonRequest.class );
        this.abandonHandler = abandonHandler;
        this.abandonHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( AbandonRequest.class, this.abandonHandler );
    }


    public LdapRequestHandler<AddRequest> getAddHandler()
    {
        return addHandler;
    }


    /**
     * @param addHandler The AddRequest handler
     */
    public void setAddHandler( LdapRequestHandler<AddRequest> addHandler )
    {
        this.handler.removeReceivedMessageHandler( AddRequest.class );
        this.addHandler = addHandler;
        this.addHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( AddRequest.class, this.addHandler );
    }


    public LdapRequestHandler<BindRequest> getBindHandler()
    {
        return bindHandler;
    }


    /**
     * @param bindHandler The BindRequest handler
     */
    public void setBindHandler( LdapRequestHandler<BindRequest> bindHandler )
    {
        this.bindHandler = bindHandler;
        this.bindHandler.setLdapServer( this );

        handler.removeReceivedMessageHandler( BindRequest.class );
        handler.addReceivedMessageHandler( BindRequest.class, this.bindHandler );
    }


    public LdapRequestHandler<CompareRequest> getCompareHandler()
    {
        return compareHandler;
    }


    /**
     * @param compareHandler The CompareRequest handler
     */
    public void setCompareHandler( LdapRequestHandler<CompareRequest> compareHandler )
    {
        this.handler.removeReceivedMessageHandler( CompareRequest.class );
        this.compareHandler = compareHandler;
        this.compareHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( CompareRequest.class, this.compareHandler );
    }


    public LdapRequestHandler<DeleteRequest> getDeleteHandler()
    {
        return deleteHandler;
    }


    /**
     * @param deleteHandler The DeleteRequest handler
     */
    public void setDeleteHandler( LdapRequestHandler<DeleteRequest> deleteHandler )
    {
        this.handler.removeReceivedMessageHandler( DeleteRequest.class );
        this.deleteHandler = deleteHandler;
        this.deleteHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( DeleteRequest.class, this.deleteHandler );
    }


    public LdapRequestHandler<ExtendedRequest<ExtendedResponse>> getExtendedHandler()
    {
        return extendedHandler;
    }


    /**
     * @param extendedHandler The ExtendedRequest handler
     */
    @SuppressWarnings(
        { "unchecked", "rawtypes" })
    public void setExtendedHandler( ExtendedHandler extendedHandler )
    {
        this.handler.removeReceivedMessageHandler( ExtendedRequest.class );
        this.extendedHandler = extendedHandler;
        this.extendedHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( ExtendedRequest.class, ( LdapRequestHandler ) this.extendedHandler );
    }


    public LdapRequestHandler<ModifyRequest> getModifyHandler()
    {
        return modifyHandler;
    }


    /**
     * @param modifyHandler The ModifyRequest handler
     */
    public void setModifyHandler( LdapRequestHandler<ModifyRequest> modifyHandler )
    {
        this.handler.removeReceivedMessageHandler( ModifyRequest.class );
        this.modifyHandler = modifyHandler;
        this.modifyHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( ModifyRequest.class, this.modifyHandler );
    }


    public LdapRequestHandler<ModifyDnRequest> getModifyDnHandler()
    {
        return modifyDnHandler;
    }


    /**
     * @param modifyDnHandler The ModifyDNRequest handler
     */
    public void setModifyDnHandler( LdapRequestHandler<ModifyDnRequest> modifyDnHandler )
    {
        this.handler.removeReceivedMessageHandler( ModifyDnRequest.class );
        this.modifyDnHandler = modifyDnHandler;
        this.modifyDnHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( ModifyDnRequest.class, this.modifyDnHandler );
    }


    public LdapRequestHandler<SearchRequest> getSearchHandler()
    {
        return searchHandler;
    }


    /**
     * @param searchHandler The SearchRequest handler
     */
    public void setSearchHandler( LdapRequestHandler<SearchRequest> searchHandler )
    {
        this.handler.removeReceivedMessageHandler( SearchRequest.class );
        this.searchHandler = searchHandler;
        this.searchHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( SearchRequest.class, this.searchHandler );
    }


    public LdapRequestHandler<UnbindRequest> getUnbindHandler()
    {
        return unbindHandler;
    }


    /**
     * @return The underlying TCP transport port, or -1 if no transport has been 
     * initialized
     */
    public int getPort()
    {
        if ( transports == null )
        {
            return -1;
        }

        for ( Transport transport : transports )
        {
            if ( transport instanceof UdpTransport )
            {
                continue;
            }

            if ( !transport.isSSLEnabled() )
            {
                return transport.getPort();
            }
        }

        return -1;
    }


    /**
     * @return The underlying SSL enabled TCP transport port, or -1 if no transport has been 
     * initialized
     */
    public int getPortSSL()
    {
        if ( transports == null )
        {
            return -1;
        }

        for ( Transport transport : transports )
        {
            if ( transport instanceof UdpTransport )
            {
                continue;
            }

            if ( transport.isSSLEnabled() )
            {
                return transport.getPort();
            }
        }

        return -1;
    }


    /**
     * @param unbindHandler The UnbindRequest handler
     */
    public void setUnbindHandler( LdapRequestHandler<UnbindRequest> unbindHandler )
    {
        this.handler.removeReceivedMessageHandler( UnbindRequest.class );
        this.unbindHandler = unbindHandler;
        this.unbindHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( UnbindRequest.class, this.unbindHandler );
    }


    public boolean isStarted()
    {
        return started;
    }


    /**
     */
    public void setStarted( boolean started )
    {
        this.started = started;
    }


    /**
     * @return The keystore path
     */
    public String getKeystoreFile()
    {
        return keystoreFile;
    }


    /**
     * Set the external keystore path
     * @param keystoreFile The external keystore path
     */
    public void setKeystoreFile( String keystoreFile )
    {
        this.keystoreFile = keystoreFile;
    }


    /**
     * @return The certificate passord
     */
    public String getCertificatePassword()
    {
        return certificatePassword;
    }


    /**
     * Set the certificate passord.
     * @param certificatePassword the certificate passord
     */
    public void setCertificatePassword( String certificatePassword )
    {
        this.certificatePassword = certificatePassword;
    }


    public void setReplicationReqHandler( ReplicationRequestHandler replicationProvider )
    {
        this.replicationReqHandler = replicationProvider;
    }


    public void setReplConsumers( List<ReplicationConsumer> replConsumers )
    {
        this.replConsumers = replConsumers;
    }


    /**
     * @see Object#toString()
     */
    public String toString()
    {
        StringBuilder sb = new StringBuilder();

        sb.append( "LdapServer[" ).append( getServiceName() ).append( "], listening on :" ).append( '\n' );

        if ( getTransports() != null )
        {
            for ( Transport transport : getTransports() )
            {
                sb.append( "    " ).append( transport ).append( '\n' );
            }
        }

        return sb.toString();
    }
}
