/*
 *  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.security.MessageDigest;
import java.util.ArrayList;
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.TimeProvider;
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.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.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 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;
    
    private TimeProvider timeProvider;


    // ------------------------------------------------------------------------
    // 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();
        timeProvider = TimeProvider.DEFAULT;
    }


    // ------------------------------------------------------------------------
    // 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.
         */
        PartitionTxn transaction = systemPartition.beginWriteTransaction();
        // Speedup the addition by using a global transaction
        adminSession.addTransaction( systemPartition, transaction );
        adminSession.beginSessionTransaction();

        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() ) );
                    }
                }
                
                adminSession.endSessionTransaction( true );
            }
        }
        catch ( Exception e )
        {
            try
            {
                adminSession.endSessionTransaction( false );
            }
            catch ( IOException ioe )
            {
                throw new LdapOperationException( ioe.getMessage(), ioe );
            }
            
            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 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( getTimeProvider() ) );
                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() );
    
                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( getTimeProvider() ) );
                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( getTimeProvider() ) );
                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( getTimeProvider() ) );
                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( getTimeProvider() ) );
                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( getTimeProvider() ) );
                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( getTimeProvider() ) );
                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( getTimeProvider() ) );
                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( getTimeProvider() ) );
                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 = MessageDigest.isEqual( 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( getTimeProvider() ) );
                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();
        }

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

        if ( dnFactory == null )
        {
            dnFactory = new DefaultDnFactory( schemaManager, 10000 );
        }

        // triggers partition to load schema fully from schema partition
        schemaPartition.initialize();
        partitions.add( schemaPartition );
        
        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 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}
     */
    @Override
    public AttributeTypeProvider getAtProvider()
    {
        return atProvider;
    }


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


    /**
     * {@inheritDoc}
     */
    @Override
    public TimeProvider getTimeProvider()
    {
        return timeProvider;
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public void setTimeProvider( TimeProvider timeProvider )
    {
        this.timeProvider = timeProvider;
    }
}
