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


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.directory.api.ldap.codec.api.LdapApiService;
import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
import org.apache.directory.api.ldap.model.constants.AuthenticationLevel;
import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.csn.Csn;
import org.apache.directory.api.ldap.model.csn.CsnFactory;
import org.apache.directory.api.ldap.model.cursor.Cursor;
import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.entry.DefaultEntry;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.entry.Modification;
import org.apache.directory.api.ldap.model.entry.Value;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapNoPermissionException;
import org.apache.directory.api.ldap.model.exception.LdapOperationException;
import org.apache.directory.api.ldap.model.exception.LdapOtherException;
import org.apache.directory.api.ldap.model.ldif.ChangeType;
import org.apache.directory.api.ldap.model.ldif.LdifEntry;
import org.apache.directory.api.ldap.model.ldif.LdifReader;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.api.ldap.model.name.DnUtils;
import org.apache.directory.api.ldap.model.name.Rdn;
import org.apache.directory.api.ldap.model.schema.SchemaManager;
import org.apache.directory.api.ldap.util.tree.DnNode;
import org.apache.directory.api.util.DateUtils;
import org.apache.directory.api.util.Strings;
import org.apache.directory.api.util.exception.NotImplementedException;
import org.apache.directory.server.constants.ApacheSchemaConstants;
import org.apache.directory.server.constants.ServerDNConstants;
import org.apache.directory.server.core.admin.AdministrativePointInterceptor;
import org.apache.directory.server.core.api.AttributeTypeProvider;
import org.apache.directory.server.core.api.CacheService;
import org.apache.directory.server.core.api.CoreSession;
import org.apache.directory.server.core.api.DirectoryService;
import org.apache.directory.server.core.api.DnFactory;
import org.apache.directory.server.core.api.InstanceLayout;
import org.apache.directory.server.core.api.InterceptorEnum;
import org.apache.directory.server.core.api.LdapPrincipal;
import org.apache.directory.server.core.api.ObjectClassProvider;
import org.apache.directory.server.core.api.OperationEnum;
import org.apache.directory.server.core.api.OperationManager;
import org.apache.directory.server.core.api.ReferralManager;
import org.apache.directory.server.core.api.administrative.AccessControlAdministrativePoint;
import org.apache.directory.server.core.api.administrative.CollectiveAttributeAdministrativePoint;
import org.apache.directory.server.core.api.administrative.SubschemaAdministrativePoint;
import org.apache.directory.server.core.api.administrative.TriggerExecutionAdministrativePoint;
import org.apache.directory.server.core.api.changelog.ChangeLog;
import org.apache.directory.server.core.api.changelog.ChangeLogEvent;
import org.apache.directory.server.core.api.changelog.Tag;
import org.apache.directory.server.core.api.changelog.TaggableSearchableChangeLogStore;
import org.apache.directory.server.core.api.event.EventService;
import org.apache.directory.server.core.api.interceptor.BaseInterceptor;
import org.apache.directory.server.core.api.interceptor.Interceptor;
import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
import org.apache.directory.server.core.api.interceptor.context.BindOperationContext;
import org.apache.directory.server.core.api.interceptor.context.HasEntryOperationContext;
import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
import org.apache.directory.server.core.api.interceptor.context.OperationContext;
import org.apache.directory.server.core.api.journal.Journal;
import org.apache.directory.server.core.api.partition.Partition;
import org.apache.directory.server.core.api.partition.PartitionNexus;
import org.apache.directory.server.core.api.partition.PartitionTxn;
import org.apache.directory.server.core.api.schema.SchemaPartition;
import org.apache.directory.server.core.api.subtree.SubentryCache;
import org.apache.directory.server.core.api.subtree.SubtreeEvaluator;
import org.apache.directory.server.core.authn.AuthenticationInterceptor;
import org.apache.directory.server.core.authn.ppolicy.PpolicyConfigContainer;
import org.apache.directory.server.core.authz.AciAuthorizationInterceptor;
import org.apache.directory.server.core.authz.DefaultAuthorizationInterceptor;
import org.apache.directory.server.core.changelog.ChangeLogInterceptor;
import org.apache.directory.server.core.changelog.DefaultChangeLog;
import org.apache.directory.server.core.collective.CollectiveAttributeInterceptor;
import org.apache.directory.server.core.event.EventInterceptor;
import org.apache.directory.server.core.exception.ExceptionInterceptor;
import org.apache.directory.server.core.journal.DefaultJournal;
import org.apache.directory.server.core.journal.JournalInterceptor;
import org.apache.directory.server.core.normalization.NormalizationInterceptor;
import org.apache.directory.server.core.operational.OperationalAttributeInterceptor;
import org.apache.directory.server.core.referral.ReferralInterceptor;
import org.apache.directory.server.core.schema.SchemaInterceptor;
import org.apache.directory.server.core.security.TlsKeyGenerator;
import org.apache.directory.server.core.shared.DefaultCoreSession;
import org.apache.directory.server.core.shared.DefaultDnFactory;
import org.apache.directory.server.core.shared.partition.DefaultPartitionNexus;
import org.apache.directory.server.core.subtree.SubentryInterceptor;
import org.apache.directory.server.core.trigger.TriggerInterceptor;
import org.apache.directory.server.i18n.I18n;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Default implementation of {@link DirectoryService}.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class DefaultDirectoryService implements DirectoryService
{
    /** The logger */
    private static final Logger LOG = LoggerFactory.getLogger( DefaultDirectoryService.class );

    private SchemaPartition schemaPartition;

    /** A reference on the SchemaManager */
    private SchemaManager schemaManager;

    /** The LDAP Codec Service */
    private LdapApiService ldapCodecService = LdapApiServiceFactory.getSingleton();

    /** the root nexus */
    private DefaultPartitionNexus partitionNexus;

    /** whether or not server is started for the first time */
    private boolean firstStart;

    /** whether or not this instance has been shutdown */
    private boolean started;

    /** the change log service */
    private ChangeLog changeLog;

    /** the journal service */
    private Journal journal;

    /**
     * the interface used to perform various operations on this
     * DirectoryService
     */
    private OperationManager operationManager = new DefaultOperationManager( this );

    /** the distinguished name of the administrative user */
    private Dn adminDn;

    /** session used as admin for internal operations */
    private CoreSession adminSession;

    /** The referral manager */
    private ReferralManager referralManager;

    /** A flag to tell if the userPassword attribute's value must be hidden */
    private boolean passwordHidden = false;

    /** The service's CSN factory */
    private CsnFactory csnFactory;

    /** The directory instance replication ID */
    private int replicaId;

    /** remove me after implementation is completed */
    private static final String PARTIAL_IMPL_WARNING =
        "WARNING: the changelog is only partially operational and will revert\n"
            + "state without consideration of who made the original change.  All reverting "
            + "changes are made by the admin user.\n Furthermore the used controls are not at "
            + "all taken into account";

    /** The delay to wait between each sync on disk */
    private long syncPeriodMillis;

    /** The default delay to wait between sync on disk : 15 seconds */
    private static final long DEFAULT_SYNC_PERIOD = 15000;

    /** The default timeLimit : 100 entries */
    public static final int MAX_SIZE_LIMIT_DEFAULT = 100;

    /** The default timeLimit : 10 seconds */
    public static final int MAX_TIME_LIMIT_DEFAULT = 10000;

    /** The instance Id */
    private String instanceId;

    /** The server directory layout*/
    private InstanceLayout instanceLayout;

    /**
     * A flag used to shutdown the VM when stopping the server. Useful
     * when the server is standalone. If the server is embedded, we don't
     * want to shutdown the VM
     */
    private boolean exitVmOnShutdown = true; // allow by default

    /** A flag used to indicate that a shutdown hook has been installed */
    private boolean shutdownHookEnabled = true; // allow by default

    /** Manage anonymous access to entries other than the RootDSE */
    private boolean allowAnonymousAccess = false; // forbid by default

    /** Manage the basic access control checks */
    private boolean accessControlEnabled; // off by default

    /** Manage the operational attributes denormalization */
    private boolean denormalizeOpAttrsEnabled; // off by default

    /** The list of declared interceptors */
    private List<Interceptor> interceptors;
    private Map<String, Interceptor> interceptorNames;

    /** A lock to protect the interceptors List */
    private ReadWriteLock interceptorsLock = new ReentrantReadWriteLock();

    /** The read and write locks */
    private Lock readLock = interceptorsLock.readLock();
    private Lock writeLock = interceptorsLock.writeLock();

    /** A map associating a list of interceptor to each operation */
    private Map<OperationEnum, List<String>> operationInterceptors;

    /** The System partition */
    private Partition systemPartition;

    /** The set of all declared partitions */
    private Set<Partition> partitions = new HashSet<>();

    /** A list of LDIF entries to inject at startup */
    private List<? extends LdifEntry> testEntries = new ArrayList<>(); // List<Attributes>

    /** The event service */
    private EventService eventService;

    /** The maximum size for an incoming PDU */
    private int maxPDUSize = Integer.MAX_VALUE;

    /** lock file for directory service's working directory */
    private RandomAccessFile lockFile = null;

    private static final String LOCK_FILE_NAME = ".dirservice.lock";

    /** the cache service */
    private CacheService cacheService;

    /** The AccessControl AdministrativePoint cache */
    private DnNode<AccessControlAdministrativePoint> accessControlAPCache;

    /** The CollectiveAttribute AdministrativePoint cache */
    private DnNode<CollectiveAttributeAdministrativePoint> collectiveAttributeAPCache;

    /** The Subschema AdministrativePoint cache */
    private DnNode<SubschemaAdministrativePoint> subschemaAPCache;

    /** The TriggerExecution AdministrativePoint cache */
    private DnNode<TriggerExecutionAdministrativePoint> triggerExecutionAPCache;

    /** The Dn factory */
    private DnFactory dnFactory;

    /** The Subentry cache */
    SubentryCache subentryCache = new SubentryCache();

    /** The Subtree evaluator instance */
    private SubtreeEvaluator evaluator;

    /** The attribute type provider */
    private AttributeTypeProvider atProvider;

    /** The object class provider */
    private ObjectClassProvider ocProvider;


    // ------------------------------------------------------------------------
    // Constructor
    // ------------------------------------------------------------------------

    /**
     * Creates a new instance of the directory service.
     * 
     * @throws LdapException If the instance cannot be created
     */
    public DefaultDirectoryService() throws LdapException
    {
        changeLog = new DefaultChangeLog();
        journal = new DefaultJournal();
        syncPeriodMillis = DEFAULT_SYNC_PERIOD;
        csnFactory = new CsnFactory( replicaId );
        evaluator = new SubtreeEvaluator( schemaManager );
        setDefaultInterceptorConfigurations();
    }


    // ------------------------------------------------------------------------
    // C O N F I G U R A T I O N   M E T H O D S
    // ------------------------------------------------------------------------

    public void setInstanceId( String instanceId )
    {
        this.instanceId = instanceId;
    }


    public String getInstanceId()
    {
        return instanceId;
    }


    /**
     * Gets the {@link Partition}s used by this DirectoryService.
     *
     * @return the set of partitions used
     */
    public Set<? extends Partition> getPartitions()
    {
        Set<Partition> cloned = new HashSet<>();
        cloned.addAll( partitions );
        return cloned;
    }


    /**
     * Sets {@link Partition}s used by this DirectoryService.
     *
     * @param partitions the partitions to used
     */
    public void setPartitions( Set<? extends Partition> partitions )
    {
        Set<Partition> cloned = new HashSet<>();
        cloned.addAll( partitions );
        Set<String> names = new HashSet<>();

        for ( Partition partition : cloned )
        {
            String id = partition.getId();

            if ( names.contains( id ) )
            {
                LOG.warn( "Encountered duplicate partition {} identifier.", id );
            }

            names.add( id );
        }

        this.partitions = cloned;
    }


    /**
     * Returns <tt>true</tt> if access control checks are enabled.
     *
     * @return true if access control checks are enabled, false otherwise
     */
    public boolean isAccessControlEnabled()
    {
        return accessControlEnabled;
    }


    /**
     * Sets whether to enable basic access control checks or not.
     *
     * @param accessControlEnabled true to enable access control checks, false otherwise
     */
    public void setAccessControlEnabled( boolean accessControlEnabled )
    {
        this.accessControlEnabled = accessControlEnabled;
    }


    /**
     * Returns <tt>true</tt> if anonymous access is allowed on entries besides the RootDSE.
     * If the access control subsystem is enabled then access to some entries may not be
     * allowed even when full anonymous access is enabled.
     *
     * @return true if anonymous access is allowed on entries besides the RootDSE, false
     * if anonymous access is allowed to all entries.
     */
    public boolean isAllowAnonymousAccess()
    {
        return allowAnonymousAccess;
    }


    /**
     * Sets whether to allow anonymous access to entries other than the RootDSE.  If the
     * access control subsystem is enabled then access to some entries may not be allowed
     * even when full anonymous access is enabled.
     *
     * @param enableAnonymousAccess true to enable anonymous access, false to disable it
     */
    public void setAllowAnonymousAccess( boolean enableAnonymousAccess )
    {
        this.allowAnonymousAccess = enableAnonymousAccess;
    }


    /**
     * Returns interceptors in the server.
     *
     * @return the interceptors in the server.
     */
    public List<Interceptor> getInterceptors()
    {
        List<Interceptor> cloned = new ArrayList<>();

        readLock.lock();

        try
        {
            cloned.addAll( interceptors );

            return cloned;
        }
        finally
        {
            readLock.unlock();
        }
    }


    /**
     * Returns interceptors in the server for a given operation.
     *
     * @return the interceptors in the server for the given operation.
     */
    public List<String> getInterceptors( OperationEnum operation )
    {
        List<String> cloned = new ArrayList<>();

        readLock.lock();

        try
        {
            cloned.addAll( operationInterceptors.get( operation ) );

            return cloned;
        }
        finally
        {
            readLock.unlock();
        }

    }


    /**
     * Compute the list of  to call for each operation
     */
    private void initOperationsList()
    {
        writeLock.lock();

        try
        {
            operationInterceptors = new ConcurrentHashMap<>();

            for ( OperationEnum operation : OperationEnum.getOperations() )
            {
                List<String> operationList = new ArrayList<>();

                for ( Interceptor interceptor : interceptors )
                {
                    gatherInterceptors( interceptor, interceptor.getClass(), operation, operationList );
                }

                operationInterceptors.put( operation, operationList );
            }
        }
        finally
        {
            writeLock.unlock();
        }
    }


    /**
     * Recursively checks if the given interceptor can be added to the list of interceptors for a given
     * operation and adds to the list of interceptors if it implements the respective operation
     * 
     * @param interceptor the instance of the interceptor
     * @param interceptorClz the class of the interceptor
     * @param operation type of operation
     * @param selectedInterceptorList the list of selected interceptors
     */
    private void gatherInterceptors( Interceptor interceptor, Class<?> interceptorClz, OperationEnum operation,
        List<String> selectedInterceptorList )
    {
        // We stop recursing when we reach the Base class
        if ( ( interceptorClz == null ) || ( interceptorClz == BaseInterceptor.class ) )
        {
            return;
        }

        // We don't call getMethods() because it would get back the default methods
        // from the BaseInterceptor, something we don't want.
        Method[] methods = interceptorClz.getDeclaredMethods();

        for ( Method method : methods )
        {
            Class<?>[] param = method.getParameterTypes();

            // check for the correct signature
            if ( ( param != null ) && ( param.length == 1 ) 
                    && OperationContext.class.isAssignableFrom( param[0] ) && method.getName().equals( operation.getMethodName() ) )
            {
                if ( !selectedInterceptorList.contains( interceptor.getName() ) )
                {
                    selectedInterceptorList.add( interceptor.getName() );
                }

                break;
            }
        }

        // Recurse on extended classes, as we have used getDeclaredMethods() instead of getmethods()
        gatherInterceptors( interceptor, interceptorClz.getSuperclass(), operation, selectedInterceptorList );
    }


    /**
     * Add an interceptor to the list of interceptors to call for each operation
     * @throws LdapException
     */
    private void addInterceptor( Interceptor interceptor, int position ) throws LdapException
    {
        // First, init the interceptor
        interceptor.init( this );

        writeLock.lock();

        try
        {
            for ( OperationEnum operation : OperationEnum.getOperations() )
            {
                List<String> operationList = operationInterceptors.get( operation );

                Method[] methods = interceptor.getClass().getDeclaredMethods();

                for ( Method method : methods )
                {
                    if ( method.getName().equals( operation.getMethodName() ) )
                    {
                        if ( position == -1 )
                        {
                            operationList.add( interceptor.getName() );
                        }
                        else
                        {
                            operationList.add( position, interceptor.getName() );
                        }

                        break;
                    }
                }
            }

            interceptorNames.put( interceptor.getName(), interceptor );

            if ( position == -1 )
            {
                interceptors.add( interceptor );
            }
            else
            {
                interceptors.add( position, interceptor );
            }
        }
        finally
        {
            writeLock.unlock();
        }
    }


    /**
     * Remove an interceptor to the list of interceptors to call for each operation
     */
    private void removeOperationsList( String interceptorName )
    {
        Interceptor interceptor = interceptorNames.get( interceptorName );

        writeLock.lock();

        try
        {
            for ( OperationEnum operation : OperationEnum.getOperations() )
            {
                List<String> operationList = operationInterceptors.get( operation );

                Method[] methods = interceptor.getClass().getDeclaredMethods();

                for ( Method method : methods )
                {
                    if ( method.getName().equals( operation.getMethodName() ) )
                    {
                        operationList.remove( interceptor.getName() );

                        break;
                    }
                }
            }

            interceptorNames.remove( interceptorName );
            interceptors.remove( interceptor );
        }
        finally
        {
            writeLock.unlock();
        }
    }


    /**
     * Sets the interceptors in the server.
     *
     * @param interceptors the interceptors to be used in the server.
     */
    public void setInterceptors( List<Interceptor> interceptors )
    {
        Map<String, Interceptor> interceptorNames = new ConcurrentHashMap<>();

        // Check if we don't have duplicate names in the interceptors list
        for ( Interceptor interceptor : interceptors )
        {
            if ( interceptorNames.containsKey( interceptor.getName() ) )
            {
                LOG.warn( "Encountered duplicate definitions for {} interceptor", interceptor.getName() );
                continue;
            }

            interceptorNames.put( interceptor.getName(), interceptor );
        }

        this.interceptors = interceptors;
        this.interceptorNames = interceptorNames;

        // Now update the Map that connect each operation with the list of interceptors.
        initOperationsList();
    }


    /**
     * Initialize the interceptors
     */
    private void initInterceptors() throws LdapException
    {
        for ( Interceptor interceptor : interceptors )
        {
            interceptor.init( this );
        }
    }


    /**
     * Returns test directory entries({@link LdifEntry}) to be loaded while
     * bootstrapping.
     *
     * @return test entries to load during bootstrapping
     */
    public List<LdifEntry> getTestEntries()
    {
        List<LdifEntry> cloned = new ArrayList<>();
        cloned.addAll( testEntries );

        return cloned;
    }


    /**
     * Sets test directory entries to be loaded while bootstrapping.
     *
     * @param testEntries the test entries to load while bootstrapping
     */
    public void setTestEntries( List<? extends LdifEntry> testEntries )
    {
        //noinspection MismatchedQueryAndUpdateOfCollection
        List<LdifEntry> cloned = new ArrayList<>();
        cloned.addAll( testEntries );
        this.testEntries = testEntries;
    }


    /**
     * {@inheritDoc}
     */
    public InstanceLayout getInstanceLayout()
    {
        return instanceLayout;
    }


    /**
     * {@inheritDoc}
     */
    public void setInstanceLayout( InstanceLayout instanceLayout ) throws IOException
    {
        this.instanceLayout = instanceLayout;

        // Create the directories if they are missing
        if ( !instanceLayout.getInstanceDirectory().exists() && !instanceLayout.getInstanceDirectory().mkdirs() )
        {
            throw new IOException( I18n.err( I18n.ERR_112_COULD_NOT_CREATE_DIRECTORY,
                instanceLayout.getInstanceDirectory() ) );
        }

        if ( !instanceLayout.getLogDirectory().exists() && !instanceLayout.getLogDirectory().mkdirs() )
        {
            throw new IOException( I18n.err( I18n.ERR_112_COULD_NOT_CREATE_DIRECTORY,
                instanceLayout.getLogDirectory() ) );
        }

        if ( !instanceLayout.getRunDirectory().exists() && !instanceLayout.getRunDirectory().mkdirs() )
        {
            throw new IOException( I18n.err( I18n.ERR_112_COULD_NOT_CREATE_DIRECTORY,
                instanceLayout.getRunDirectory() ) );
        }

        if ( !instanceLayout.getPartitionsDirectory().exists() && !instanceLayout.getPartitionsDirectory().mkdirs() )
        {
            throw new IOException( I18n.err( I18n.ERR_112_COULD_NOT_CREATE_DIRECTORY,
                instanceLayout.getPartitionsDirectory() ) );
        }

        if ( !instanceLayout.getConfDirectory().exists() && !instanceLayout.getConfDirectory().mkdirs() )
        {
            throw new IOException( I18n.err( I18n.ERR_112_COULD_NOT_CREATE_DIRECTORY,
                instanceLayout.getConfDirectory() ) );
        }
    }


    public void setShutdownHookEnabled( boolean shutdownHookEnabled )
    {
        this.shutdownHookEnabled = shutdownHookEnabled;
    }


    public boolean isShutdownHookEnabled()
    {
        return shutdownHookEnabled;
    }


    public void setExitVmOnShutdown( boolean exitVmOnShutdown )
    {
        this.exitVmOnShutdown = exitVmOnShutdown;
    }


    public boolean isExitVmOnShutdown()
    {
        return exitVmOnShutdown;
    }


    public void setSystemPartition( Partition systemPartition )
    {
        this.systemPartition = systemPartition;
    }


    public Partition getSystemPartition()
    {
        return systemPartition;
    }


    /**
     * return true if the operational attributes must be normalized when returned
     */
    public boolean isDenormalizeOpAttrsEnabled()
    {
        return denormalizeOpAttrsEnabled;
    }


    /**
     * Sets whether the operational attributes are denormalized when returned
     * @param denormalizeOpAttrsEnabled The flag value
     */
    public void setDenormalizeOpAttrsEnabled( boolean denormalizeOpAttrsEnabled )
    {
        this.denormalizeOpAttrsEnabled = denormalizeOpAttrsEnabled;
    }


    /**
     * {@inheritDoc}
     */
    public ChangeLog getChangeLog()
    {
        return changeLog;
    }


    /**
     * {@inheritDoc}
     */
    public Journal getJournal()
    {
        return journal;
    }


    /**
     * {@inheritDoc}
     */
    public void setChangeLog( ChangeLog changeLog )
    {
        this.changeLog = changeLog;
    }


    /**
     * {@inheritDoc}
     */
    public void setJournal( Journal journal )
    {
        this.journal = journal;
    }


    /**
     * {@inheritDoc}
     */
    public void addPartition( Partition partition ) throws LdapException
    {
        partition.setSchemaManager( schemaManager );

        // can be null when called before starting up
        if ( partitionNexus != null )
        {
            partitionNexus.addContextPartition( partition );
        }

        // Now, add the partition to the set of managed partitions
        partitions.add( partition );
    }


    /**
     * {@inheritDoc}
     */
    public void removePartition( Partition partition ) throws LdapException
    {
        // Do the backend cleanup first
        // can be null when called before starting up
        if ( partitionNexus != null )
        {
            partitionNexus.removeContextPartition( partition.getSuffixDn().getNormName() );
        }

        // And update the set of managed partitions
        partitions.remove( partition );
    }


    // ------------------------------------------------------------------------
    // BackendSubsystem Interface Method Implementations
    // ------------------------------------------------------------------------
    /**
     * Define a default list of interceptors that has to be used if no other
     * configuration is defined.
     */
    private void setDefaultInterceptorConfigurations()
    {
        // Set default interceptor chains
        List<Interceptor> list = new ArrayList<>();

        list.add( new NormalizationInterceptor() );
        list.add( new AuthenticationInterceptor() );
        list.add( new ReferralInterceptor() );
        list.add( new AciAuthorizationInterceptor() );
        list.add( new DefaultAuthorizationInterceptor() );
        list.add( new AdministrativePointInterceptor() );
        list.add( new ExceptionInterceptor() );
        list.add( new SchemaInterceptor() );
        list.add( new OperationalAttributeInterceptor() );
        list.add( new CollectiveAttributeInterceptor() );
        list.add( new SubentryInterceptor() );
        list.add( new EventInterceptor() );
        list.add( new TriggerInterceptor() );
        list.add( new ChangeLogInterceptor() );
        list.add( new JournalInterceptor() );

        setInterceptors( list );
    }


    public CoreSession getAdminSession()
    {
        return adminSession;
    }


    /**
     * Get back an anonymous session
     */
    public CoreSession getSession()
    {
        return new DefaultCoreSession( new LdapPrincipal( schemaManager ), this );
    }


    /** 
     * Get back a session for a given principal
     */
    public CoreSession getSession( LdapPrincipal principal )
    {
        return new DefaultCoreSession( principal, this );
    }


    /**
     * Get back a session for the give user and credentials bound with Simple Bind
     */
    public CoreSession getSession( Dn principalDn, byte[] credentials ) throws LdapException
    {
        synchronized ( this )
        {
            if ( !started )
            {
                throw new IllegalStateException( "Service has not started." );
            }
        }

        BindOperationContext bindContext = new BindOperationContext( null );
        bindContext.setCredentials( credentials );
        
        if ( principalDn.isSchemaAware() )
        {
            bindContext.setDn( principalDn );
        }
        else
        {
            bindContext.setDn( new Dn( schemaManager, principalDn ) );
        }
        
        bindContext.setInterceptors( getInterceptors( OperationEnum.BIND ) );

        operationManager.bind( bindContext );

        return bindContext.getSession();
    }


    /**
     * Get back a session for a given user bound with SASL Bind
     */
    public CoreSession getSession( Dn principalDn, byte[] credentials, String saslMechanism, String saslAuthId )
        throws LdapException
    {
        synchronized ( this )
        {
            if ( !started )
            {
                throw new IllegalStateException( "Service has not started." );

            }
        }

        BindOperationContext bindContext = new BindOperationContext( null );
        bindContext.setTransaction( partitionNexus.beginReadTransaction() );
        bindContext.setCredentials( credentials );

        if ( principalDn.isSchemaAware() )
        {
            bindContext.setDn( principalDn );
        }
        else
        {
            bindContext.setDn( new Dn( schemaManager, principalDn ) );
        }

        bindContext.setSaslMechanism( saslMechanism );
        bindContext.setInterceptors( getInterceptors( OperationEnum.BIND ) );

        operationManager.bind( bindContext );

        return bindContext.getSession();
    }


    public long revert() throws LdapException
    {
        if ( changeLog == null || !changeLog.isEnabled() )
        {
            throw new IllegalStateException( I18n.err( I18n.ERR_310 ) );
        }

        Tag latest = changeLog.getLatest();

        if ( null != latest )
        {
            if ( latest.getRevision() < changeLog.getCurrentRevision() )
            {
                return revert( latest.getRevision() );
            }
            else
            {
                LOG.info( "Ignoring request to revert without changes since the latest tag." );
                return changeLog.getCurrentRevision();
            }
        }

        throw new IllegalStateException( I18n.err( I18n.ERR_311 ) );
    }


    /**
     * We handle the ModDN/ModRDN operation for the revert here.
     */
    private void moddn( Dn oldDn, Dn newDn, boolean delOldRdn ) throws LdapException
    {
        if ( oldDn.size() == 0 )
        {
            throw new LdapNoPermissionException( I18n.err( I18n.ERR_312 ) );
        }

        // calculate parents
        Dn oldBase = oldDn.getParent();
        Dn newBase = newDn.getParent();

        // Compute the Rdn for each of the Dn
        Rdn newRdn = newDn.getRdn();
        Rdn oldRdn = oldDn.getRdn();

        /*
         * We need to determine if this rename operation corresponds to a simple
         * Rdn name change or a move operation.  If the two names are the same
         * except for the Rdn then it is a simple modifyRdn operation.  If the
         * names differ in size or have a different baseDN then the operation is
         * a move operation.  Furthermore if the Rdn in the move operation
         * changes it is both an Rdn change and a move operation.
         */
        if ( ( oldDn.size() == newDn.size() ) && oldBase.equals( newBase ) )
        {
            adminSession.rename( oldDn, newRdn, delOldRdn );
        }
        else
        {
            Dn target = newDn.getParent();

            if ( newRdn.equals( oldRdn ) )
            {
                adminSession.move( oldDn, target );
            }
            else
            {
                adminSession.moveAndRename( oldDn, target, newRdn, delOldRdn );
            }
        }
    }


    public long revert( long revision ) throws LdapException
    {
        if ( changeLog == null || !changeLog.isEnabled() )
        {
            throw new IllegalStateException( I18n.err( I18n.ERR_310 ) );
        }

        if ( revision < 0 )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_239 ) );
        }

        if ( revision >= changeLog.getChangeLogStore().getCurrentRevision() )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_314 ) );
        }

        Cursor<ChangeLogEvent> cursor = changeLog.getChangeLogStore().findAfter( revision );

        /*
         * BAD, BAD, BAD!!!
         *
         * No synchronization no nothing.  Just getting this to work for now
         * so we can revert tests.  Any production grade use of this feature
         * needs to synchronize on all changes while the revert is in progress.
         *
         * How about making this operation transactional?
         *
         * First of all just stop using JNDI and construct the operations to
         * feed into the interceptor pipeline.
         *
         * TODO review this code.
         */

        try
        {
            LOG.warn( PARTIAL_IMPL_WARNING );
            cursor.afterLast();

            while ( cursor.previous() ) // apply ldifs in reverse order
            {
                ChangeLogEvent event = cursor.get();
                List<LdifEntry> reverses = event.getReverseLdifs();

                for ( LdifEntry reverse : reverses )
                {
                    switch ( reverse.getChangeType().getChangeType() )
                    {
                        case ChangeType.ADD_ORDINAL:
                            adminSession.add(
                                new DefaultEntry( schemaManager, reverse.getEntry() ), true );
                            break;

                        case ChangeType.DELETE_ORDINAL:
                            adminSession.delete( reverse.getDn(), true );
                            break;

                        case ChangeType.MODIFY_ORDINAL:
                            List<Modification> mods = reverse.getModifications();

                            adminSession.modify( reverse.getDn(), mods, true );
                            break;

                        case ChangeType.MODDN_ORDINAL:
                            // NO BREAK - both ModDN and ModRDN handling is the same

                        case ChangeType.MODRDN_ORDINAL:
                            Dn forwardDn = event.getForwardLdif().getDn();
                            Dn reverseDn = reverse.getDn();

                            moddn( reverseDn, forwardDn, reverse.isDeleteOldRdn() );

                            break;

                        default:
                            LOG.error( I18n.err( I18n.ERR_75 ) );
                            throw new NotImplementedException( I18n.err( I18n.ERR_76, reverse.getChangeType() ) );
                    }
                }
            }
        }
        catch ( Exception e )
        {
            throw new LdapOperationException( e.getMessage(), e );
        }
        finally
        {
            try
            {
                cursor.close();
            }
            catch ( Exception e )
            {
                throw new LdapOperationException( e.getMessage(), e );
            }
        }

        return changeLog.getCurrentRevision();
    }


    public OperationManager getOperationManager()
    {
        return operationManager;
    }


    /**
     * @throws LdapException if the LDAP server cannot be started
     */
    public synchronized void startup() throws LdapException
    {
        if ( started )
        {
            return;
        }

        lockWorkDir();

        if ( shutdownHookEnabled )
        {
            Runtime.getRuntime().addShutdownHook( new Thread( new Runnable()
            {
                public void run()
                {
                    try
                    {
                        shutdown();
                    }
                    catch ( Exception e )
                    {
                        LOG.warn( "Failed to shut down the directory service: "
                            + DefaultDirectoryService.this.instanceId, e );
                    }
                }
            }, "ApacheDS Shutdown Hook (" + instanceId + ')' ) );

            LOG.info( "ApacheDS shutdown hook has been registered with the runtime." );
        }
        else if ( LOG.isWarnEnabled() )
        {
            LOG.warn( "ApacheDS shutdown hook has NOT been registered with the runtime."
                + "  This default setting for standalone operation has been overriden." );
        }

        initialize();
        showSecurityWarnings();

        started = true;

        if ( !testEntries.isEmpty() )
        {
            createTestEntries();
        }
    }


    public synchronized void sync() throws LdapException
    {
        if ( !started )
        {
            return;
        }

        this.changeLog.sync();
        this.partitionNexus.sync();
    }


    public synchronized void shutdown() throws LdapException
    {
        LOG.debug( "+++ DirectoryService Shutdown required" );

        if ( !started )
        {
            return;
        }

        // --------------------------------------------------------------------
        // Shutdown the sync thread
        // --------------------------------------------------------------------
        LOG.debug( "--- Syncing the nexus " );
        LOG.debug( "--- Flushing everything before quitting" );
        operationManager.lockWrite();
        partitionNexus.sync();
        operationManager.unlockWrite();

        // --------------------------------------------------------------------
        // Shutdown the changelog
        // --------------------------------------------------------------------
        LOG.debug( "--- Syncing the changeLog " );
        changeLog.sync();
        changeLog.destroy();

        // --------------------------------------------------------------------
        // Shutdown the journal if enabled
        // --------------------------------------------------------------------
        if ( journal.isEnabled() )
        {
            LOG.debug( "--- Destroying the journal " );
            journal.destroy();
        }

        
        // --------------------------------------------------------------------
        // Shutdown the partition
        // --------------------------------------------------------------------

        LOG.debug( "--- Destroying the nexus" );
        partitionNexus.destroy( null );
        
        // --------------------------------------------------------------------
        // Shutdown the interceptors
        // --------------------------------------------------------------------
        LOG.debug( "--- Destroying the interceptors" );
        
        for ( Interceptor interceptor : interceptors )
        {
            interceptor.destroy();
        }

        // --------------------------------------------------------------------
        // And shutdown the server
        // --------------------------------------------------------------------
        LOG.debug( "--- Deleting the cache service" );
        cacheService.destroy();

        LOG.debug( "---Deleting the DnCache" );
        dnFactory = null;

        if ( lockFile != null )
        {
            try
            {
                lockFile.close();
                // no need to delete the lock file
            }
            catch ( IOException e )
            {
                LOG.warn( "couldn't delete the lock file {}", LOCK_FILE_NAME );
            }
        }

        LOG.debug( "+++ DirectoryService stopped" );
        started = false;
    }


    /**
     * @return The referral manager
     */
    public ReferralManager getReferralManager()
    {
        return referralManager;
    }


    /**
     * Set the referralManager
     * @param referralManager The initialized referralManager
     */
    public void setReferralManager( ReferralManager referralManager )
    {
        this.referralManager = referralManager;
    }


    /**
     * @return the SchemaManager
     */
    public SchemaManager getSchemaManager()
    {
        return schemaManager;
    }


    /**
     * Set the SchemaManager instance.
     *
     * @param schemaManager The server schemaManager
     */
    public void setSchemaManager( SchemaManager schemaManager )
    {
        this.schemaManager = schemaManager;
    }


    public LdapApiService getLdapCodecService()
    {
        return ldapCodecService;
    }


    /**
     * {@inheritDoc}
     */
    public SchemaPartition getSchemaPartition()
    {
        return schemaPartition;
    }


    /**
     * {@inheritDoc}
     */
    public void setSchemaPartition( SchemaPartition schemaPartition )
    {
        this.schemaPartition = schemaPartition;
    }


    public DefaultPartitionNexus getPartitionNexus()
    {
        return partitionNexus;
    }


    public boolean isFirstStart()
    {
        return firstStart;
    }


    public synchronized boolean isStarted()
    {
        return started;
    }


    public Entry newEntry( Dn dn )
    {
        return new DefaultEntry( schemaManager, dn );
    }
    
    
    /**
     * Add a new entry into the server
     */
    private void addEntry( Entry serverEntry ) throws LdapException
    {
        Partition partition = partitionNexus.getPartition( serverEntry.getDn() );
        AddOperationContext addContext = new AddOperationContext( adminSession, serverEntry );
        PartitionTxn partitionTxn = null;

        try
        {
            partitionTxn = partition.beginWriteTransaction();
            addContext.setTransaction( partitionTxn );
            addContext.setPartition( partition );
            partitionNexus.add( addContext );
            partitionTxn.commit();
        }
        catch ( LdapException le )
        {
            try
            {
                partitionTxn.abort();
            }
            catch ( IOException ioe )
            {
                throw new LdapOtherException( ioe.getMessage(), ioe );
            }
            
            throw le;
        }
        catch ( IOException ioe )
        {
            try
            {
                partitionTxn.abort();
            }
            catch ( IOException ioe2 )
            {
                throw new LdapOtherException( ioe2.getMessage(), ioe2 );
            }
            
            throw new LdapOtherException( ioe.getMessage(), ioe );
        }
    }


    /**
     * Returns true if we had to create the bootstrap entries on the first
     * start of the server.  Otherwise if all entries exist, meaning none
     * had to be created, then we are not starting for the first time.
     *
     * @return true if the bootstrap entries had to be created, false otherwise
     * @throws LdapException if entries cannot be created
     */
    private boolean createBootstrapEntries() throws LdapException, IOException
    {
        boolean firstStart = false;

        // -------------------------------------------------------------------
        // create admin entry
        // -------------------------------------------------------------------

        /*
         * If the admin entry is there, then the database was already created
         */
        Partition partition = partitionNexus.getPartition( adminDn );
        
        try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
        {
            HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( adminSession, adminDn );
            hasEntryContext.setPartition( partition );
            hasEntryContext.setTransaction( partitionTxn );
            
            if ( !partitionNexus.hasEntry( hasEntryContext ) )
            {
                firstStart = true;
    
                Entry serverEntry = new DefaultEntry( schemaManager, adminDn );
    
                serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
                    SchemaConstants.TOP_OC,
                    SchemaConstants.PERSON_OC,
                    SchemaConstants.ORGANIZATIONAL_PERSON_OC,
                    SchemaConstants.INET_ORG_PERSON_OC );
    
                serverEntry.put( SchemaConstants.UID_AT, PartitionNexus.ADMIN_UID );
                serverEntry.put( SchemaConstants.USER_PASSWORD_AT, PartitionNexus.ADMIN_PASSWORD_BYTES );
                serverEntry.put( SchemaConstants.DISPLAY_NAME_AT, "Directory Superuser" );
                serverEntry.put( SchemaConstants.CN_AT, "system administrator" );
                serverEntry.put( SchemaConstants.SN_AT, "administrator" );
                serverEntry.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED );
                serverEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
                serverEntry.put( SchemaConstants.DISPLAY_NAME_AT, "Directory Superuser" );
                serverEntry.add( SchemaConstants.ENTRY_CSN_AT, getCSN().toString() );
                serverEntry.add( SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString() );
    
                TlsKeyGenerator.addKeyPair( serverEntry );
                
                addEntry( serverEntry );
            }
        }

        // -------------------------------------------------------------------
        // create system users area
        // -------------------------------------------------------------------

        Dn userDn = getDnFactory().create( ServerDNConstants.USERS_SYSTEM_DN );
        partition = partitionNexus.getPartition( userDn );

        try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
        {
            HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( adminSession, userDn );
            hasEntryContext.setPartition( partition );
            hasEntryContext.setTransaction( partitionTxn );
            
            if ( !partitionNexus.hasEntry( hasEntryContext ) )
            {
                firstStart = true;
    
                Entry serverEntry = new DefaultEntry( schemaManager, userDn );
    
                serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
                    SchemaConstants.TOP_OC,
                    SchemaConstants.ORGANIZATIONAL_UNIT_OC );
    
                serverEntry.put( SchemaConstants.OU_AT, "users" );
                serverEntry.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED );
                serverEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
                serverEntry.add( SchemaConstants.ENTRY_CSN_AT, getCSN().toString() );
                serverEntry.add( SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString() );
                
                addEntry( serverEntry );
            }
        }

        // -------------------------------------------------------------------
        // create system groups area
        // -------------------------------------------------------------------

        Dn groupDn = getDnFactory().create( ServerDNConstants.GROUPS_SYSTEM_DN );
        partition = partitionNexus.getPartition( groupDn );

        try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
        {
            HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( adminSession, groupDn );
            hasEntryContext.setPartition( partition );
            hasEntryContext.setTransaction( partitionTxn );
            
            if ( !partitionNexus.hasEntry( hasEntryContext ) )
            {
                firstStart = true;
    
                Entry serverEntry = new DefaultEntry( schemaManager, groupDn );
    
                serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
                    SchemaConstants.TOP_OC,
                    SchemaConstants.ORGANIZATIONAL_UNIT_OC );
    
                serverEntry.put( SchemaConstants.OU_AT, "groups" );
                serverEntry.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED );
                serverEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
                serverEntry.add( SchemaConstants.ENTRY_CSN_AT, getCSN().toString() );
                serverEntry.add( SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString() );
    
                addEntry( serverEntry );
            }
        }
        
        // -------------------------------------------------------------------
        // create administrator group
        // -------------------------------------------------------------------

        Dn name = getDnFactory().create( ServerDNConstants.ADMINISTRATORS_GROUP_DN );
        partition = partitionNexus.getPartition( name );

        try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
        {
            HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( adminSession, name );
            hasEntryContext.setPartition( partition );
            hasEntryContext.setTransaction( partitionTxn );
            
            if ( !partitionNexus.hasEntry( hasEntryContext ) )
            {
                firstStart = true;
    
                Entry serverEntry = new DefaultEntry( schemaManager, name );
    
                serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
                    SchemaConstants.TOP_OC,
                    SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC );
    
                serverEntry.put( SchemaConstants.CN_AT, "Administrators" );
                serverEntry.put( SchemaConstants.UNIQUE_MEMBER_AT, ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED );
                serverEntry.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED );
                serverEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
                serverEntry.add( SchemaConstants.ENTRY_CSN_AT, getCSN().toString() );
                serverEntry.add( SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString() );
    
                addEntry( serverEntry );
            }
        }

        // -------------------------------------------------------------------
        // create system configuration area
        // -------------------------------------------------------------------

        Dn configurationDn = getDnFactory().create( "ou=configuration,ou=system" );
        partition = partitionNexus.getPartition( configurationDn );

        try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
        {
            HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( adminSession, configurationDn );
            hasEntryContext.setPartition( partition );
            hasEntryContext.setTransaction( partitionTxn );
            
            if ( !partitionNexus.hasEntry( hasEntryContext ) )
            {
                firstStart = true;
    
                Entry serverEntry = new DefaultEntry( schemaManager, configurationDn );
                serverEntry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC,
                    SchemaConstants.ORGANIZATIONAL_UNIT_OC );
    
                serverEntry.put( SchemaConstants.OU_AT, "configuration" );
                serverEntry.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED );
                serverEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
                serverEntry.add( SchemaConstants.ENTRY_CSN_AT, getCSN().toString() );
                serverEntry.add( SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString() );
    
                addEntry( serverEntry );
            }
        }

        // -------------------------------------------------------------------
        // create system configuration area for partition information
        // -------------------------------------------------------------------

        Dn partitionsDn = getDnFactory().create( "ou=partitions,ou=configuration,ou=system" );
        partition = partitionNexus.getPartition( partitionsDn );

        try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
        {
            HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( adminSession, partitionsDn );
            hasEntryContext.setPartition( partition );
            hasEntryContext.setTransaction( partitionTxn );
            
            if ( !partitionNexus.hasEntry( hasEntryContext ) )
            {
                firstStart = true;
    
                Entry serverEntry = new DefaultEntry( schemaManager, partitionsDn );
                serverEntry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC,
                    SchemaConstants.ORGANIZATIONAL_UNIT_OC );
                serverEntry.put( SchemaConstants.OU_AT, "partitions" );
                serverEntry.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED );
                serverEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
                serverEntry.add( SchemaConstants.ENTRY_CSN_AT, getCSN().toString() );
                serverEntry.add( SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString() );
    
                addEntry( serverEntry );
            }
        }

        // -------------------------------------------------------------------
        // create system configuration area for services
        // -------------------------------------------------------------------

        Dn servicesDn = getDnFactory().create( "ou=services,ou=configuration,ou=system" );
        partition = partitionNexus.getPartition( servicesDn );

        try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
        {
            HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( adminSession, servicesDn );
            hasEntryContext.setPartition( partition );
            hasEntryContext.setTransaction( partitionTxn );
            
            if ( !partitionNexus.hasEntry( hasEntryContext ) )
            {
                firstStart = true;
    
                Entry serverEntry = new DefaultEntry( schemaManager, servicesDn );
                serverEntry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC,
                    SchemaConstants.ORGANIZATIONAL_UNIT_OC );
    
                serverEntry.put( SchemaConstants.OU_AT, "services" );
                serverEntry.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED );
                serverEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
                serverEntry.add( SchemaConstants.ENTRY_CSN_AT, getCSN().toString() );
                serverEntry.add( SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString() );
    
                addEntry( serverEntry );
            }
        }

        // -------------------------------------------------------------------
        // create system configuration area for interceptors
        // -------------------------------------------------------------------

        Dn interceptorsDn = getDnFactory().create( "ou=interceptors,ou=configuration,ou=system" );
        partition = partitionNexus.getPartition( interceptorsDn );

        try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
        {
            HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( adminSession, interceptorsDn );
            hasEntryContext.setPartition( partition );
            hasEntryContext.setTransaction( partitionTxn );
            
            if ( !partitionNexus.hasEntry( hasEntryContext ) )
            {
                firstStart = true;
    
                Entry serverEntry = new DefaultEntry( schemaManager, interceptorsDn );
                serverEntry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC,
                    SchemaConstants.ORGANIZATIONAL_UNIT_OC );
    
                serverEntry.put( SchemaConstants.OU_AT, "interceptors" );
                serverEntry.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED );
                serverEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
                serverEntry.add( SchemaConstants.ENTRY_CSN_AT, getCSN().toString() );
                serverEntry.add( SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString() );
    
                addEntry( serverEntry );
            }
        }

        // -------------------------------------------------------------------
        // create system preferences area
        // -------------------------------------------------------------------

        Dn sysPrefRootDn = getDnFactory().create( ServerDNConstants.SYSPREFROOT_SYSTEM_DN );
        partition = partitionNexus.getPartition( sysPrefRootDn );

        try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
        {
            HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( adminSession, sysPrefRootDn );
            hasEntryContext.setPartition( partition );
            hasEntryContext.setTransaction( partitionTxn );
            
            if ( !partitionNexus.hasEntry( hasEntryContext ) )
            {
                firstStart = true;
    
                Entry serverEntry = new DefaultEntry( schemaManager, sysPrefRootDn );
                serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
                    SchemaConstants.TOP_OC,
                    SchemaConstants.ORGANIZATIONAL_UNIT_OC,
                    SchemaConstants.EXTENSIBLE_OBJECT_OC );
    
                serverEntry.put( "prefNodeName", "sysPrefRoot" );
                serverEntry.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED );
                serverEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
                serverEntry.add( SchemaConstants.ENTRY_CSN_AT, getCSN().toString() );
                serverEntry.add( SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString() );
    
                addEntry( serverEntry );
            }
        }

        return firstStart;
    }


    /**
     * Displays security warning messages if any possible secutiry issue is found.
     * @throws LdapException if there are failures parsing and accessing internal structures
     */
    // made protected as per the request in DIRSERVER-1920
    protected void showSecurityWarnings() throws LdapException
    {
        // Warn if the default password is not changed.
        boolean needToChangeAdminPassword;

        Dn admin = getDnFactory().create( ServerDNConstants.ADMIN_SYSTEM_DN );
        Partition partition = partitionNexus.getPartition( admin );
        LookupOperationContext lookupContext = new LookupOperationContext( adminSession, admin );
        lookupContext.setPartition( partition );
        
        Entry adminEntry;

        try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
        {
            lookupContext.setTransaction( partitionTxn );
            adminEntry = partitionNexus.lookup( lookupContext );
        }
        catch ( IOException ioe )
        {
            throw new LdapOtherException( ioe.getMessage(), ioe );
        }
        
        Value userPassword = adminEntry.get( SchemaConstants.USER_PASSWORD_AT ).get();
        needToChangeAdminPassword = Arrays.equals( PartitionNexus.ADMIN_PASSWORD_BYTES, userPassword.getBytes() );

        if ( needToChangeAdminPassword )
        {
            LOG.warn( "You didn't change the admin password of directory service instance '{}'.  "
                + "Please update the admin password as soon as possible to prevent a possible security breach.", instanceId );
        }
    }


    /**
     * Adds test entries into the core.
     *
     * TODO this may no longer be needed when JNDI is not used for bootstrapping
     *
     * @throws LdapException if the creation of test entries fails.
     */
    private void createTestEntries() throws LdapException
    {
        for ( LdifEntry testEntry : testEntries )
        {
            try
            {
                LdifEntry ldifEntry = testEntry.clone();
                Entry entry = ldifEntry.getEntry();
                String dn = ldifEntry.getDn().getName();

                try
                {
                    getAdminSession().add( new DefaultEntry( schemaManager, entry ) );
                }
                catch ( Exception e )
                {
                    LOG.warn( dn + " test entry already exists.", e );
                }
            }
            catch ( CloneNotSupportedException cnse )
            {
                LOG.warn( "Cannot clone the entry ", cnse );
            }
        }
    }


    private void initializeSystemPartition() throws LdapException, IOException
    {
        Partition system = getSystemPartition();

        // Add root context entry for system partition
        Dn systemSuffixDn = getDnFactory().create( ServerDNConstants.SYSTEM_DN );
        CoreSession admin = getAdminSession();

        HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( admin, systemSuffixDn );
        Partition partition = getPartitionNexus().getPartition( systemSuffixDn );
        hasEntryContext.setPartition( partition );
        
        try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
        {
            hasEntryContext.setTransaction( partitionTxn );
            
            if ( !system.hasEntry( hasEntryContext ) )
            {
                Entry systemEntry = new DefaultEntry( schemaManager, systemSuffixDn );
    
                // Add the ObjectClasses
                systemEntry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC,
                    SchemaConstants.ORGANIZATIONAL_UNIT_OC, SchemaConstants.EXTENSIBLE_OBJECT_OC );
    
                // Add some operational attributes
                systemEntry.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN );
                systemEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
                systemEntry.add( SchemaConstants.ENTRY_CSN_AT, getCSN().toString() );
                systemEntry.add( SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString() );
                systemEntry.put( DnUtils.getRdnAttributeType( ServerDNConstants.SYSTEM_DN ), DnUtils
                    .getRdnValue( ServerDNConstants.SYSTEM_DN ) );
    
                AddOperationContext addOperationContext = new AddOperationContext( admin, systemEntry );
                addOperationContext.setPartition( partition );
                
                PartitionTxn writeTxn = null;
                
                try
                {
                    writeTxn = partition.beginWriteTransaction();
                    addOperationContext.setTransaction( writeTxn );
                    system.add( addOperationContext );
                    
                    writeTxn.commit();
                }
                catch ( LdapException le )
                {
                    try
                    {
                        writeTxn.abort();
                    }
                    catch ( IOException ioe )
                    {
                        throw new LdapOtherException( ioe.getMessage(), ioe );
                    }
                    
                    throw le;
                }
                catch ( IOException ioe )
                {
                    try
                    {
                        writeTxn.abort();
                    }
                    catch ( IOException ioe2 )
                    {
                        throw new LdapOtherException( ioe2.getMessage(), ioe2 );
                    }
                    
                    throw new LdapOtherException( ioe.getMessage(), ioe );
                }
            }
        }
    }


    /**
     * Kicks off the initialization of the entire system.
     *
     * @throws LdapException if there are problems along the way
     */
    private void initialize() throws LdapException
    {
        if ( LOG.isDebugEnabled() )
        {
            LOG.debug( "---> Initializing the DefaultDirectoryService " );
        }

        csnFactory.setReplicaId( replicaId );

        // If no interceptor list is defined, setup a default list
        if ( interceptors == null )
        {
            setDefaultInterceptorConfigurations();
        }

        if ( cacheService == null )
        {
            // Initialize a default cache service
            cacheService = new CacheService();
        }

        cacheService.initialize( instanceLayout, instanceId );

        // Initialize the AP caches
        accessControlAPCache = new DnNode<>();
        collectiveAttributeAPCache = new DnNode<>();
        subschemaAPCache = new DnNode<>();
        triggerExecutionAPCache = new DnNode<>();

        if ( dnFactory == null )
        {
            dnFactory = new DefaultDnFactory( schemaManager, 
                cacheService.getCache( "dnCache", String.class, Dn.class ) );
        }

        // triggers partition to load schema fully from schema partition
        schemaPartition.setCacheService( cacheService );
        schemaPartition.initialize();
        partitions.add( schemaPartition );
        systemPartition.setCacheService( cacheService );
        
        if ( !systemPartition.getSuffixDn().isSchemaAware() )
        {
            systemPartition.setSuffixDn( new Dn( schemaManager, systemPartition.getSuffixDn() ) );
        }

        adminDn = getDnFactory().create( ServerDNConstants.ADMIN_SYSTEM_DN );
        adminSession = new DefaultCoreSession( new LdapPrincipal( schemaManager, adminDn, AuthenticationLevel.STRONG ),
            this );

        // TODO - NOTE: Need to find a way to instantiate without dependency on DPN
        partitionNexus = new DefaultPartitionNexus( new DefaultEntry( schemaManager, Dn.ROOT_DSE ) );
        partitionNexus.setDirectoryService( this );
        partitionNexus.initialize();

        try
        {
            initializeSystemPartition();
        }
        catch ( IOException ioe )
        {
            throw new LdapException( ioe.getMessage(), ioe );
        }

        // --------------------------------------------------------------------
        // Create all the bootstrap entries before initializing chain
        // --------------------------------------------------------------------

        try
        {
            firstStart = createBootstrapEntries();
        }
        catch ( IOException ioe )
        {
            throw new LdapException( ioe.getMessage(), ioe );
        }

        // initialize schema providers
        atProvider = new AttributeTypeProvider( schemaManager );
        ocProvider = new ObjectClassProvider( schemaManager );

        // Initialize the interceptors
        initInterceptors();

        // --------------------------------------------------------------------
        // Initialize the changeLog if it's enabled
        // --------------------------------------------------------------------

        if ( changeLog.isEnabled() )
        {
            changeLog.init( this );

            if ( changeLog.isExposed() && changeLog.isTagSearchSupported() )
            {
                String clSuffix = ( ( TaggableSearchableChangeLogStore ) changeLog.getChangeLogStore() ).getPartition()
                    .getSuffixDn().getName();
                partitionNexus.getRootDse( null ).add( ApacheSchemaConstants.CHANGELOG_CONTEXT_AT, clSuffix );
            }
        }

        // --------------------------------------------------------------------
        // Initialize the journal if it's enabled
        // --------------------------------------------------------------------
        if ( journal.isEnabled() )
        {
            journal.init( this );
        }

        if ( LOG.isDebugEnabled() )
        {
            LOG.debug( "<--- DefaultDirectoryService initialized" );
        }
    }


    /**
     * Read an entry (without Dn)
     *
     * @param text The ldif format file
     * @return An entry.
     */
    private Entry readEntry( String text )
    {
        StringReader strIn = new StringReader( text );
        BufferedReader in = new BufferedReader( strIn );

        String line = null;
        Entry entry = new DefaultEntry();

        try
        {
            while ( ( line = in.readLine() ) != null )
            {
                if ( line.length() == 0 )
                {
                    continue;
                }

                String addedLine = line.trim();

                if ( Strings.isEmpty( addedLine ) )
                {
                    continue;
                }

                Attribute attribute = LdifReader.parseAttributeValue( addedLine );
                Attribute oldAttribute = entry.get( attribute.getId() );

                if ( oldAttribute != null )
                {
                    try
                    {
                        oldAttribute.add( attribute.get() );
                        entry.put( oldAttribute );
                    }
                    catch ( LdapException ne )
                    {
                        // Do nothing
                    }
                }
                else
                {
                    try
                    {
                        entry.put( attribute );
                    }
                    catch ( LdapException ne )
                    {
                        // TODO do nothing ...
                    }
                }
            }
        }
        catch ( IOException ioe )
        {
            // Do nothing : we can't reach this point !
        }

        return entry;
    }


    /**
     * Create a new Entry
     *
     * @param ldif The String representing the attributes, as a LDIF file
     * @param dn The Dn for this new entry
     */
    public Entry newEntry( String ldif, String dn )
    {
        try
        {
            Entry entry = readEntry( ldif );
            Dn newDn = getDnFactory().create( dn );

            entry.setDn( newDn );

            return new DefaultEntry( schemaManager, entry );
        }
        catch ( Exception e )
        {
            LOG.error( I18n.err( I18n.ERR_78, ldif, dn ) );
            // do nothing
            return null;
        }
    }


    public EventService getEventService()
    {
        return eventService;
    }


    public void setEventService( EventService eventService )
    {
        this.eventService = eventService;
    }


    /**
     * {@inheritDoc}
     */
    public boolean isPasswordHidden()
    {
        return passwordHidden;
    }


    /**
     * {@inheritDoc}
     */
    public void setPasswordHidden( boolean passwordHidden )
    {
        this.passwordHidden = passwordHidden;
    }


    /**
     * @return The maximum allowed size for an incoming PDU
     */
    public int getMaxPDUSize()
    {
        return maxPDUSize;
    }


    /**
     * Set the maximum allowed size for an incoming PDU
     * @param maxPDUSize A positive number of bytes for the PDU. A negative or
     * null value will be transformed to {@link Integer#MAX_VALUE}
     */
    public void setMaxPDUSize( int maxPDUSize )
    {
        if ( maxPDUSize <= 0 )
        {
            maxPDUSize = Integer.MAX_VALUE;
        }

        this.maxPDUSize = maxPDUSize;
    }


    /**
     * {@inheritDoc}
     */
    public Interceptor getInterceptor( String interceptorName )
    {
        return interceptorNames.get( interceptorName );
    }


    /**
     * {@inheritDoc}
     */
    public void addFirst( Interceptor interceptor ) throws LdapException
    {
        addInterceptor( interceptor, 0 );
    }


    /**
     * {@inheritDoc}
     */
    public void addLast( Interceptor interceptor ) throws LdapException
    {
        addInterceptor( interceptor, -1 );
    }


    /**
     * {@inheritDoc}
     */
    public void addAfter( String interceptorName, Interceptor interceptor )
    {
        writeLock.lock();

        try
        {
            int position = 0;

            // Find the position
            for ( Interceptor inter : interceptors )
            {
                if ( interceptorName.equals( inter.getName() ) )
                {
                    break;
                }

                position++;
            }

            if ( position == interceptors.size() )
            {
                interceptors.add( interceptor );
            }
            else
            {
                interceptors.add( position, interceptor );
            }
        }
        finally
        {
            writeLock.unlock();
        }
    }


    /**
     * {@inheritDoc}
     */
    public void remove( String interceptorName )
    {
        removeOperationsList( interceptorName );
    }


    /**
     * Get a new CSN
     * @return The CSN generated for this directory service
     */
    public Csn getCSN()
    {
        return csnFactory.newInstance();
    }


    /**
     * @return the replicaId
     */
    public int getReplicaId()
    {
        return replicaId;
    }


    /**
     * @param replicaId the replicaId to set
     */
    public void setReplicaId( int replicaId )
    {
        if ( ( replicaId < 0 ) || ( replicaId > 999 ) )
        {
            LOG.error( I18n.err( I18n.ERR_79 ) );
            this.replicaId = 0;
        }
        else
        {
            this.replicaId = replicaId;
        }
    }


    /**
     * {@inheritDoc}
     */
    public long getSyncPeriodMillis()
    {
        return syncPeriodMillis;
    }


    /**
     * {@inheritDoc}
     */
    public void setSyncPeriodMillis( long syncPeriodMillis )
    {
        this.syncPeriodMillis = syncPeriodMillis;
    }


    /**
     * checks if the working directory is already in use by some other directory service, if yes
     * then throws a runtime exception else will obtain the lock on the working directory
     */
    private void lockWorkDir()
    {
        FileLock fileLock = null;

        try
        {
            lockFile = new RandomAccessFile( new File( instanceLayout.getInstanceDirectory(), LOCK_FILE_NAME ), "rw" );
            try
            {
                fileLock = lockFile.getChannel().tryLock( 0, 1, false );
            }
            catch ( IOException e )
            {
                // shoudn't happen, but log
                LOG.error( "failed to lock the work directory", e );
            }
            catch ( OverlappingFileLockException e ) // thrown if we can't get a lock
            {
                fileLock = null;
            }
        }
        catch ( FileNotFoundException e )
        {
            // shouldn't happen, but log anyway
            LOG.error( "failed to lock the work directory", e );
        }

        if ( ( fileLock == null ) || ( !fileLock.isValid() ) )
        {
            String message = "the working directory " + instanceLayout.getRunDirectory()
                + " has been locked by another directory service.";
            LOG.error( message );
            throw new RuntimeException( message );
        }

    }


    /**
     * {@inheritDoc}
     */
    public CacheService getCacheService()
    {
        return cacheService;
    }


    /**
     * {@inheritDoc}
     */
    public DnNode<AccessControlAdministrativePoint> getAccessControlAPCache()
    {
        return accessControlAPCache;
    }


    /**
     * {@inheritDoc}
     */
    public DnNode<CollectiveAttributeAdministrativePoint> getCollectiveAttributeAPCache()
    {
        return collectiveAttributeAPCache;
    }


    /**
     * {@inheritDoc}
     */
    public DnNode<SubschemaAdministrativePoint> getSubschemaAPCache()
    {
        return subschemaAPCache;
    }


    /**
     * {@inheritDoc}
     */
    public DnNode<TriggerExecutionAdministrativePoint> getTriggerExecutionAPCache()
    {
        return triggerExecutionAPCache;
    }


    /**
     * {@inheritDoc}
     */
    public boolean isPwdPolicyEnabled()
    {
        AuthenticationInterceptor authenticationInterceptor = ( AuthenticationInterceptor ) getInterceptor( InterceptorEnum.AUTHENTICATION_INTERCEPTOR
            .getName() );

        if ( authenticationInterceptor == null )
        {
            return false;
        }

        PpolicyConfigContainer pwdPolicyContainer = authenticationInterceptor.getPwdPolicyContainer();

        return ( ( pwdPolicyContainer != null )
        && ( ( pwdPolicyContainer.getDefaultPolicy() != null )
        || ( pwdPolicyContainer.hasCustomConfigs() ) ) );
    }


    /**
     * {@inheritDoc}
     */
    public DnFactory getDnFactory()
    {
        return dnFactory;
    }


    /**
     * {@inheritDoc}
     */
    public void setDnFactory( DnFactory dnFactory )
    {
        this.dnFactory = dnFactory;
    }


    /**
     * {@inheritDoc}
     */
    public SubentryCache getSubentryCache()
    {
        return subentryCache;
    }


    /**
     * {@inheritDoc}
     */
    public SubtreeEvaluator getEvaluator()
    {
        return evaluator;
    }


    /**
     * {@inheritDoc}
     */
    public void setCacheService( CacheService cacheService )
    {
        this.cacheService = cacheService;
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public AttributeTypeProvider getAtProvider()
    {
        return atProvider;
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public ObjectClassProvider getOcProvider()
    {
        return ocProvider;
    }

}