/*
 *  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.shared.ldap.client.api;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

import javax.naming.InvalidNameException;
import javax.naming.ldap.BasicControl;
import javax.naming.ldap.Control;
import javax.net.ssl.SSLContext;

import org.apache.directory.shared.asn1.ber.IAsn1Container;
import org.apache.directory.shared.asn1.codec.DecoderException;
import org.apache.directory.shared.asn1.primitives.OID;
import org.apache.directory.shared.ldap.client.api.exception.InvalidConnectionException;
import org.apache.directory.shared.ldap.client.api.exception.LdapException;
import org.apache.directory.shared.ldap.client.api.listeners.AddListener;
import org.apache.directory.shared.ldap.client.api.listeners.BindListener;
import org.apache.directory.shared.ldap.client.api.listeners.CompareListener;
import org.apache.directory.shared.ldap.client.api.listeners.DeleteListener;
import org.apache.directory.shared.ldap.client.api.listeners.ExtendedListener;
import org.apache.directory.shared.ldap.client.api.listeners.IntermediateResponseListener;
import org.apache.directory.shared.ldap.client.api.listeners.ModifyDnListener;
import org.apache.directory.shared.ldap.client.api.listeners.ModifyListener;
import org.apache.directory.shared.ldap.client.api.listeners.OperationResponseListener;
import org.apache.directory.shared.ldap.client.api.listeners.SearchListener;
import org.apache.directory.shared.ldap.client.api.messages.AbandonRequest;
import org.apache.directory.shared.ldap.client.api.messages.AddRequest;
import org.apache.directory.shared.ldap.client.api.messages.AddResponse;
import org.apache.directory.shared.ldap.client.api.messages.BindRequest;
import org.apache.directory.shared.ldap.client.api.messages.BindResponse;
import org.apache.directory.shared.ldap.client.api.messages.CompareRequest;
import org.apache.directory.shared.ldap.client.api.messages.CompareResponse;
import org.apache.directory.shared.ldap.client.api.messages.DeleteRequest;
import org.apache.directory.shared.ldap.client.api.messages.DeleteResponse;
import org.apache.directory.shared.ldap.client.api.messages.ExtendedRequest;
import org.apache.directory.shared.ldap.client.api.messages.ExtendedResponse;
import org.apache.directory.shared.ldap.client.api.messages.IntermediateResponse;
import org.apache.directory.shared.ldap.client.api.messages.LdapResult;
import org.apache.directory.shared.ldap.client.api.messages.ModifyDnRequest;
import org.apache.directory.shared.ldap.client.api.messages.ModifyDnResponse;
import org.apache.directory.shared.ldap.client.api.messages.ModifyRequest;
import org.apache.directory.shared.ldap.client.api.messages.ModifyResponse;
import org.apache.directory.shared.ldap.client.api.messages.Referral;
import org.apache.directory.shared.ldap.client.api.messages.SearchRequest;
import org.apache.directory.shared.ldap.client.api.messages.SearchResponse;
import org.apache.directory.shared.ldap.client.api.messages.SearchResultDone;
import org.apache.directory.shared.ldap.client.api.messages.SearchResultEntry;
import org.apache.directory.shared.ldap.client.api.messages.SearchResultReference;
import org.apache.directory.shared.ldap.client.api.messages.future.ResponseFuture;
import org.apache.directory.shared.ldap.client.api.protocol.LdapProtocolCodecFactory;
import org.apache.directory.shared.ldap.codec.ControlCodec;
import org.apache.directory.shared.ldap.codec.LdapConstants;
import org.apache.directory.shared.ldap.codec.LdapMessageCodec;
import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
import org.apache.directory.shared.ldap.codec.LdapResultCodec;
import org.apache.directory.shared.ldap.codec.TwixTransformer;
import org.apache.directory.shared.ldap.codec.abandon.AbandonRequestCodec;
import org.apache.directory.shared.ldap.codec.add.AddRequestCodec;
import org.apache.directory.shared.ldap.codec.add.AddResponseCodec;
import org.apache.directory.shared.ldap.codec.bind.BindRequestCodec;
import org.apache.directory.shared.ldap.codec.bind.BindResponseCodec;
import org.apache.directory.shared.ldap.codec.bind.LdapAuthentication;
import org.apache.directory.shared.ldap.codec.bind.SaslCredentials;
import org.apache.directory.shared.ldap.codec.bind.SimpleAuthentication;
import org.apache.directory.shared.ldap.codec.compare.CompareRequestCodec;
import org.apache.directory.shared.ldap.codec.compare.CompareResponseCodec;
import org.apache.directory.shared.ldap.codec.del.DelRequestCodec;
import org.apache.directory.shared.ldap.codec.del.DelResponseCodec;
import org.apache.directory.shared.ldap.codec.extended.ExtendedRequestCodec;
import org.apache.directory.shared.ldap.codec.extended.ExtendedResponseCodec;
import org.apache.directory.shared.ldap.codec.intermediate.IntermediateResponseCodec;
import org.apache.directory.shared.ldap.codec.modify.ModifyRequestCodec;
import org.apache.directory.shared.ldap.codec.modify.ModifyResponseCodec;
import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNRequestCodec;
import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNResponseCodec;
import org.apache.directory.shared.ldap.codec.search.Filter;
import org.apache.directory.shared.ldap.codec.search.SearchRequestCodec;
import org.apache.directory.shared.ldap.codec.search.SearchResultDoneCodec;
import org.apache.directory.shared.ldap.codec.search.SearchResultEntryCodec;
import org.apache.directory.shared.ldap.codec.search.SearchResultReferenceCodec;
import org.apache.directory.shared.ldap.codec.unbind.UnBindRequestCodec;
import org.apache.directory.shared.ldap.constants.SchemaConstants;
import org.apache.directory.shared.ldap.cursor.Cursor;
import org.apache.directory.shared.ldap.cursor.ListCursor;
import org.apache.directory.shared.ldap.entry.Entry;
import org.apache.directory.shared.ldap.entry.EntryAttribute;
import org.apache.directory.shared.ldap.entry.ModificationOperation;
import org.apache.directory.shared.ldap.entry.Value;
import org.apache.directory.shared.ldap.filter.ExprNode;
import org.apache.directory.shared.ldap.filter.FilterParser;
import org.apache.directory.shared.ldap.filter.SearchScope;
import org.apache.directory.shared.ldap.message.AliasDerefMode;
import org.apache.directory.shared.ldap.message.ResultCodeEnum;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.directory.shared.ldap.name.Rdn;
import org.apache.directory.shared.ldap.util.LdapURL;
import org.apache.directory.shared.ldap.util.StringTools;
import org.apache.mina.core.filterchain.IoFilter;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoEventType;
import org.apache.mina.core.session.IoSession;
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.filter.ssl.SslFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 *  Describe the methods to be implemented by the LdapConnection class.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$, $Date$
 */
public class LdapConnection  extends IoHandlerAdapter
{

    /** logger for reporting errors that might not be handled properly upstream */
    private static final Logger LOG = LoggerFactory.getLogger( LdapConnection.class );

    private static final String LDAP_RESPONSE = "LdapReponse";
    
    /** The timeout used for response we are waiting for */ 
    private long timeOut = LdapConnectionConfig.DEFAULT_TIMEOUT;
    
    /** configuration object for the connection */
    private LdapConnectionConfig config = new LdapConnectionConfig();
    
    /** The connector open with the remote server */
    private IoConnector connector;
    
    /** A flag set to true when we used a local connector */ 
    private boolean localConnector;
    
    /** The Ldap codec */
    private IoFilter ldapProtocolFilter = new ProtocolCodecFilter(
            new LdapProtocolCodecFactory() );

    /**  
     * The created session, created when we open a connection with
     * the Ldap server.
     */
    private IoSession ldapSession;
    
    /** A Message ID which is incremented for each operation */
    private AtomicInteger messageId;
    
    /** A queue used to store the incoming add responses */
    private BlockingQueue<AddResponse> addResponseQueue;
    
    /** A queue used to store the incoming bind responses */
    private BlockingQueue<BindResponse> bindResponseQueue;
    
    /** A queue used to store the incoming compare responses */
    private BlockingQueue<CompareResponse> compareResponseQueue;
    
    /** A queue used to store the incoming delete responses */
    private BlockingQueue<DeleteResponse> deleteResponseQueue;
    
    /** A queue used to store the incoming extended responses */
    private BlockingQueue<ExtendedResponse> extendedResponseQueue;
    
    /** A queue used to store the incoming modify responses */
    private BlockingQueue<ModifyResponse> modifyResponseQueue;
    
    /** A queue used to store the incoming modifyDN responses */
    private BlockingQueue<ModifyDnResponse> modifyDNResponseQueue;
    
    /** A queue used to store the incoming search responses */
    private BlockingQueue<SearchResponse> searchResponseQueue;
    
    /** A queue used to store the incoming intermediate responses */
    private BlockingQueue<IntermediateResponse> intermediateResponseQueue;

    /** a map to hold the response listeners based on the operation id */
    private Map<Integer, OperationResponseListener> listenerMap = new ConcurrentHashMap<Integer, OperationResponseListener>();
    
    /** a map to hold the ResponseFutures for all operations */
    private Map<Integer, ResponseFuture> futureMap = new ConcurrentHashMap<Integer, ResponseFuture>();
    
    /** list of controls supported by the server */
    private List<String> supportedControls;

    private Entry rootDSE;


    // ~~~~~~~~~~~~~~~~~ common error messages ~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    private static final String OPERATION_CANCELLED = "Operation would have been cancelled";

    private static final String TIME_OUT_ERROR = "TimeOut occured";

    private static final String NO_RESPONSE_ERROR = "The response queue has been emptied, no response was found.";

    private static final String COMPARE_FAILED = "Failed to perform compare operation";
    
    
    //--------------------------- Helper methods ---------------------------//
    /**
     * Check if the connection is valid : created and connected
     *
     * @return <code>true</code> if the session is valid.
     */
    public boolean isSessionValid()
    {
        return ( ldapSession != null ) && ldapSession.isConnected();
    }

    
    /**
     * Check that a session is valid, ie we can send requests to the
     * server
     *
     * @throws Exception If the session is not valid
     */
    private void checkSession() throws InvalidConnectionException
    {
        if ( ldapSession == null )
        {
            throw new InvalidConnectionException( "Cannot connect on the server, the connection is null" );
        }
        
        if ( !isSessionValid() )
        {
            throw new InvalidConnectionException( "Cannot connect on the server, the connection is invalid" );
        }
    }
    
    /**
     * Return the response stored into the current session.
     *
     * @return The last request response
     */
    public LdapMessageCodec getResponse()
    {
        return (LdapMessageCodec)ldapSession.getAttribute( LDAP_RESPONSE );
    }

    
    /**
     * Inject the client Controls into the message
     */
    private void setControls( Map<String, Control> controls, LdapMessageCodec message )
    {
        // Add the controls
        if ( controls != null )
        {
            for ( Control control:controls.values() )
            {
                ControlCodec ctrl = new ControlCodec();
                
                ctrl.setControlType( control.getID() );
                ctrl.setControlValue( control.getEncodedValue() );
                
                message.addControl( ctrl );
            }
        }
    }
    
    
    /**
     * Get the smallest timeout from the client timeout and the connection
     * timeout.
     */
    private long getTimeout( long clientTimeOut )
    {
        if ( clientTimeOut <= 0 )
        {
            return ( timeOut <= 0 ) ? Long.MAX_VALUE : timeOut;
        }
        else if ( timeOut <= 0 )
        {
            return clientTimeOut;
        }
        else
        {
            return timeOut < clientTimeOut ? timeOut : clientTimeOut; 
        }
    }
    
    
    /**
     * Convert a BindResponseCodec to a BindResponse message
     */
    private BindResponse convert( BindResponseCodec bindResponseCodec )
    {
        BindResponse bindResponse = new BindResponse();
        
        bindResponse.setMessageId( bindResponseCodec.getMessageId() );
        bindResponse.setServerSaslCreds( bindResponseCodec.getServerSaslCreds() );
        bindResponse.setLdapResult( convert( bindResponseCodec.getLdapResult() ) );

        return bindResponse;
    }


    /**
     * Convert a IntermediateResponseCodec to a IntermediateResponse message
     */
    private IntermediateResponse convert( IntermediateResponseCodec intermediateResponseCodec )
    {
        IntermediateResponse intermediateResponse = new IntermediateResponse();
        
        intermediateResponse.setMessageId( intermediateResponseCodec.getMessageId() );
        intermediateResponse.setResponseName( intermediateResponseCodec.getResponseName() );
        intermediateResponse.setResponseValue( intermediateResponseCodec.getResponseValue() );

        return intermediateResponse;
    }


    /**
     * Convert a LdapResultCodec to a LdapResult message
     */
    private LdapResult convert( LdapResultCodec ldapResultCodec )
    {
        LdapResult ldapResult = new LdapResult();
        
        ldapResult.setErrorMessage( ldapResultCodec.getErrorMessage() );
        ldapResult.setMatchedDn( ldapResultCodec.getMatchedDN() );
        
        // Loop on the referrals
        Referral referral = new Referral();
        
        if (ldapResultCodec.getReferrals() != null )
        {
            for ( LdapURL url:ldapResultCodec.getReferrals() )
            {
                referral.addLdapUrls( url );
            }
        }
        
        ldapResult.setReferral( referral );
        ldapResult.setResultCode( ldapResultCodec.getResultCode() );

        return ldapResult;
    }


    /**
     * Convert a SearchResultEntryCodec to a SearchResultEntry message
     */
    private SearchResultEntry convert( SearchResultEntryCodec searchEntryResultCodec )
    {
        SearchResultEntry searchResultEntry = new SearchResultEntry();
        
        searchResultEntry.setMessageId( searchEntryResultCodec.getMessageId() );
        searchResultEntry.setEntry( searchEntryResultCodec.getEntry() );
        
        return searchResultEntry;
    }


    /**
     * Convert a SearchResultDoneCodec to a SearchResultDone message
     */
    private SearchResultDone convert( SearchResultDoneCodec searchResultDoneCodec )
    {
        SearchResultDone searchResultDone = new SearchResultDone();
        
        searchResultDone.setMessageId( searchResultDoneCodec.getMessageId() );
        searchResultDone.setLdapResult( convert( searchResultDoneCodec.getLdapResult() ) );
        
        return searchResultDone;
    }


    /**
     * Convert a SearchResultReferenceCodec to a SearchResultReference message
     */
    private SearchResultReference convert( SearchResultReferenceCodec searchEntryReferenceCodec )
    {
        SearchResultReference searchResultReference = new SearchResultReference();
        
        searchResultReference.setMessageId( searchEntryReferenceCodec.getMessageId() );

        // Loop on the referrals
        Referral referral = new Referral();
        
        if (searchEntryReferenceCodec.getSearchResultReferences() != null )
        {
            for ( LdapURL url:searchEntryReferenceCodec.getSearchResultReferences() )
            {
                referral.addLdapUrls( url );
            }
        }
        
        searchResultReference.setReferral( referral );

        return searchResultReference;
    }


    //------------------------- The constructors --------------------------//
    /**
     * Create a new instance of a LdapConnection on localhost,
     * port 389.
     */
    public LdapConnection()
    {
        config.setUseSsl( false );
        config.setLdapPort( config.getDefaultLdapPort() );
        config.setLdapHost( config.getDefaultLdapHost() );
        messageId = new AtomicInteger();
    }
    
    
    /**
     * 
     * Creates a new instance of LdapConnection with the given connection configuration.
     *
     * @param config the configuration of the LdapConnection
     */
    public LdapConnection( LdapConnectionConfig config )
    {
        this.config = config;
        messageId = new AtomicInteger();
    }
    
    
    /**
     * Create a new instance of a LdapConnection on localhost,
     * port 389 if the SSL flag is off, or 636 otherwise.
     * 
     * @param useSsl A flag to tell if it's a SSL connection or not.
     */
    public LdapConnection( boolean useSsl )
    {
        config.setUseSsl( useSsl );
        config.setLdapPort( useSsl ? config.getDefaultLdapsPort() : config.getDefaultLdapPort() );
        config.setLdapHost( config.getDefaultLdapHost() );
        messageId = new AtomicInteger();
    }
    
    
    /**
     * Create a new instance of a LdapConnection on a given
     * server, using the default port (389).
     *
     * @param server The server we want to be connected to
     */
    public LdapConnection( String server )
    {
        config.setUseSsl( false );
        config.setLdapPort( config.getDefaultLdapPort() );
        config.setLdapHost( server );
        messageId = new AtomicInteger();
    }
    
    
    /**
     * Create a new instance of a LdapConnection on a given
     * server, using the default port (389) if the SSL flag 
     * is off, or 636 otherwise.
     *
     * @param server The server we want to be connected to
     * @param useSsl A flag to tell if it's a SSL connection or not.
     */
    public LdapConnection( String server, boolean useSsl )
    {
        config.setUseSsl( useSsl );
        config.setLdapPort( useSsl ? config.getDefaultLdapsPort() : config.getDefaultLdapPort() );
        config.setLdapHost( server );
        messageId = new AtomicInteger();
    }
    
    
    /**
     * Create a new instance of a LdapConnection on a 
     * given server and a given port. We don't use ssl.
     *
     * @param server The server we want to be connected to
     * @param port The port the server is listening to
     */
    public LdapConnection( String server, int port )
    {
        this( server, port, false );
    }
    
    
    /**
     * Create a new instance of a LdapConnection on a given
     * server, and a give port. We set the SSL flag accordingly
     * to the last parameter.
     *
     * @param server The server we want to be connected to
     * @param port The port the server is listening to
     * @param useSsl A flag to tell if it's a SSL connection or not.
     */
    public LdapConnection( String server, int port, boolean useSsl )
    {
        config.setUseSsl( useSsl );
        config.setLdapPort( port );
        config.setLdapHost( server );
        messageId = new AtomicInteger();
    }

    
    //-------------------------- The methods ---------------------------//
    /**
     * Connect to the remote LDAP server.
     *
     * @return <code>true</code> if the connection is established, false otherwise
     * @throws LdapException if some error has occured
     */
    private boolean connect() throws LdapException
    {
        if ( ( ldapSession != null ) && ldapSession.isConnected() ) 
        {
            return true;
        }

        // Create the connector if needed
        if ( connector == null ) 
        {
            connector = new NioSocketConnector();
            localConnector = true;
            
            // Add the codec to the chain
            connector.getFilterChain().addLast( "ldapCodec", ldapProtocolFilter );
    
            // If we use SSL, we have to add the SslFilter to the chain
            if ( config.isUseSsl() ) 
            {
                try
                {
                    SSLContext sslContext = SSLContext.getInstance( config.getSslProtocol() );
                    sslContext.init( config.getKeyManagers(), config.getTrustManagers(), config.getSecureRandom() );

                    SslFilter sslFilter = new SslFilter( sslContext );
                    sslFilter.setUseClientMode(true);
                    connector.getFilterChain().addFirst( "sslFilter", sslFilter );
                }
                catch( Exception e )
                {
                    String msg = "Failed to initialize the SSL context";
                    LOG.error( msg, e );
                    throw new LdapException( msg, e );
                }
            }
            
            connector.getFilterChain().addLast( "executor", 
                new ExecutorFilter( 
                    new UnorderedThreadPoolExecutor( 10 ),
                    IoEventType.MESSAGE_RECEIVED ) );
    
            // Inject the protocolHandler
            connector.setHandler( this );
        }
        
        // Build the connection address
        SocketAddress address = new InetSocketAddress( config.getLdapHost() , config.getLdapPort() );
        
        // And create the connection future
        ConnectFuture connectionFuture = connector.connect( address );
        
        // Wait until it's established
        connectionFuture.awaitUninterruptibly();
        
        if ( !connectionFuture.isConnected() ) 
        {
            // disposing connector if not connected
            connector.dispose();
            return false;
        }
        
        // Get back the session
        ldapSession = connectionFuture.getSession();
        
        // And inject the current Ldap container into the session
        IAsn1Container ldapMessageContainer = new LdapMessageContainer();
        
        // Store the container into the session 
        ldapSession.setAttribute( "LDAP-Container", ldapMessageContainer );
        
        // Create the responses queues
        addResponseQueue = new LinkedBlockingQueue<AddResponse>();
        bindResponseQueue = new LinkedBlockingQueue<BindResponse>();
        compareResponseQueue = new LinkedBlockingQueue<CompareResponse>();
        deleteResponseQueue = new LinkedBlockingQueue<DeleteResponse>();
        extendedResponseQueue = new LinkedBlockingQueue<ExtendedResponse>();
        modifyResponseQueue = new LinkedBlockingQueue<ModifyResponse>();
        modifyDNResponseQueue = new LinkedBlockingQueue<ModifyDnResponse>();
        searchResponseQueue = new LinkedBlockingQueue<SearchResponse>();
        intermediateResponseQueue = new LinkedBlockingQueue<IntermediateResponse>();
        
        // And return
        return true;
    }
    
    
    /**
     * Disconnect from the remote LDAP server
     *
     * @return <code>true</code> if the connection is closed, false otherwise
     * @throws IOException if some I/O error occurs
     */
    public boolean close() throws IOException 
    {
        // Close the session
        if ( ( ldapSession != null ) && ldapSession.isConnected() )
        {
            ldapSession.close( true );
        }
        
        // clean the queues
        addResponseQueue.clear();
        bindResponseQueue.clear();
        compareResponseQueue.clear();
        deleteResponseQueue.clear();
        extendedResponseQueue.clear();
        modifyResponseQueue.clear();
        modifyDNResponseQueue.clear();
        searchResponseQueue.clear();
        intermediateResponseQueue.clear();
        
        // And close the connector if it has been created locally
        if ( localConnector ) 
        {
            // Release the connector
            connector.dispose();
        }
        
        return true;
    }
    
    
    //------------------------ The LDAP operations ------------------------//
    // Add operations                                                      //
    //---------------------------------------------------------------------//
    /**
     * Add an entry to the server. This is a blocking add : the user has 
     * to wait for the response until the AddResponse is returned.
     * 
     * @param entry The entry to add
     * @result the add operation's response 
     */
    public AddResponse add( Entry entry ) throws LdapException
    {
        if ( entry == null ) 
        {
            String msg = "Cannot add empty entry";
            LOG.debug( msg );
            throw new NullPointerException( msg );
        }
        
        return add( new AddRequest( entry ), null );
    }
    
    
    /**
     * Add an entry present in the AddRequest to the server.
     * @param addRequest the request object containing an entry and controls(if any)
     * @return the add operation's response
     * @throws LdapException
     */
    public AddResponse add( AddRequest addRequest ) throws LdapException
    {
        return add( addRequest, null );
    }
    
    /**
     * Add an entry present in the AddRequest to the server.
     * @param addRequest the request object containing an entry and controls(if any)
     * @param listener A listener used for an asynchronous add operation
     * @return the add operation's response, null if non-null listener is provided
     * @throws LdapException
     */
    public AddResponse add( AddRequest addRequest, AddListener listener ) throws LdapException
    {
        checkSession();

        AddRequestCodec addReqCodec = new AddRequestCodec();
        
        int newId = messageId.incrementAndGet();
        LdapMessageCodec message = new LdapMessageCodec();
        message.setMessageId( newId );
        addReqCodec.setMessageId( newId );

        addReqCodec.setEntry( addRequest.getEntry() );
        addReqCodec.setEntryDn( addRequest.getEntry().getDn() );
        setControls( addRequest.getControls(), addReqCodec );
        
        message.setProtocolOP( addReqCodec );
        
        ResponseFuture addFuture = new ResponseFuture( addResponseQueue );
        futureMap.put( newId, addFuture );

        // Send the request to the server
        ldapSession.write( message );
        
        AddResponse response = null;
        if( listener == null )
        {
            try
            {
                long timeout = getTimeout( addRequest.getTimeout() );
                response = ( AddResponse ) addFuture.get( timeout, TimeUnit.MILLISECONDS );
                
                if ( response == null )
                {
                    LOG.error( "Add failed : timeout occured" );
                    throw new LdapException( TIME_OUT_ERROR );
                }
            }
            catch( InterruptedException ie )
            {
                LOG.error( OPERATION_CANCELLED, ie );
                throw new LdapException( OPERATION_CANCELLED, ie );
            }
            catch( Exception e )
            {
                LOG.error( NO_RESPONSE_ERROR );
                futureMap.remove( newId );
                throw new LdapException( NO_RESPONSE_ERROR, e );
            }
        }
        else
        {
            listenerMap.put( newId, listener );            
        }

        return response;
    }

    
    /**
     * converts the AddResponseCodec to AddResponse.
     */
    private AddResponse convert( AddResponseCodec addRespCodec )
    {
        AddResponse addResponse = new AddResponse();
        
        addResponse.setMessageId( addRespCodec.getMessageId() );
        addResponse.setLdapResult( convert( addRespCodec.getLdapResult() ) );
        
        return addResponse;
    }

    
    //------------------------ The LDAP operations ------------------------//

    /**
     * Abandons a request submitted to the server for performing a particular operation
     * 
     * The abandonRequest is always non-blocking, because no response is expected
     * 
     * @param messageId the ID of the request message sent to the server 
     */
    public void abandon( int messageId )
    {
        AbandonRequest abandonRequest = new AbandonRequest();
        abandonRequest.setAbandonedMessageId( messageId );
        
        abandonInternal( abandonRequest );
    }

    
    /**
     * An abandon request essentially with the request message ID of the operation to be cancelled
     * and/or potentially some controls and timeout (the controls and timeout are not mandatory).
     * 
     * The abandonRequest is always non-blocking, because no response is expected
     *  
     * @param abandonRequest the abandon operation's request
     */
    public void abandon( AbandonRequest abandonRequest )
    {
        abandonInternal( abandonRequest );
    }
    
    
    /**
     * Internal AbandonRequest handling
     */
    private void abandonInternal( AbandonRequest abandonRequest )
    {
        // Create the new message and update the messageId
        LdapMessageCodec message = new LdapMessageCodec();

        // Creates the messageID and stores it into the 
        // initial message and the transmitted message.
        int newId = messageId.incrementAndGet();
        abandonRequest.setMessageId( newId );
        message.setMessageId( newId );

        // Create the inner abandonRequest
        AbandonRequestCodec request = new AbandonRequestCodec();
        
        // Inject the data into the request
        request.setAbandonedMessageId( abandonRequest.getAbandonedMessageId() );
        
        // Inject the request into the message
        message.setProtocolOP( request );
        
        // Inject the controls
        setControls( abandonRequest.getControls(), message );
        
        LOG.debug( "-----------------------------------------------------------------" );
        LOG.debug( "Sending request \n{}", message );

        // Send the request to the server
        ldapSession.write( message );

        // remove the associated listener if any 
        int abandonId = abandonRequest.getAbandonedMessageId();

        ResponseFuture rf = futureMap.remove( abandonId );
        OperationResponseListener listener = listenerMap.remove( abandonId );

        // if the listener is not null, this is a async operation and no need to
        // send cancel signal on future, sending so will leave a dangling poision object in the corresponding queue
        if( listener != null )
        {
            LOG.debug( "removed the listener associated with the abandoned operation with id {}", abandonId );
        }
        else // this is a sync operation send cancel signal to the corresponding ResponseFuture
        {
            if( rf != null )
            {
                LOG.debug( "sending cancel signal to future" );
                rf.cancel( true );
            }
            else
            {
                // this shouldn't happen
                LOG.error( "There is no future asscoiated with operation message ID {}, perhaps the operation would have been completed", abandonId );
            }
        }
    }
    
    
    /**
     * Anonymous Bind on a server. 
     *
     * @return The BindResponse LdapResponse 
     */
    public BindResponse bind() throws LdapException
    {
        LOG.debug( "Anonymous Bind request" );

        return bind( StringTools.EMPTY, StringTools.EMPTY_BYTES );
    }
    
    
    /**
     * An Unauthenticated Authentication Bind on a server. (cf RFC 4513,
     * par 5.1.2)
     *
     * @param name The name we use to authenticate the user. It must be a 
     * valid DN
     * @return The BindResponse LdapResponse 
     */
    public BindResponse bind( String name ) throws Exception
    {
        LOG.debug( "Bind request : {}", name );

        return bind( name, StringTools.EMPTY_BYTES );
    }

    
    /**
     * An Unauthenticated Authentication Bind on a server. (cf RFC 4513,
     * par 5.1.2)
     *
     * @param name The name we use to authenticate the user.
     * @return The BindResponse LdapResponse 
     */
    public BindResponse bind( LdapDN name ) throws Exception
    {
        if ( name == null )
        {
            LOG.debug( "Anonymous Bind request : {}", name );

            return bind( StringTools.EMPTY, StringTools.EMPTY_BYTES );
        }
        else
        {
            LOG.debug( "Unauthenticated Bind request : {}", name );

            return bind( name.getName(), StringTools.EMPTY_BYTES );
        }
    }

    
    /**
     * Simple Bind on a server.
     *
     * @param name The name we use to authenticate the user. It must be a 
     * valid DN
     * @param credentials The password. It can't be null 
     * @return The BindResponse LdapResponse 
     */
    public BindResponse bind( String name, String credentials ) throws LdapException
    {
        LOG.debug( "Bind request : {}", name );

        return bind( name, StringTools.getBytesUtf8( credentials ) );
    }


    /**
     * Simple Bind on a server.
     *
     * @param name The name we use to authenticate the user. It must be a 
     * valid DN
     * @param credentials The password. It can't be null 
     * @return The BindResponse LdapResponse 
     */
    public BindResponse bind( LdapDN name, String credentials ) throws LdapException
    {
        LOG.debug( "Bind request : {}", name );

        if ( name == null )
        {
            return bind( StringTools.EMPTY, StringTools.getBytesUtf8( credentials ) );
        }
        else
        {
            return bind( name.getName(), StringTools.getBytesUtf8( credentials ) );
        }
    }

    
    /**
     * Simple Bind on a server.
     *
     * @param name The name we use to authenticate the user.
     * @param credentials The password.
     * @return The BindResponse LdapResponse 
     */
    public BindResponse bind( LdapDN name, byte[] credentials )  throws LdapException
    {
        LOG.debug( "Bind request : {}", name );

        return bind( name.getName(), credentials );
    }

    
    /**
     * Simple Bind on a server.
     *
     * @param name The name we use to authenticate the user. It must be a 
     * valid DN
     * @param credentials The password.
     * @return The BindResponse LdapResponse 
     */
    public BindResponse bind( String name, byte[] credentials )  throws LdapException
    {
        LOG.debug( "Bind request : {}", name );

        // Create the BindRequest
        BindRequest bindRequest = new BindRequest();
        bindRequest.setName( name );
        bindRequest.setCredentials( credentials );
        
        BindResponse response = bind( bindRequest, null );

        if ( LOG.isDebugEnabled() )
        {
            if ( response.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
            {
                LOG.debug( " Bind successfull" );
            }
            else
            {
                LOG.debug( " Bind failure {}", response );
            }
        }
        
        return response;
    }
    
    
    /**
     * Bind to the server using a BindRequest object.
     *
     * @param bindRequest The BindRequest POJO containing all the needed
     * parameters 
     * @return A LdapResponse containing the result
     */
    public BindResponse bind( BindRequest bindRequest ) throws LdapException
    {
        return bind( bindRequest, null );
    }
        

    /**
     * Do a non-blocking bind non-blocking
     *
     * @param bindRequest The BindRequest to send
     * @param listener The listener 
     */
    public BindResponse bind( BindRequest bindRequest, BindListener bindListener ) throws LdapException 
    {
        // First try to connect, if we aren't already connected.
        connect();
        
        // If the session has not been establish, or is closed, we get out immediately
        checkSession();

        // Create the new message and update the messageId
        LdapMessageCodec bindMessage = new LdapMessageCodec();

        // Creates the messageID and stores it into the 
        // initial message and the transmitted message.
        int newId = messageId.incrementAndGet();
        bindRequest.setMessageId( newId );
        bindMessage.setMessageId( newId );
        
        if( bindListener != null )
        {
            listenerMap.put( newId, bindListener );
        }
        
        // Create a new codec BindRequest object
        BindRequestCodec request =  new BindRequestCodec();
        
        // Set the version
        request.setVersion( LdapConnectionConfig.LDAP_V3 );
        
        // Set the name
        try
        {
            LdapDN dn = new LdapDN( bindRequest.getName() );
            request.setName( dn );
        }
        catch ( InvalidNameException ine )
        {
            String msg = "The given dn '" + bindRequest.getName() + "' is not valid";
            LOG.error( msg );
            LdapException ldapException = new LdapException( msg );
            ldapException.initCause( ine );

            throw ldapException;
        }
        
        // Set the credentials
        LdapAuthentication authentication = null;
        
        if ( bindRequest.isSimple() )
        {
            // Simple bind
            authentication = new SimpleAuthentication();
            ((SimpleAuthentication)authentication).setSimple( bindRequest.getCredentials() );
        }
        else
        {
            // SASL bind
            authentication = new SaslCredentials();
            ((SaslCredentials)authentication).setCredentials( bindRequest.getCredentials() );
            ((SaslCredentials)authentication).setMechanism( bindRequest.getSaslMechanism() );
        }
        
        // The authentication
        request.setAuthentication( authentication );
        
        // Stores the BindRequest into the message
        bindMessage.setProtocolOP( request );
        
        // Add the controls
        setControls( bindRequest.getControls(), bindMessage );

        LOG.debug( "-----------------------------------------------------------------" );
        LOG.debug( "Sending request \n{}", bindMessage );

        ResponseFuture responseFuture = new ResponseFuture( bindResponseQueue );
        futureMap.put( newId, responseFuture );

        // Send the request to the server
        ldapSession.write( bindMessage );
        
        if ( bindListener == null )
        {
            // And get the result
            try
            {
                // Read the response, waiting for it if not available immediately
                long timeout = getTimeout( bindRequest.getTimeout() );
                
                // Get the response, blocking
                BindResponse bindResponse = (BindResponse)responseFuture.get( timeout, TimeUnit.MILLISECONDS );
    
                // Everything is fine, return the response
                LOG.debug( "Bind successful : {}", bindResponse );
                
                return bindResponse;
            }
            catch ( TimeoutException te )
            {
                // Send an abandon request
                if( !responseFuture.isCancelled() )
                {
                    abandon( bindRequest.getMessageId() );
                }
                
                // We didn't received anything : this is an error
                LOG.error( "Bind failed : timeout occured" );
                throw new LdapException( TIME_OUT_ERROR );
            }
            catch ( Exception ie )
            {
                // Catch all other exceptions
                LOG.error( NO_RESPONSE_ERROR, ie );
                LdapException ldapException = new LdapException( NO_RESPONSE_ERROR );
                ldapException.initCause( ie );
                
                // Send an abandon request
                if( !responseFuture.isCancelled() )
                {
                    abandon( bindRequest.getMessageId() );
                }
                
                throw ldapException;
            }
        }
        else
        {
            // Return null.
            listenerMap.put( newId, bindListener );
            return null;
        }
    }
    
    
    /**
     * Do a search, on the base object, using the given filter. The
     * SearchRequest parameters default to :
     * Scope : ONE
     * DerefAlias : ALWAYS
     * SizeLimit : none
     * TimeLimit : none
     * TypesOnly : false
     * Attributes : all the user's attributes.
     * This method is blocking.
     * 
     * @param baseDn The base for the search. It must be a valid
     * DN, and can't be emtpy
     * @param filterString The filter to use for this search. It can't be empty
     * @param scope The sarch scope : OBJECT, ONELEVEL or SUBTREE 
     * @return A cursor on the result. 
     */
    public Cursor<SearchResponse> search( String baseDn, String filter, SearchScope scope, 
        String... attributes ) throws LdapException
    {
        // Create a new SearchRequest object
        SearchRequest searchRequest = new SearchRequest();
        
        searchRequest.setBaseDn( baseDn );
        searchRequest.setFilter( filter );
        searchRequest.setScope( scope );
        searchRequest.addAttributes( attributes );
        searchRequest.setDerefAliases( AliasDerefMode.DEREF_ALWAYS );

        // Process the request in blocking mode
        return searchInternal( searchRequest, null );
    }
    
    
    /**
     * Do a search, on the base object, using the given filter. The
     * SearchRequest parameters default to :
     * Scope : ONE
     * DerefAlias : ALWAYS
     * SizeLimit : none
     * TimeLimit : none
     * TypesOnly : false
     * Attributes : all the user's attributes.
     * This method is blocking.
     * 
     * @param listener a SearchListener used to be informed when a result 
     * has been found, or when the search is done
     * @param baseObject The base for the search. It must be a valid
     * DN, and can't be emtpy
     * @param filter The filter to use for this search. It can't be empty
     * @return A cursor on the result. 
     */
    public void search( SearchRequest searchRequest, SearchListener listener ) throws LdapException
    {
        searchInternal( searchRequest, listener );
    }
    
    
    /**
     * performs search in a synchronous mode (as if a null search listener is passed) 
     * @see #search(SearchRequest, SearchListener)
     */
    public Cursor<SearchResponse> search( SearchRequest searchRequest ) throws LdapException
    {
        return searchInternal( searchRequest, null );
    }

    
    private Cursor<SearchResponse> searchInternal( SearchRequest searchRequest, SearchListener searchListener )
        throws LdapException
    {
        // If the session has not been establish, or is closed, we get out immediately
        checkSession();
    
        // Create the new message and update the messageId
        LdapMessageCodec searchMessage = new LdapMessageCodec();
        
        // Creates the messageID and stores it into the 
        // initial message and the transmitted message.
        int newId = messageId.incrementAndGet();
        searchRequest.setMessageId( newId );
        searchMessage.setMessageId( newId );
        
        // Create a new codec SearchRequest object
        SearchRequestCodec request =  new SearchRequestCodec();
        
        // Set the name
        try
        {
            LdapDN dn = new LdapDN( searchRequest.getBaseDn() );
            request.setBaseObject( dn );
        }
        catch ( InvalidNameException ine )
        {
            String msg = "The given dn '" + searchRequest.getBaseDn() + "' is not valid";
            LOG.error( msg );
            LdapException ldapException = new LdapException( msg );
            ldapException.initCause( ine );

            throw ldapException;
        }
        
        // Set the scope
        request.setScope( searchRequest.getScope() );
        
        // Set the typesOnly flag
        request.setDerefAliases( searchRequest.getDerefAliases().getValue() );
        
        // Set the timeLimit
        request.setTimeLimit( searchRequest.getTimeLimit() );
        
        // Set the sizeLimit
        request.setSizeLimit( searchRequest.getSizeLimit() );
        
        // Set the typesOnly flag
        request.setTypesOnly( searchRequest.getTypesOnly() );
    
        // Set the filter
        Filter filter = null;
        
        try
        {
            ExprNode filterNode = FilterParser.parse( searchRequest.getFilter() );
            
            filter = TwixTransformer.transformFilter( filterNode );
        }
        catch ( ParseException pe )
        {
            String msg = "The given filter '" + searchRequest.getFilter() + "' is not valid";
            LOG.error( msg );
            LdapException ldapException = new LdapException( msg );
            ldapException.initCause( pe );

            throw ldapException;
        }
        
        request.setFilter( filter );
        
        // Set the attributes
        Set<String> attributes = searchRequest.getAttributes();
        
        if ( attributes != null )
        {
            for ( String attribute:attributes )
            {
                request.addAttribute( attribute );
            }
        }
        
        // Stores the SearchRequest into the message
        searchMessage.setProtocolOP( request );
        
        // Add the controls
        setControls( searchRequest.getControls(), searchMessage );
    
        LOG.debug( "-----------------------------------------------------------------" );
        LOG.debug( "Sending request \n{}", searchMessage );
    
        ResponseFuture searchFuture = new ResponseFuture( searchResponseQueue );
        futureMap.put( newId, searchFuture );

        // Send the request to the server
        ldapSession.write( searchMessage );
    
        
        if ( searchListener == null )
        {
            // Read the response, waiting for it if not available immediately
            try
            {
                long timeout = getTimeout( searchRequest.getTimeout() );
                SearchResponse response = null;
                List<SearchResponse> searchResponses = new ArrayList<SearchResponse>();

                // We may have more than one response, so loop on the queue
                do 
                {
                    response = ( SearchResponse ) searchFuture.get( timeout, TimeUnit.MILLISECONDS );

                    // Check that we didn't get out because of a timeout
                    if ( response == null )
                    {
                        // Send an abandon request
                        abandon( searchMessage.getSearchRequest().getMessageId() );
                        
                        // We didn't received anything : this is an error
                        LOG.error( "Search failed : timeout occured" );

                        throw new LdapException( TIME_OUT_ERROR );
                    }
                    else
                    {
                        if ( response instanceof SearchResultEntry )
                        {
                            searchResponses.add( response );
                        }
                        else if ( response instanceof SearchResultReference )
                        {
                            searchResponses.add( response );
                        }
                    }
                }
                while ( !( response instanceof SearchResultDone ) );

                LOG.debug( "Search successful, {} elements found", searchResponses.size() );
                
                return new ListCursor<SearchResponse>( searchResponses );
            }
            catch( InterruptedException ie )
            {
                LOG.error( OPERATION_CANCELLED, ie );
                throw new LdapException( OPERATION_CANCELLED, ie );
            }
            catch ( Exception e )
            {
                LOG.error( NO_RESPONSE_ERROR, e );
                LdapException ldapException = new LdapException( NO_RESPONSE_ERROR );
                ldapException.initCause( e );
                
                // Send an abandon request
                if( !searchFuture.isCancelled() )
                {
                    abandon( searchMessage.getBindRequest().getMessageId() );
                }
                
                throw ldapException;
            }
        }
        else
        {
            // The listener will be called on a MessageReceived event,
            // no need to create a cursor
            listenerMap.put( newId, searchListener );
            return null;
        }
    }

    
    //------------------------ The LDAP operations ------------------------//
    // Unbind operations                                                   //
    //---------------------------------------------------------------------//
    /**
     * UnBind from a server. this is a request which expect no response.
     */
    public void unBind() throws Exception
    {
        // First try to connect, if we aren't already connected.
        connect();
        
        // If the session has not been establish, or is closed, we get out immediately
        checkSession();
        
        // Create the UnbindRequest
        UnBindRequestCodec unbindRequest = new UnBindRequestCodec();
        
        // Encode the request
        LdapMessageCodec unbindMessage = new LdapMessageCodec();

        // Creates the messageID and stores it into the 
        // initial message and the transmitted message.
        int newId = messageId.incrementAndGet();
        unbindRequest.setMessageId( newId );
        unbindMessage.setMessageId( newId );

        unbindMessage.setProtocolOP( unbindRequest );
        
        LOG.debug( "-----------------------------------------------------------------" );
        LOG.debug( "Sending Unbind request \n{}", unbindMessage );
        
        // Send the request to the server
        ldapSession.write( unbindMessage );
        
        //  We now have to close the connection
        close();

        // And get out
        LOG.debug( "Unbind successful" );
    }
    
    
    /**
     * Set the connector to use.
     *
     * @param connector The connector to use
     */
    public void setConnector( IoConnector connector )
    {
        this.connector = connector;
    }


    /**
     * Set the timeOut for the responses. We wont wait longer than this 
     * value.
     *
     * @param timeOut The timeout, in milliseconds
     */
    public void setTimeOut( long timeOut )
    {
        this.timeOut = timeOut;
    }
    
    
    /**
     * Handle the incoming LDAP messages. This is where we feed the cursor for search 
     * requests, or call the listener. 
     */
    public void messageReceived( IoSession session, Object message) throws Exception 
    {
        // Feed the response and store it into the session
        LdapMessageCodec response = (LdapMessageCodec)message;

        LOG.debug( "-------> {} Message received <-------", response.getMessageTypeName() );
        
        // this check is necessary to prevent adding an abandoned operation's
        // result(s) to corresponding queue
        ResponseFuture rf = futureMap.get( response.getMessageId() );
        
        if( rf == null )
        {
            LOG.error( "There is no future associated with the messageId {}, ignoring the message", response.getMessageId()  );
            return;
        }
        
        SearchListener searchListener = null;

        switch ( response.getMessageType() )
        {
            case LdapConstants.ADD_RESPONSE :
                // Store the response into the responseQueue
                AddResponseCodec addRespCodec = response.getAddResponse();
                addRespCodec.addControl( response.getCurrentControl() );
                addRespCodec.setMessageId( response.getMessageId() );
                
                futureMap.remove( addRespCodec.getMessageId() );
                AddListener addListener = ( AddListener ) listenerMap.remove( addRespCodec.getMessageId() );
                AddResponse addResp = convert( addRespCodec );
                if( addListener != null )
                {
                    addListener.entryAdded( this, addResp );
                }
                else
                {
                    addResponseQueue.add( addResp ); 
                }
                break;
                
            case LdapConstants.BIND_RESPONSE: 
                // Store the response into the responseQueue
                BindResponseCodec bindResponseCodec = response.getBindResponse();
                bindResponseCodec.setMessageId( response.getMessageId() );
                bindResponseCodec.addControl( response.getCurrentControl() );
                BindResponse bindResponse = convert( bindResponseCodec );

                futureMap.remove( bindResponseCodec.getMessageId() );
                // remove the listener from the listener map
                BindListener bindListener = ( BindListener ) listenerMap.remove( bindResponseCodec.getMessageId() );
                
                if ( bindListener != null )
                {
                    bindListener.bindCompleted( this, bindResponse );
                }
                else
                {
                    // Store the response into the responseQueue
                    bindResponseQueue.add( bindResponse );
                }
                
                break;
                
            case LdapConstants.COMPARE_RESPONSE :
                // Store the response into the responseQueue
                CompareResponseCodec compResCodec = response.getCompareResponse();
                compResCodec.setMessageId( response.getMessageId() );
                compResCodec.addControl( response.getCurrentControl() );
                CompareResponse compRes = convert( compResCodec );
                
                futureMap.remove( compRes.getMessageId() );
                
                CompareListener listener = ( CompareListener ) listenerMap.remove( compRes.getMessageId() );
                if( listener != null )
                {
                    listener.attributeCompared( this, compRes );
                }
                else
                {
                    compareResponseQueue.add( compRes ); 
                }
                
                break;
                
            case LdapConstants.DEL_RESPONSE :
                // Store the response into the responseQueue
                DelResponseCodec delRespCodec = response.getDelResponse();
                delRespCodec.setMessageId( response.getMessageId() );
                delRespCodec.addControl( response.getCurrentControl() );
                DeleteResponse delResp = convert( delRespCodec );
                
                futureMap.remove( delResp.getMessageId() );
                DeleteListener delListener = ( DeleteListener ) listenerMap.remove( delResp.getMessageId() );
                if( delListener != null )
                {
                    delListener.entryDeleted( this, delResp );
                }
                else
                {
                    deleteResponseQueue.add( delResp ); 
                }
                break;
                
            case LdapConstants.EXTENDED_RESPONSE :
                ExtendedResponseCodec extResCodec = response.getExtendedResponse();
                extResCodec.setMessageId( response.getMessageId() );
                extResCodec.addControl( response.getCurrentControl() );
                
                ExtendedResponse extResponse = convert( extResCodec );
                ExtendedListener extListener = ( ExtendedListener ) listenerMap.remove( extResCodec.getMessageId() );
                if( extListener != null )
                {
                    extListener.extendedOperationCompleted( this, extResponse );
                }
                else
                {
                    // Store the response into the responseQueue
                    extendedResponseQueue.add( extResponse ); 
                }
                
                break;
                
            case LdapConstants.INTERMEDIATE_RESPONSE:
                // Store the response into the responseQueue
                IntermediateResponseCodec intermediateResponseCodec = 
                    response.getIntermediateResponse();
                intermediateResponseCodec.setMessageId( response.getMessageId() );
                intermediateResponseCodec.addControl( response.getCurrentControl() );
                
                IntermediateResponse intrmResp = convert( intermediateResponseCodec );                
                IntermediateResponseListener intrmListener = ( IntermediateResponseListener ) listenerMap.get( intermediateResponseCodec.getMessageId() ); 
                if ( intrmListener != null )
                {
                    intrmListener.responseReceived( this, intrmResp );
                }
                else
                {
                    // Store the response into the responseQueue
                    intermediateResponseQueue.add( intrmResp );
                }
                
                break;
     
            case LdapConstants.MODIFY_RESPONSE :
                ModifyResponseCodec modRespCodec = response.getModifyResponse();
                modRespCodec.setMessageId( response.getMessageId() );
                modRespCodec.addControl( response.getCurrentControl() );
                ModifyResponse modResp = convert( modRespCodec );

                futureMap.remove( modResp.getMessageId() );
                ModifyListener modListener = ( ModifyListener ) listenerMap.remove( modResp.getMessageId() );
                
                if( modListener != null )
                {
                    modListener.modifyCompleted( this, modResp );
                }
                else
                {
                    modifyResponseQueue.add( modResp ); 
                }
                break;
                
            case LdapConstants.MODIFYDN_RESPONSE :
                
                ModifyDNResponseCodec modDnCodec = response.getModifyDNResponse();
                modDnCodec.addControl( response.getCurrentControl() );
                modDnCodec.setMessageId( response.getMessageId() );
                ModifyDnResponse modDnResp = convert( modDnCodec );
                
                futureMap.remove( modDnCodec.getMessageId() );
                ModifyDnListener modDnListener = ( ModifyDnListener ) listenerMap.remove( modDnCodec.getMessageId() );
                if( modDnListener != null )
                {
                    modDnListener.modifyDnCompleted( this, modDnResp );
                }
                else
                {
                    // Store the response into the responseQueue
                    modifyDNResponseQueue.add( modDnResp );
                }
                break;
                
            case LdapConstants.SEARCH_RESULT_DONE:
                // Store the response into the responseQueue
                SearchResultDoneCodec searchResultDoneCodec = 
                    response.getSearchResultDone();
                searchResultDoneCodec.setMessageId( response.getMessageId() );
                searchResultDoneCodec.addControl( response.getCurrentControl() );
                SearchResultDone srchDone = convert( searchResultDoneCodec );
                
                futureMap.remove( searchResultDoneCodec.getMessageId() );
                // search listener has to be removed from listener map only here
                searchListener = ( SearchListener ) listenerMap.remove( searchResultDoneCodec.getMessageId() );
                if ( searchListener != null )
                {
                    searchListener.searchDone( this, srchDone );
                }
                else
                {
                    searchResponseQueue.add( srchDone );
                }
                
                break;
            
            case LdapConstants.SEARCH_RESULT_ENTRY:
                // Store the response into the responseQueue
                SearchResultEntryCodec searchResultEntryCodec = 
                    response.getSearchResultEntry();
                searchResultEntryCodec.setMessageId( response.getMessageId() );
                searchResultEntryCodec.addControl( response.getCurrentControl() );
                
                SearchResultEntry srchEntry = convert( searchResultEntryCodec );
                searchListener = ( SearchListener ) listenerMap.get( searchResultEntryCodec.getMessageId() );
                
                if ( searchListener != null )
                {
                    searchListener.entryFound( this, srchEntry );
                }
                else
                {
                    searchResponseQueue.add( srchEntry );
                }
                
                break;
                       
            case LdapConstants.SEARCH_RESULT_REFERENCE:
                // Store the response into the responseQueue
                SearchResultReferenceCodec searchResultReferenceCodec = 
                    response.getSearchResultReference();
                searchResultReferenceCodec.setMessageId( response.getMessageId() );
                searchResultReferenceCodec.addControl( response.getCurrentControl() );

                SearchResultReference srchRef = convert( searchResultReferenceCodec );
                searchListener = ( SearchListener ) listenerMap.get( searchResultReferenceCodec.getMessageId() );
                if ( searchListener != null )
                {
                    searchListener.referralFound( this, srchRef );
                }
                else
                {
                    searchResponseQueue.add( srchRef );
                }

                break;
                       
             default: LOG.error( "~~~~~~~~~~~~~~~~~~~~~ Unknown message type {} ~~~~~~~~~~~~~~~~~~~~~", response.getMessageTypeName() );
        }
    }
    
    
    /**
     * 
     * modifies all the attributes present in the entry by applying the same operation.
     *
     * @param entry the entry whise attributes to be modified
     * @param modOp the operation to be applied on all the attributes of the above entry
     * @return the modify operation's response
     * @throws LdapException in case of modify operation failure or timeout happens
     */
    public ModifyResponse modify( Entry entry, ModificationOperation modOp ) throws LdapException
    {
        if( entry == null )
        {
            LOG.debug( "received a null entry for modification" );
            throw new NullPointerException( "Entry to be modified cannot be null" );
        }
        
        ModifyRequest modReq = new ModifyRequest( entry.getDn() );
        
        Iterator<EntryAttribute> itr = entry.iterator();
        while( itr.hasNext() )
        {
            modReq.addModification( itr.next(), modOp );
        }
        
        return modify( modReq, null );
    }
    
    
    /**
     * 
     * performs modify operation based on the modifications present in the ModifyRequest.
     *
     * @param modRequest the request for modify operation
     * @param listener callback listener which will be called after the operation is completed
     * @return the modify operation's response, null if non-null listener is provided
     * @throws LdapException in case of modify operation failure or timeout happens
     */
    public ModifyResponse modify( ModifyRequest modRequest, ModifyListener listener )  throws LdapException
    {
        checkSession();
    
        LdapMessageCodec modifyMessage = new LdapMessageCodec();
        
        int newId = messageId.incrementAndGet();
        modRequest.setMessageId( newId );
        modifyMessage.setMessageId( newId );
        
        ModifyRequestCodec modReqCodec = new ModifyRequestCodec();
        modReqCodec.setModifications( modRequest.getMods() );
        modReqCodec.setObject( modRequest.getDn() );

        modifyMessage.setProtocolOP( modReqCodec );
        setControls( modRequest.getControls(), modifyMessage );

        ResponseFuture modifyFuture = new ResponseFuture( modifyResponseQueue );
        futureMap.put( newId, modifyFuture );
        
        ldapSession.write( modifyMessage );
        
        ModifyResponse response = null;
        if( listener == null )
        {
            try
            {
                long timeout = getTimeout( modRequest.getTimeout() );
                response = ( ModifyResponse ) modifyFuture.get( timeout, TimeUnit.MILLISECONDS );
                
                if ( response == null )
                {
                    LOG.error( "Modify failed : timeout occured" );

                    throw new LdapException( TIME_OUT_ERROR );
                }
            }
            catch( InterruptedException ie )
            {
                LOG.error( OPERATION_CANCELLED, ie );
                throw new LdapException( OPERATION_CANCELLED, ie );
            }
            catch( Exception e )
            {
                LOG.error( NO_RESPONSE_ERROR );
                futureMap.remove( newId );

                throw new LdapException( NO_RESPONSE_ERROR, e );
            }
        }
        else
        {
            listenerMap.put( newId, listener );
        }
        
        return response;
    }
    
    
    /**
     * converts the ModifyResponseCodec to ModifyResponse.
     */
    private ModifyResponse convert( ModifyResponseCodec modRespCodec )
    {
        ModifyResponse modResponse = new ModifyResponse();
        
        modResponse.setMessageId( modRespCodec.getMessageId() );
        modResponse.setLdapResult( convert( modRespCodec.getLdapResult() ) );

        return modResponse;
    }


    /**
     * renames the given entryDn with new Rdn and deletes the old RDN.
     * @see #rename(String, String, boolean)
     */
    public ModifyDnResponse rename( String entryDn, String newRdn ) throws LdapException
    {
        return rename( entryDn, newRdn, true );
    }

    
    /**
     * renames the given entryDn with new RDN and deletes the old RDN.
     * @see #rename(LdapDN, Rdn, boolean)
     */
    public ModifyDnResponse rename( LdapDN entryDn, Rdn newRdn ) throws LdapException
    {
        return rename( entryDn, newRdn, true );
    }
    
    
    /**
     * @see #rename(LdapDN, Rdn, boolean)
     */
    public ModifyDnResponse rename( String entryDn, String newRdn, boolean deleteOldRdn ) throws LdapException
    {
        try
        {
            return rename( new LdapDN( entryDn ), new Rdn( newRdn ), deleteOldRdn );
        }
        catch( InvalidNameException e )
        {
            LOG.error( e.getMessage(), e );
            throw new LdapException( e.getMessage(), e );
        }
    }
    
    
    /**
     * 
     * renames the given entryDn with new RDN and deletes the old Rdn if 
     * deleteOldRdn is set to true.
     *
     * @param entryDn the target DN
     * @param newRdn new Rdn for the target DN
     * @param deleteOldRdn flag to indicate whether to delete the old Rdn
     * @return modifyDn operations response
     * @throws LdapException
     */
    public ModifyDnResponse rename( LdapDN entryDn, Rdn newRdn, boolean deleteOldRdn ) throws LdapException
    {
        ModifyDnRequest modDnRequest = new ModifyDnRequest();
        modDnRequest.setEntryDn( entryDn );
        modDnRequest.setNewRdn( newRdn );
        modDnRequest.setDeleteOldRdn( deleteOldRdn );
        
        return modifyDn( modDnRequest, null );
    }
    

    /**
     * @see #move(LdapDN, LdapDN) 
     */
    public ModifyDnResponse move( String entryDn, String newSuperiorDn ) throws LdapException
    {
        try
        {
            return move( new LdapDN( entryDn ), new LdapDN( newSuperiorDn ) );
        }
        catch( InvalidNameException e )
        {
            LOG.error( e.getMessage(), e );
            throw new LdapException( e.getMessage(), e );
        }
    }
    

    /**
     * moves the given entry DN under the new superior DN
     *
     * @param entryDn the DN of the target entry
     * @param newSuperiorDn DN of the new parent/superior
     * @return modifyDn operations response
     * @throws LdapException
     */
    public ModifyDnResponse move( LdapDN entryDn, LdapDN newSuperiorDn ) throws LdapException
    {
        ModifyDnRequest modDnRequest = new ModifyDnRequest();
        modDnRequest.setEntryDn( entryDn );
        modDnRequest.setNewSuperior( newSuperiorDn );
        
        //TODO not setting the below value is resulting in error
        modDnRequest.setNewRdn( entryDn.getRdn() );
        
        return modifyDn( modDnRequest, null );
    }

    
    /**
     * 
     * performs the modifyDn operation based on the given ModifyDnRequest.
     *
     * @param modDnRequest the request
     * @param listener callback listener which will be called after the operation is completed
     * @return modifyDn operations response, null if non-null listener is provided
     * @throws LdapException
     */
    public ModifyDnResponse modifyDn( ModifyDnRequest modDnRequest, ModifyDnListener listener ) throws LdapException
    {
        checkSession();
    
        LdapMessageCodec modifyDnMessage = new LdapMessageCodec();
        
        int newId = messageId.incrementAndGet();
        modDnRequest.setMessageId( newId );
        modifyDnMessage.setMessageId( newId );

        ModifyDNRequestCodec modDnCodec = new ModifyDNRequestCodec();
        modDnCodec.setEntry( modDnRequest.getEntryDn() );
        modDnCodec.setNewRDN( modDnRequest.getNewRdn() );
        modDnCodec.setDeleteOldRDN( modDnRequest.isDeleteOldRdn() );
        modDnCodec.setNewSuperior( modDnRequest.getNewSuperior() );
        
        modifyDnMessage.setProtocolOP( modDnCodec );
        setControls( modDnRequest.getControls(), modifyDnMessage );
        
        ResponseFuture modifyDNFuture = new ResponseFuture( modifyDNResponseQueue );
        futureMap.put( newId, modifyDNFuture );
        
        ldapSession.write( modifyDnMessage );
        
        if( listener == null )
        {
            ModifyDnResponse response = null;
            try
            {
                long timeout = getTimeout( modDnRequest.getTimeout() );
                response = ( ModifyDnResponse ) modifyDNFuture.get( timeout, TimeUnit.MILLISECONDS );
                
                if ( response == null )
                {
                    LOG.error( "Modifying DN failed : timeout occured" );

                    throw new LdapException( TIME_OUT_ERROR );
                }
            }
            catch( InterruptedException ie )
            {
                LOG.error( OPERATION_CANCELLED, ie );
                throw new LdapException( OPERATION_CANCELLED, ie );
            }
            catch( Exception e )
            {
                LOG.error( NO_RESPONSE_ERROR );
                futureMap.remove( newId );

                LdapException ldapException = new LdapException( NO_RESPONSE_ERROR );
                ldapException.initCause( e );
                throw ldapException;
            }
            
            return response;
        }
        else
        {
            listenerMap.put( newId, listener );
            return null;
        }
    }
    
    
    /**
     * converts the ModifyDnResponseCodec to ModifyResponse.
     */
    private ModifyDnResponse convert( ModifyDNResponseCodec modDnRespCodec )
    {
        ModifyDnResponse modDnResponse = new ModifyDnResponse();
        
        modDnResponse.setMessageId( modDnRespCodec.getMessageId() );
        modDnResponse.setLdapResult( convert( modDnRespCodec.getLdapResult() ) );
        
        return modDnResponse;
    }


    /**
     * deletes the entry with the given DN
     *  
     * @param dn the target entry's DN as a String
     * @throws LdapException If the DN is not valid or if the deletion failed
     */
    public DeleteResponse delete( String dn ) throws LdapException
    {
        try
        {
            DeleteRequest deleteRequest = new DeleteRequest( new LdapDN( dn ) );

            return delete( deleteRequest, null );
        }
        catch( InvalidNameException e )
        {
            LOG.error( e.getMessage(), e );
            throw new LdapException( e.getMessage(), e );
        }
    }

    
    /**
     * deletes the entry with the given DN
     *  
     * @param dn the target entry's DN
     * @throws LdapException If the DN is not valid or if the deletion failed
     */
    public DeleteResponse delete( LdapDN dn ) throws LdapException
    {
        DeleteRequest deleteRequest = new DeleteRequest( dn );
        
        return delete( deleteRequest, null ); 
    }


    /**
     * deletes the entry with the given DN, and all its children
     *  
     * @param dn the target entry's DN
     * @return operation's response
     * @throws LdapException If the DN is not valid or if the deletion failed
     */
    public DeleteResponse deleteTree( LdapDN dn ) throws LdapException
    {
        String treeDeleteOid = "1.2.840.113556.1.4.805";
        
        if ( isControlSupported( treeDeleteOid ) ) 
        {
            DeleteRequest delRequest = new DeleteRequest( dn );
            delRequest.add( new BasicControl( treeDeleteOid ) );
            return delete( delRequest, null ); 
        }
        else
        {
            return deleteRecursive( dn, null, null );
        }
    }

    
    /**
     * deletes the entry with the given DN, and all its children
     *  
     * @param dn the target entry's DN as a String
     * @return operation's response
     * @throws LdapException If the DN is not valid or if the deletion failed
     */
    public DeleteResponse deleteTree( String dn ) throws LdapException
    {
        try
        {
            String treeDeleteOid = "1.2.840.113556.1.4.805";
            LdapDN ldapDn = new LdapDN( dn );
            
            if ( isControlSupported( treeDeleteOid ) ) 
            {
                DeleteRequest delRequest = new DeleteRequest( ldapDn );
                delRequest.add( new BasicControl( treeDeleteOid ) );
                return delete( delRequest, null ); 
            }
            else
            {
                return deleteRecursive( ldapDn, null, null );
            }
        }
        catch( InvalidNameException e )
        {
            LOG.error( e.getMessage(), e );
            throw new LdapException( e.getMessage(), e );
        }
    }
    

    /**
     * removes all child entries present under the given DN and finally the DN itself
     * 
     * Working:
     *          This is a recursive function which maintains a Map<LdapDN,Cursor>.
     *          The way the cascade delete works is by checking for children for a 
     *          given DN(i.e opening a search cursor) and if the cursor is empty
     *          then delete the DN else for each entry's DN present in cursor call
     *          deleteChildren() with the DN and the reference to the map.
     *          
     *          The reason for opening a search cursor is based on an assumption
     *          that an entry *might* contain children, consider the below DIT fragment
     *          
     *          parent
     *          /     \
     *        child1   child2
     *                 /     \
     *               grand21  grand22
     *               
     *           The below method works better in the case where the tree depth is >1 
     *          
     *   In the case of passing a non-null DeleteListener, the return value will always be null, cause the
     *   operation is treated as asynchronous and response result will be sent using the listener callback
     *   
     *  //FIXME provide another method for optimizing delete operation for a tree with depth <=1
     *          
     * @param dn the DN which will be removed after removing its children
     * @param map a map to hold the Cursor related to a DN
     * @param listener  the delete operation response listener 
     * @throws LdapException If the DN is not valid or if the deletion failed
     */
    private DeleteResponse deleteRecursive( LdapDN dn, Map<LdapDN, Cursor<SearchResponse>> cursorMap, DeleteListener listener ) throws LdapException
    {
        LOG.debug( "searching for {}", dn.getName() );
        DeleteResponse delResponse = null;
        Cursor<SearchResponse> cursor = null;
        
        try
        {
            if ( cursorMap == null )
            {
                cursorMap = new HashMap<LdapDN, Cursor<SearchResponse>>();
            }

            cursor = cursorMap.get( dn ); 
            
            if( cursor == null )
            {
                cursor = search( dn.getName(), "(objectClass=*)", SearchScope.ONELEVEL, (String[])null ); 
                LOG.debug( "putting curosr for {}", dn.getName() );
                cursorMap.put( dn, cursor );
            }
            
            if( ! cursor.next() ) // if this is a leaf entry's DN
            {
                LOG.debug( "deleting {}", dn.getName() );
                cursorMap.remove( dn );
                cursor.close();
                delResponse = delete( new DeleteRequest( dn ), listener );
            }
            else
            {
                do
                {
                    SearchResponse searchResp = cursor.get();
                    
                    if( searchResp instanceof SearchResultEntry )
                    {
                        SearchResultEntry searchResult = ( SearchResultEntry ) searchResp;
                        deleteRecursive( searchResult.getEntry().getDn(), cursorMap, listener );
                    }
                }
                while( cursor.next() );
                
                cursorMap.remove( dn );
                cursor.close();
                LOG.debug( "deleting {}", dn.getName() );
                delResponse = delete( new DeleteRequest( dn ), listener );
            }
        }
        catch( Exception e )
        {
            String msg = "Failed to delete child entries under the DN " + dn.getName();
            LOG.error( msg, e );
            throw new LdapException( msg, e );
        }
        
        return delResponse;
    }
    
    
    /**
     * Performs a synchronous delete operation based on the delete request object.
     *  
     * @param delRequest the delete operation's request
     * @return delete operation's response, null if a non-null listener value is provided
     * @throws LdapException If the DN is not valid or if the deletion failed
     */
    public DeleteResponse delete( DeleteRequest delRequest )  throws LdapException
    {
        // Just call the delete method with a null listener
        return delete( delRequest, null );
    }


    /**
     * Performs a delete operation based on the delete request object.
     *  
     * @param delRequest the delete operation's request
     * @param listener the delete operation response listener
     * @return delete operation's response, null if a non-null listener value is provided
     * @throws LdapException If the DN is not valid or if the deletion failed
     */
    public DeleteResponse delete( DeleteRequest delRequest, DeleteListener listener )  throws LdapException
    {
        checkSession();
    
        LdapMessageCodec deleteMessage = new LdapMessageCodec();
        
        int newId = messageId.incrementAndGet();
        delRequest.setMessageId( newId );
        deleteMessage.setMessageId( newId );

        DelRequestCodec delCodec = new DelRequestCodec();
        delCodec.setEntry( delRequest.getTargetDn() );

        deleteMessage.setProtocolOP( delCodec );
        setControls( delRequest.getControls(), deleteMessage );
        
        ResponseFuture deleteFuture = new ResponseFuture( deleteResponseQueue );
        futureMap.put( newId, deleteFuture );

        ldapSession.write( deleteMessage );
        
        DeleteResponse response = null;
        
        if( listener == null )
        {
            try
            {
                long timeout = getTimeout( delRequest.getTimeout() );
                response = ( DeleteResponse ) deleteFuture.get( timeout, TimeUnit.MILLISECONDS );
                
                if ( response == null )
                {
                    LOG.error( "Delete DN failed : timeout occured" );

                    throw new LdapException( TIME_OUT_ERROR );
                }
            }
            catch( InterruptedException ie )
            {
                LOG.error( OPERATION_CANCELLED, ie );
                throw new LdapException( OPERATION_CANCELLED, ie );
            }
            catch( Exception e )
            {
                LOG.error( NO_RESPONSE_ERROR );
                futureMap.remove( newId );

                LdapException ldapException = new LdapException( NO_RESPONSE_ERROR );
                ldapException.initCause( e );
                throw ldapException;
            }
        }
        else
        {
            listenerMap.put( newId, listener );
        }

        return response;
    }


    /**
     * Compares a whether a given attribute's value matches that of the 
     * existing value of the attribute present in the entry with the given DN
     *
     * @param dn the target entry's String DN
     * @param attributeName the attribute's name
     * @param value a String value with which the target entry's attribute value to be compared with
     * @return compare operation's response
     * @throws LdapException
     */
    public CompareResponse compare( String dn, String attributeName, String value ) throws LdapException
    {
        try
        {
            CompareRequest compareRequest = new CompareRequest();
            compareRequest.setEntryDn( new LdapDN( dn ) );
            compareRequest.setAttrName( attributeName );
            compareRequest.setValue( value );
            
            return compare( compareRequest, null );
        }
        catch( Exception e )
        {
            LOG.error( COMPARE_FAILED, e );
            throw new LdapException( COMPARE_FAILED, e );
        }
    }


    /**
     * Compares a whether a given attribute's value matches that of the 
     * existing value of the attribute present in the entry with the given DN
     *
     * @param dn the target entry's String DN
     * @param attributeName the attribute's name
     * @param value a byte[] value with which the target entry's attribute value to be compared with
     * @return compare operation's response
     * @throws LdapException
     */
    public CompareResponse compare( String dn, String attributeName, byte[] value ) throws LdapException
    {
        try
        {
            CompareRequest compareRequest = new CompareRequest();
            compareRequest.setEntryDn( new LdapDN( dn ) );
            compareRequest.setAttrName( attributeName );
            compareRequest.setValue( value );
            
            return compare( compareRequest, null );
        }
        catch( Exception e )
        {
            LOG.error( COMPARE_FAILED, e );
            throw new LdapException( COMPARE_FAILED, e );
        }
    }


    /**
     * Compares a whether a given attribute's value matches that of the 
     * existing value of the attribute present in the entry with the given DN
     *
     * @param dn the target entry's String DN
     * @param attributeName the attribute's name
     * @param value a Value<?> value with which the target entry's attribute value to be compared with
     * @return compare operation's response
     * @throws LdapException
     */
    public CompareResponse compare( String dn, String attributeName, Value<?> value ) throws LdapException
    {
        try
        {
            CompareRequest compareRequest = new CompareRequest();
            compareRequest.setEntryDn( new LdapDN( dn ) );
            compareRequest.setAttrName( attributeName );
            compareRequest.setValue( value );
            
            return compare( compareRequest, null );
        }
        catch( Exception e )
        {
            LOG.error( COMPARE_FAILED, e );
            throw new LdapException( COMPARE_FAILED, e );
        }
    }

    
    /**
     * Compares a whether a given attribute's value matches that of the 
     * existing value of the attribute present in the entry with the given DN
     *
     * @param dn the target entry's DN
     * @param attributeName the attribute's name
     * @param value a String value with which the target entry's attribute value to be compared with
     * @return compare operation's response
     * @throws LdapException
     */
    public CompareResponse compare( LdapDN dn, String attributeName, String value ) throws LdapException
    {
        CompareRequest compareRequest = new CompareRequest();
        compareRequest.setEntryDn( dn );
        compareRequest.setAttrName( attributeName );
        compareRequest.setValue( value );
        
        return compare( compareRequest, null );
    }

    
    /**
     * Compares a whether a given attribute's value matches that of the 
     * existing value of the attribute present in the entry with the given DN
     *
     * @param dn the target entry's DN
     * @param attributeName the attribute's name
     * @param value a byte[] value with which the target entry's attribute value to be compared with
     * @return compare operation's response
     * @throws LdapException
     */
    public CompareResponse compare( LdapDN dn, String attributeName, byte[] value ) throws LdapException
    {
        CompareRequest compareRequest = new CompareRequest();
        compareRequest.setEntryDn( dn );
        compareRequest.setAttrName( attributeName );
        compareRequest.setValue( value );
        
        return compare( compareRequest, null );
    }


    /**
     * Compares a whether a given attribute's value matches that of the 
     * existing value of the attribute present in the entry with the given DN
     *
     * @param dn the target entry's DN
     * @param attributeName the attribute's name
     * @param value a Value<?> value with which the target entry's attribute value to be compared with
     * @return compare operation's response
     * @throws LdapException
     */
    public CompareResponse compare( LdapDN dn, String attributeName, Value<?> value ) throws LdapException
    {
        CompareRequest compareRequest = new CompareRequest();
        compareRequest.setEntryDn( dn );
        compareRequest.setAttrName( attributeName );
        compareRequest.setValue( value.get() );
        
        return compare( compareRequest, null );
    }
    
    
    /**
     * compares an entry's attribute's value with that of the given value
     *   
     * @param compareRequest the CompareRequest which contains the target DN, attribute name and value
     * @return compare operation's response
     * @throws LdapException
     */
    public CompareResponse compare( CompareRequest compareRequest ) throws LdapException
    {
        return compare( compareRequest, null );
    }
    
    
    /**
     * compares an entry's attribute's value with that of the given value
     *   
     * @param compareRequest the CompareRequest which contains the target DN, attribute name and value
     * @param listener a non-null listener if provided will be called to receive this operation's response asynchronously
     * @return compare operation's response
     * @throws LdapException
     */
    public CompareResponse compare( CompareRequest compareRequest, CompareListener listener ) throws LdapException
    {
        checkSession();

        CompareRequestCodec compareReqCodec = new CompareRequestCodec();
        
        int newId = messageId.incrementAndGet();
        LdapMessageCodec message = new LdapMessageCodec();
        message.setMessageId( newId );
        compareReqCodec.setMessageId( newId );

        compareReqCodec.setEntry( compareRequest.getEntryDn() );
        compareReqCodec.setAttributeDesc( compareRequest.getAttrName() );
        compareReqCodec.setAssertionValue( compareRequest.getValue() );
        setControls( compareRequest.getControls(), compareReqCodec );
        
        message.setProtocolOP( compareReqCodec );
        
        ResponseFuture compareFuture = new ResponseFuture( compareResponseQueue );
        futureMap.put( newId, compareFuture );

        // Send the request to the server
        ldapSession.write( message );
        
        CompareResponse response = null;
        if( listener == null )
        {
            try
            {
                long timeout = getTimeout( compareRequest.getTimeout() );
                response = ( CompareResponse ) compareFuture.get( timeout, TimeUnit.MILLISECONDS );
                
                if ( response == null )
                {
                    LOG.error( "Compare failed : timeout occured" );

                    throw new LdapException( TIME_OUT_ERROR );
                }
            }
            catch( InterruptedException ie )
            {
                LOG.error( OPERATION_CANCELLED, ie );
                throw new LdapException( OPERATION_CANCELLED, ie );
            }
            catch( Exception e )
            {
                LOG.error( NO_RESPONSE_ERROR );
                futureMap.remove( newId );

                throw new LdapException( NO_RESPONSE_ERROR, e );
            }
        }
        else
        {
            listenerMap.put( newId, listener );            
        }

        return response;
    }
    
    
    /**
     * converts the CompareResponseCodec to CompareResponse.
     */
    private CompareResponse convert( CompareResponseCodec compareRespCodec )
    {
        CompareResponse compareResponse = new CompareResponse();
        
        compareResponse.setMessageId( compareRespCodec.getMessageId() );
        compareResponse.setLdapResult( convert( compareRespCodec.getLdapResult() ) );
        
        return compareResponse;
    }

    
    /**
     * converts the DeleteResponseCodec to DeleteResponse object.
     */
    private DeleteResponse convert( DelResponseCodec delRespCodec )
    {
        DeleteResponse response = new DeleteResponse();
        
        response.setMessageId( delRespCodec.getMessageId() );
        response.setLdapResult( convert( delRespCodec.getLdapResult() ) );
        
        return response;
    }
    
    
    /**
     * @see #extended(OID, byte[])
     */
    public ExtendedResponse extended( String oid ) throws LdapException
    {
        return extended( oid, null );
    }

    
    /**
     * @see #extended(OID, byte[])
     */
    public ExtendedResponse extended( String oid, byte[] value ) throws LdapException
    {
        try
        {
            return extended( new OID( oid ), value );
        }
        catch( DecoderException e )
        {
            String msg = "Failed to decode the OID " + oid;
            LOG.error( msg );
            throw new LdapException( msg, e );
        }
    }
    
    
    /**
     * @see #extended(OID, byte[])
     */
    public ExtendedResponse extended( OID oid ) throws LdapException
    {
        return extended( oid, null );
    }
    

    /**
     * sends a extended operation request to the server with the given OID and value
     * 
     * @param oid the object identifier of the extended operation
     * @param value value to be used by the extended operation, can be a null value 
     * @return extended operation's response
     * @throws LdapException
     */
    public ExtendedResponse extended( OID oid, byte[] value ) throws LdapException
    {
        ExtendedRequest extRequest = new ExtendedRequest( oid );
        extRequest.setValue( value );
        
        return extended( extRequest );
    }

    
    /**
     * @see #extended(ExtendedRequest, ExtendedListener) 
     */
    public ExtendedResponse extended( ExtendedRequest extendedRequest ) throws LdapException
    {
        return extended( extendedRequest, null );
    }
    
    
    /**
     * requests the server to perform an extended operation based on the given request.
     * 
     * @param extendedRequest the object containing the details of the extended operation to be performed
     * @param listener an ExtendedListener instance, if a non-null instance is provided the result will be sent to this listener    
     * @return extended operation's reponse, or null if a non-null listener instance is provided
     * @throws LdapException
     */
    public ExtendedResponse extended( ExtendedRequest extendedRequest, ExtendedListener listener ) throws LdapException
    {
        checkSession();
        
        ExtendedRequestCodec extReqCodec = new ExtendedRequestCodec();
        
        int newId = messageId.incrementAndGet();
        LdapMessageCodec message = new LdapMessageCodec();
        message.setMessageId( newId );
        extReqCodec.setMessageId( newId );

        extReqCodec.setRequestName( extendedRequest.getOid() );
        extReqCodec.setRequestValue( extendedRequest.getValue() );
        setControls( extendedRequest.getControls(), extReqCodec );
        
        message.setProtocolOP( extReqCodec );
        
        ResponseFuture extendedFuture = new ResponseFuture( extendedResponseQueue );
        futureMap.put( newId, extendedFuture );

        // Send the request to the server
        ldapSession.write( message );
        
        ExtendedResponse response = null;
        if( listener == null )
        {
            try
            {
                long timeout = getTimeout( extendedRequest.getTimeout() );
                response = ( ExtendedResponse ) extendedFuture.get( timeout, TimeUnit.MILLISECONDS );
                
                if ( response == null )
                {
                    LOG.error( "Extended operation failed : timeout occured" );

                    throw new LdapException( TIME_OUT_ERROR );
                }
            }
            catch( InterruptedException ie )
            {
                LOG.error( OPERATION_CANCELLED, ie );
                throw new LdapException( OPERATION_CANCELLED, ie );
            }
            catch( Exception e )
            {
                LOG.error( NO_RESPONSE_ERROR );
                futureMap.remove( newId );

                throw new LdapException( NO_RESPONSE_ERROR, e );
            }
        }
        else
        {
            listenerMap.put( newId, listener );            
        }

        return response;
    }

    
    /**
     * converts the ExtendedResponseCodec to ExtendedResponse.
     */
    private ExtendedResponse convert( ExtendedResponseCodec extRespCodec )
    {
        ExtendedResponse extResponse = new ExtendedResponse();
        
        OID oid = null;
        try
        {
            if( extRespCodec.getResponseName() != null )
            {
                oid = new OID( extRespCodec.getResponseName() );
            }
        }
        catch( DecoderException e )
        {
            // can happen in case of a PROTOCOL_ERROR result, ignore 
            //LOG.error( "invalid response name {}", extRespCodec.getResponseName() );
        }
        
        extResponse.setOid( oid );
        extResponse.setValue( extRespCodec.getResponse() );
        extResponse.setMessageId( extRespCodec.getMessageId() );
        extResponse.setLdapResult( convert( extRespCodec.getLdapResult() ) );
        
        return extResponse;
    }

    
    /**
     * checks if a control with the given OID is supported
     * 
     * @param controlOID the OID of the control
     * @return true if the control is supported, false otherwise
     */
    public boolean isControlSupported( String controlOID ) throws LdapException
    {
        return getSupportedConrols().contains( controlOID );
    }
    
    
    /**
     * get the Conrols supported by server.
     *
     * @return a list of control OIDs supported by server
     * @throws LdapException
     */
    public List<String> getSupportedConrols() throws LdapException
    {
        if( supportedControls != null )
        {
            return supportedControls;
        }
        
        if( rootDSE == null )
        {
            fetchRootDSE();
        }

        supportedControls = new ArrayList<String>();

        EntryAttribute attr = rootDSE.get( SchemaConstants.SUPPORTED_CONTROL_AT );
        Iterator<Value<?>> itr = attr.getAll();
        
        while( itr.hasNext() )
        {
            supportedControls.add( ( String ) itr.next().get() );
        }

        return supportedControls;
    }
    

    /**
     * fetches the rootDSE from the server
     * @throws LdapException
     */
    private void fetchRootDSE() throws LdapException
    {
        Cursor<SearchResponse> cursor = null;
        try
        {
            cursor = search( "", "(objectClass=*)", SearchScope.OBJECT, "*", "+" );
            cursor.next();
            SearchResultEntry searchRes = ( SearchResultEntry ) cursor.get();
            
            rootDSE = searchRes.getEntry();
        }
        catch( Exception e )
        {
            String msg = "Failed to fetch the RootDSE";
            LOG.error( msg );
            throw new LdapException( msg, e );
        }
        finally
        {
            if( cursor != null )
            {
                try
                {
                    cursor.close();
                }
                catch( Exception e )
                {
                    LOG.error( "Failed to close open cursor", e );
                }
            }
        }
    }


    /**
     * gives the configuration information of the connection
     * 
     * @return the configuration of the connection
     */
    public LdapConnectionConfig getConfig()
    {
        return config;
    }
    
}
