/*
 *   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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.ldap.server.partition.impl.btree.jdbm;


import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;

import jdbm.RecordManager;
import jdbm.helper.MRU;
import jdbm.recman.BaseRecordManager;
import jdbm.recman.CacheRecordManager;

import org.apache.ldap.common.MultiException;
import org.apache.ldap.common.exception.LdapNameNotFoundException;
import org.apache.ldap.common.exception.LdapSchemaViolationException;
import org.apache.ldap.common.message.LockableAttributesImpl;
import org.apache.ldap.common.message.ResultCodeEnum;
import org.apache.ldap.common.name.LdapName;
import org.apache.ldap.common.schema.AttributeType;
import org.apache.ldap.common.schema.Normalizer;
import org.apache.ldap.common.util.NamespaceTools;
import org.apache.ldap.server.configuration.ContextPartitionConfiguration;
import org.apache.ldap.server.jndi.ContextFactoryConfiguration;
import org.apache.ldap.server.partition.ContextPartition;
import org.apache.ldap.server.partition.impl.btree.BTreeContextPartition;
import org.apache.ldap.server.partition.impl.btree.Index;
import org.apache.ldap.server.partition.impl.btree.IndexAssertion;
import org.apache.ldap.server.partition.impl.btree.IndexAssertionEnumeration;
import org.apache.ldap.server.partition.impl.btree.IndexNotFoundException;
import org.apache.ldap.server.partition.impl.btree.IndexRecord;


/**
 * A {@link ContextPartition} that stores entries in
 * <a href="http://jdbm.sourceforge.net/">JDBM</a> database.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class JdbmContextPartition extends BTreeContextPartition
{
    /** the JDBM record manager used by this database */
    private RecordManager recMan;
    /** the user provided suffix of this backend database */
    private Name upSuffix;
    /** the normalized suffix of this backend database */
    private Name normSuffix;
    /** the working directory to use for files */
    private File workingDirectory;
    /** the master table storing entries by primary key */
    private JdbmMasterTable master;
    /** a map of attribute names to user indices */
    private Map indices;
    /** a map of index names to system indices */
    private Map sysIndices;

    /** true if open */
    private boolean initialized;

    /** the normalized distinguished name index */
    private Index ndnIdx;
    /** the user provided distinguished name index */
    private Index updnIdx;
    /** the attribute existance index */
    private Index existanceIdx;
    /** the parent child relationship index */
    private Index hierarchyIdx;
    /** the one level scope alias index */
    private Index oneAliasIdx;
    /** the subtree scope alias index */
    private Index subAliasIdx;
    /** a system index on aliasedObjectName attribute */
    private Index aliasIdx;


    // ------------------------------------------------------------------------
    // C O N S T R U C T O R S
    // ------------------------------------------------------------------------


    /**
     * Creates a store based on JDBM B+Trees.
     */
    public JdbmContextPartition()
    {
    }

    public synchronized void init( ContextFactoryConfiguration factoryCfg, ContextPartitionConfiguration cfg ) throws NamingException
    {
        this.upSuffix = new LdapName( cfg.getSuffix() );
        this.normSuffix = cfg.getNormalizedSuffix( factoryCfg.getGlobalRegistries().getMatchingRuleRegistry() );

        File workingDirectory = new File(
                factoryCfg.getStartupConfiguration().getWorkingDirectory().getPath() +
                File.separator + cfg.getName() );
        
        workingDirectory.mkdirs();
        
        this.workingDirectory = workingDirectory;
            
        try 
        {
            String path = workingDirectory.getPath() + File.separator + "master";
            BaseRecordManager base = new BaseRecordManager( path );
            base.disableTransactions();
            recMan = new CacheRecordManager( base, new MRU( 1000 ) );
        } 
        catch ( IOException e )
        {
            NamingException ne = new NamingException( 
                "Could not initialize RecordManager" );
            ne.setRootCause( e );
            throw ne;
        }

        master = new JdbmMasterTable( recMan );
        indices = new HashMap();
        sysIndices = new HashMap();
        
        super.init( factoryCfg, cfg );
        initialized = true;
    }
    
    
    public synchronized void destroy()
    {
        if ( !initialized )
        {
            return;
        }

        ArrayList array = new ArrayList();
        array.addAll( indices.values() );
        
        if ( null != ndnIdx )
        {
            array.add( ndnIdx );
        }
        
        if ( null != updnIdx )
        {
            array.add( updnIdx );
        }

        if ( null != aliasIdx )
        {
            array.add( aliasIdx );
        }

        if ( null != oneAliasIdx )
        {
            array.add( oneAliasIdx );
        }

        if ( null != subAliasIdx )
        {
            array.add( subAliasIdx );
        }

        if ( null != hierarchyIdx )
        {
            array.add( hierarchyIdx );
        }

        if ( null != existanceIdx )
        {
            array.add( existanceIdx );
        }
        
        Iterator list = array.iterator();
        MultiException rootCause = null;
        
        while ( list.hasNext() ) 
        {
            Index index = ( Index ) list.next();

            try 
            {
               index.close();
            } 
            catch ( Throwable t ) 
            {
                if ( null == rootCause ) 
                {
                    rootCause = new MultiException();
                }
                
                rootCause.addThrowable( t );
            }
        }

        try 
        {
            master.close();
        } 
        catch ( Throwable t ) 
        {
            if ( null == rootCause ) 
            {
                rootCause = new MultiException();
            }
                
            rootCause.addThrowable( t );
        }

        try 
        {
            recMan.close();
        } 
        catch ( Throwable t ) 
        {
            if ( null == rootCause ) 
            {
                rootCause = new MultiException();
            }
                
            rootCause.addThrowable( t );
        }

        initialized = false;

        if ( null != rootCause )
        {
            NamingException ne = new NamingException( "Failed to close all" );
            ne.setRootCause( rootCause );
            ne.printStackTrace();
        }
    }


    public boolean isInitialized()
    {
        return initialized;
    }


    public synchronized void sync() throws NamingException
    {
        if( !initialized )
        {
            return;
        }

        ArrayList array = new ArrayList();
        array.addAll( indices.values() );
        array.add( ndnIdx );
        array.add( updnIdx );
        array.add( aliasIdx );
        array.add( oneAliasIdx );
        array.add( subAliasIdx );
        array.add( hierarchyIdx );
        array.add( existanceIdx );
        
        Iterator list = array.iterator();
        MultiException rootCause = null;

        // Sync all user defined indices
        while ( list.hasNext() ) 
        {
            Index idx = ( Index ) list.next();

            try 
            {
                idx.sync();
            } 
            catch ( Throwable t ) 
            {
                t.printStackTrace();
                if ( null == rootCause ) 
                {
                    rootCause = new MultiException();
                }
                
                rootCause.addThrowable( t );
            }
        }
        
        try 
        {
            master.sync();
            recMan.commit();
        }
        catch ( Throwable t ) 
        {
            t.printStackTrace();
            if ( null == rootCause ) 
            {
                rootCause = new MultiException();
            }
                
            rootCause.addThrowable( t );
        }

        if ( null != rootCause )
        {
            NamingException ne = new NamingException( "Failed to sync all" );
            ne.setRootCause( rootCause );
            throw ne;
        }        
    }


    // ------------------------------------------------------------------------
    // I N D E X   M E T H O D S
    // ------------------------------------------------------------------------


    public void addIndexOn( AttributeType spec ) throws NamingException
    {
        Index idx = new JdbmIndex( spec, workingDirectory );
        indices.put( spec.getName().toLowerCase(), idx );
    }

    
    public Index getExistanceIndex() 
    {
        return existanceIdx;
    }
    

    public void setExistanceIndexOn( AttributeType attrType ) throws NamingException
    {
        if ( existanceIdx != null )
        {
            NamingException e = new NamingException( "Index already set!" );
            throw e;
        }

        existanceIdx = new JdbmIndex( attrType, workingDirectory );
        sysIndices.put( attrType.getName().toLowerCase(), existanceIdx );
    }

    
    public Index getHierarchyIndex() 
    {
        return hierarchyIdx;
    }
    

    public void setHierarchyIndexOn( AttributeType attrType ) throws NamingException
    {
        if ( hierarchyIdx != null )
        {
            NamingException e = new NamingException( "Index already set!" );
            throw e;
        }

        hierarchyIdx = new JdbmIndex( attrType, workingDirectory );
        sysIndices.put( attrType.getName().toLowerCase(), hierarchyIdx );
    }

    
    public Index getAliasIndex()
    {
        return aliasIdx;    
    }


    public void setAliasIndexOn( AttributeType attrType ) throws NamingException
    {
        if ( aliasIdx != null )
        {
            NamingException e = new NamingException( "Index already set!" );
            throw e;
        }

        aliasIdx = new JdbmIndex( attrType, workingDirectory );
        sysIndices.put( attrType.getName().toLowerCase(), aliasIdx );
    }    
    

    public Index getOneAliasIndex()
    {
        return oneAliasIdx;
    }


    public void setOneAliasIndexOn( AttributeType attrType ) throws NamingException
    {
        if ( oneAliasIdx != null )
        {
            NamingException e = new NamingException( "Index already set!" );
            throw e;
        }

        oneAliasIdx = new JdbmIndex( attrType, workingDirectory );
        sysIndices.put( attrType.getName().toLowerCase(), oneAliasIdx );
    }


    public Index getSubAliasIndex()
    {
        return subAliasIdx;
    }


    public void setSubAliasIndexOn( AttributeType attrType ) throws NamingException
    {
        if ( subAliasIdx != null )
        {
            NamingException e = new NamingException( "Index already set!" );
            throw e;
        }

        subAliasIdx = new JdbmIndex( attrType, workingDirectory );
        sysIndices.put( attrType.getName().toLowerCase(), subAliasIdx );
    }


    public Index getUpdnIndex()
    {
        return updnIdx;
    }


    public void setUpdnIndexOn( AttributeType attrType ) throws NamingException
    {
        if ( updnIdx != null )
        {
            NamingException e = new NamingException( "Index already set!" );
            throw e;
        }

        updnIdx = new JdbmIndex( attrType, workingDirectory );
        sysIndices.put( attrType.getName().toLowerCase(), updnIdx );
    }

    
    public Index getNdnIndex() 
    {
        return ndnIdx;
    }
    

    public void setNdnIndexOn( AttributeType attrType ) throws NamingException
    {
        if ( ndnIdx != null )
        {
            NamingException e = new NamingException( "Index already set!" );
            throw e;
        }

        ndnIdx = new JdbmIndex( attrType, workingDirectory );
        sysIndices.put( attrType.getName().toLowerCase(), ndnIdx );
    }

    
    public Iterator getUserIndices()
    {
        return indices.keySet().iterator();
    }


    public Iterator getSystemIndices()
    {
        return sysIndices.keySet().iterator();
    }


    public boolean hasUserIndexOn( String attribute )
    {
        return indices.containsKey( attribute ) ||
            indices.containsKey( attribute.toLowerCase() );
    }


    public boolean hasSystemIndexOn( String attribute )
    {
        return sysIndices.containsKey( attribute ) ||
            sysIndices.containsKey( attribute.toLowerCase() );
    }


    /**
     * @todo replace lookups to use the OID instead of the name.  Also note
     * that the OID registry can be used to go between names and oids.
     * 
     * @see org.apache.ldap.server.partition.impl.btree.BTreeContextPartition#getUserIndex(String)
     */
    public Index getUserIndex( String attribute ) throws IndexNotFoundException
    {
        String lowerCased = attribute.toLowerCase();

        if ( indices.containsKey( attribute ) ) 
        {
            return ( Index ) indices.get( attribute );
        } 
        else if ( indices.containsKey( lowerCased ) ) 
        {
            return ( Index ) indices.get( lowerCased );
        } 
        else 
        {
            throw new IndexNotFoundException( "An index on attribute " +
                attribute + " does not exist!" );
        }
    }
    
    
    /**
     * @todo replace lookups to use the OID instead of the name.  Also note
     * that the OID registry can be used to go between names and oids.
     * 
     * @see BTreeContextPartition#getEntryId(String)
     */
    public Index getSystemIndex( String indexName ) throws IndexNotFoundException
    {
        String lowerCased = indexName.toLowerCase();

        if ( sysIndices.containsKey( indexName ) ) 
        {
            return ( Index ) sysIndices.get( indexName );
        } 
        else if ( sysIndices.containsKey( lowerCased ) ) 
        {
            return ( Index ) sysIndices.get( lowerCased );
        } 
        else 
        {
            throw new IndexNotFoundException( "A system index by the name of " +
                indexName + " does not exist!" );
        }
    }


    public BigInteger getEntryId( String dn ) throws NamingException
    {
        return ndnIdx.forwardLookup( dn );
    }


    public String getEntryDn( BigInteger id ) throws NamingException
    {
        return ( String ) ndnIdx.reverseLookup( id );
    }


    public BigInteger getParentId( String dn ) throws NamingException
    {
        BigInteger childId = ndnIdx.forwardLookup( dn );
        return ( BigInteger ) hierarchyIdx.reverseLookup( childId );
    }


    public BigInteger getParentId( BigInteger childId ) throws NamingException
    {
        return ( BigInteger ) hierarchyIdx.reverseLookup( childId );
    }
    
    
    public String getEntryUpdn( BigInteger id ) throws NamingException
    {
        return ( String ) updnIdx.reverseLookup( id );
    }


    public String getEntryUpdn( String dn ) throws NamingException
    {
        BigInteger id = ndnIdx.forwardLookup( dn );
        return ( String ) updnIdx.reverseLookup( id );
    }


    public int count() throws NamingException
    {
        return master.count();
    }
    
    
    /**
     * Removes the index entries for an alias before the entry is deleted from
     * the master table.
     * 
     * @todo Optimize this by walking the hierarchy index instead of the name 
     * @param aliasId the id of the alias entry in the master table
     * @throws NamingException if we cannot delete the indices
     */
    private void dropAliasIndices( BigInteger aliasId ) throws NamingException
    {
        String targetDn = ( String ) aliasIdx.reverseLookup( aliasId );
        BigInteger targetId = getEntryId( targetDn );
        String aliasDn = getEntryDn( aliasId );
        Name ancestorDn = new LdapName( aliasDn ).getSuffix( 1 );
        BigInteger ancestorId = getEntryId( ancestorDn.toString() );
        
        /*
         * We cannot just drop all tuples in the one level and subtree indices
         * linking baseIds to the targetId.  If more than one alias refers to
         * the target then droping all tuples with a value of targetId would
         * make all other aliases to the target inconsistent.
         * 
         * We need to walk up the path of alias ancestors until we reach the 
         * upSuffix, deleting each ( ancestorId, targetId ) tuple in the
         * subtree scope alias.  We only need to do this for the direct parent
         * of the alias on the one level subtree.
         */
        oneAliasIdx.drop( ancestorId, targetId );
        subAliasIdx.drop( ancestorId, targetId );
        
        while ( ! ancestorDn.equals( upSuffix ) )
        {
            ancestorDn = ancestorDn.getSuffix( 1 );
            ancestorId = getEntryId( ancestorDn.toString() );
            
            subAliasIdx.drop( ancestorId, targetId );
        }    

        // Drops all alias tuples pointing to the id of the alias to be deleted
        aliasIdx.drop( aliasId );
    }
    
    
    /**
     * Adds indices for an aliasEntry to be added to the database while checking
     * for constrained alias constructs like alias cycles and chaining.
     * 
     * @param aliasDn normalized distinguished name for the alias entry
     * @param aliasTarget the user provided aliased entry dn as a string
     * @param aliasId the id of alias entry to add
     * @throws NamingException if index addition fails, of the alias is not 
     * allowed due to chaining or cycle formation.
     */
    private void addAliasIndices( BigInteger aliasId, Name aliasDn, 
        String aliasTarget ) throws NamingException
    {
        Name targetDn = null;            // Name value of aliasedObjectName
        BigInteger targetId = null;      // Id of the aliasedObjectName
        Normalizer normalizer = null;    // Temporary handle for Dn's
        Name ancestorDn = null;          // Name of an alias entry relative
        BigInteger ancestorId = null;    // Id of an alias entry relative

        // Access aliasedObjectName, normalize it and generate the Name 
        normalizer = oneAliasIdx.getAttribute().getEquality().getNormalizer();
        targetDn = new LdapName( ( String ) normalizer.normalize( aliasTarget ) );
           
        /*
         * Check For Cycles
         * 
         * Before wasting time to lookup more values we check using the target
         * dn to see if we have the possible formation of an alias cycle.  This
         * happens when the alias refers back to a target that is also a 
         * relative of the alias entry.  For detection we test if the aliased
         * entry Dn starts with the target Dn.  If it does then we know the 
         * aliased target is a relative and we have a perspecitive cycle.
         */ 
        if ( aliasDn.startsWith( targetDn ) )
        {
            if ( aliasDn.equals( targetDn ) )
            {
                throw new NamingException( "[36] aliasDereferencingProblem - " 
                    + "attempt to create alias to itself." );
            }
            
            throw new NamingException( "[36] aliasDereferencingProblem - " 
                + "attempt to create alias with cycle to relative " 
                + aliasTarget + " not allowed from descendent alias " 
                + aliasDn );
        }
            
        /*
         * Check For Aliases External To Naming Context
         * 
         * id may be null but the alias may be to a valid entry in 
         * another namingContext.  Such aliases are not allowed and we
         * need to point it out to the user instead of saying the target
         * does not exist when it potentially could outside of this upSuffix.
         */
        if ( ! targetDn.startsWith( upSuffix ) )
        {
            // Complain specifically about aliases to outside naming contexts
            throw new NamingException( "[36] aliasDereferencingProblem -"
                + " the alias points to an entry outside of the " + upSuffix
                + " namingContext to an object whose existance cannot be"
                + " determined." );
        }

        // L O O K U P   T A R G E T   I D
        targetId = ndnIdx.forwardLookup( targetDn.toString() );

        /*
         * Check For Target Existance
         * 
         * We do not allow the creation of inconsistant aliases.  Aliases should
         * not be broken links.  If the target does not exist we start screaming
         */
        if ( null == targetId )
        {
            // Complain about target not existing
            throw new NamingException( "[33] aliasProblem - " 
                + "the alias when dereferenced would not name a known object "
                + "the aliasedObjectName must be set to a valid existing "
                + "entry." );
        }
        
        /*
         * Detect Direct Alias Chain Creation
         * 
         * Rather than resusitate the target to test if it is an alias and fail
         * due to chaing creation we use the alias index to determine if the
         * target is an alias.  Hence if the alias we are about to create points
         * to another alias as its target in the aliasedObjectName attribute, 
         * then we have a situation where an alias chain is being created.  
         * Alias chaining is not allowed so we throw and exception. 
         */
        if ( null != aliasIdx.reverseLookup( targetId ) )
        {
            // Complain about illegal alias chain
            throw new NamingException( "[36] aliasDereferencingProblem -" 
                + " the alias points to another alias.  Alias chaining is" 
                + " not supported by this backend." );
        }
        
        // Add the alias to the simple alias index
        aliasIdx.add( aliasTarget, aliasId );
        
        /*
         * Handle One Level Scope Alias Index
         * 
         * The first relative is special with respect to the one level alias
         * index.  If the target is not a sibling of the alias then we add the
         * index entry maping the parent's id to the aliased target id.
         */
        ancestorDn = aliasDn.getSuffix( 1 );
        ancestorId = getEntryId( ancestorDn.toString() );
        
        if ( ! NamespaceTools.isSibling( targetDn, aliasDn ) )
        {
            oneAliasIdx.add( ancestorId, targetId );
        }

        /*
         * Handle Sub Level Scope Alias Index
         * 
         * Walk the list of relatives from the parents up to the upSuffix, testing
         * to see if the alias' target is a descendant of the relative.  If the
         * alias target is not a descentant of the relative it extends the scope
         * and is added to the sub tree scope alias index.  The upSuffix node is
         * ignored since everything is under its scope.  The first loop 
         * iteration shall handle the parents.
         */
        while ( ! ancestorDn.equals( upSuffix ) && null != ancestorId )
        {
            if ( ! NamespaceTools.isDescendant( ancestorDn, targetDn ) )
            {
                subAliasIdx.add( ancestorId, targetId );
            }
            
            ancestorDn = ancestorDn.getSuffix( 1 );
            ancestorId = getEntryId( ancestorDn.toString() );
        }        
    }


    public void add( String updn, Name dn, Attributes entry ) throws NamingException
    {
        BigInteger id;
        BigInteger parentId = null;

        id = master.getNextId();

        //
        // Suffix entry cannot have a parent since it is the root so it is 
        // capped off using the zero value which no entry can have since 
        // entry sequences start at 1.
        //
        
        if ( dn.equals( normSuffix ) )
        {
            parentId = BigInteger.ZERO;
        }
        else 
        {
            parentId = getEntryId( dn.getSuffix( 1 ).toString() );
        }

        // don't keep going if we cannot find the parent Id
        if ( parentId == null )
        {
            throw new LdapNameNotFoundException( "Id for parent '" + dn.getSuffix( 1 ).toString() + "' not found!" );
        }

        Attribute objectClass = entry.get( "objectClass" );

        if ( objectClass == null )
        {
            String msg = "Entry " + updn + " contains no objectClass attribute: " + entry;

            throw new LdapSchemaViolationException( msg, ResultCodeEnum.OBJECTCLASSVIOLATION );
        }

        // Start adding the system indices
        // Why bother doing a lookup if this is not an alias.

        if ( entry.get( "objectClass" ).contains( ContextPartition.ALIAS_OBJECT ) )
        {
            addAliasIndices( id, dn, ( String ) entry.get( ContextPartition.ALIAS_ATTRIBUTE ).get() );
        }
        
        ndnIdx.add( dn.toString(), id );
        updnIdx.add( updn, id );
        hierarchyIdx.add( parentId, id );
        
        // Now work on the user defined indices
        NamingEnumeration list = entry.getIDs();
        while ( list.hasMore() ) 
        {
            String attribute = ( String ) list.next();
            
            if ( hasUserIndexOn( attribute ) ) 
            {
                Index idx = getUserIndex( attribute );
                NamingEnumeration values = entry.get( attribute ).getAll();
                
                while ( values.hasMore() ) 
                {
                    idx.add( values.next(), id );
                }

                // Adds only those attributes that are indexed
                existanceIdx.add( attribute.toLowerCase(), id );
            }
        }

        master.put( entry, id );
    }


    public Attributes lookup( BigInteger id ) throws NamingException
    {
        return master.get( id );
    }


    public void delete( BigInteger id ) throws  NamingException
    {
        Attributes entry = lookup( id );
        BigInteger parentId = getParentId( id );
        NamingEnumeration attrs = entry.getIDs();
        
        if ( entry.get( "objectClass" ).contains( ContextPartition.ALIAS_OBJECT ) )
        {
            dropAliasIndices( id );
        }

        ndnIdx.drop( id );
        updnIdx.drop( id );
        hierarchyIdx.drop( id );
        
        // Remove parent's reference to entry only if entry is not the upSuffix
        if ( ! parentId.equals( BigInteger.ZERO ) )
        {
            hierarchyIdx.drop( parentId, id );
        }
        
        while ( attrs.hasMore() ) 
        {
            String attr = ( ( String ) attrs.next() );

            if ( hasUserIndexOn( attr ) )
            {
                Index index = getUserIndex( attr );
                NamingEnumeration values = entry.get( attr ).getAll();
                
                while ( values.hasMore() )
                {
                    index.drop( values.next(), id );
                }

                existanceIdx.drop( attr.toLowerCase(), id );
            }
        }

        master.delete( id );
    }


    public NamingEnumeration list( BigInteger id ) throws  NamingException
    {
        return hierarchyIdx.listIndices( id );
    }


    public int getChildCount( BigInteger id ) throws NamingException
    {
        return hierarchyIdx.count( id );
    }


    public Name getSuffix( boolean normalized )
    {
        if ( normalized )
        {
            return normSuffix;
        }
        
        return upSuffix;
    }


    public Attributes getSuffixEntry() throws NamingException
    {
        BigInteger id = getEntryId( upSuffix.toString() );

        if ( null == id )
        {
            return null;
        }

        return lookup( id );
    }


    public void setProperty( String propertyName, String propertyValue )
        throws NamingException
    {
        master.setProperty( propertyName, propertyValue );
    }


    public String getProperty( String propertyName ) throws NamingException
    {
        return master.getProperty( propertyName );
    }


    public Attributes getIndices( BigInteger id ) throws  NamingException
    {
        Attributes attributes = new LockableAttributesImpl();

        // Get the distinguishedName to id mapping
        attributes.put( "_nDn", getEntryDn( id ) );
        attributes.put( "_upDn", getEntryUpdn( id ) );
        attributes.put( "_parent", getParentId( id ) );

        // Get all standard index attribute to value mappings
        Iterator idxList = this.indices.values().iterator();
        while ( idxList.hasNext() )
        {
            Index index = ( Index ) idxList.next();
            NamingEnumeration list = index.listReverseIndices( id );
            while ( list.hasMore() ) 
            {
                IndexRecord rec = ( IndexRecord ) list.next();
                Object val = rec.getIndexKey();
                attributes.put( index.getAttribute().getName(), val );
            }
        }

        // Get all existance mappings for this id creating a special key
        // that looks like so 'existance[attribute]' and the value is set to id
        NamingEnumeration list = existanceIdx.listReverseIndices( id );
        StringBuffer val = new StringBuffer();
        while ( list.hasMore() ) 
        {
            IndexRecord rec = ( IndexRecord ) list.next();
            val.append( "_existance[" ); 
            val.append( rec.getIndexKey() );
            val.append( "]" );
            attributes.put( val.toString(), rec.getEntryId() );
            val.setLength( 0 );
        }

        // Get all parent child mappings for this entry as the parent using the
        // key 'child' with many entries following it.
        list = hierarchyIdx.listIndices( id );
        while ( list.hasMore() ) 
        {
            IndexRecord rec = ( IndexRecord ) list.next();
            attributes.put( "_child", rec.getEntryId() );
        }

        return attributes;
    }


    /**
     * Adds a set of attribute values while affecting the appropriate indices. 
     * The entry is not persisted: it is only changed in anticipation for a put 
     * into the master table.
     *
     * @param id the primary key of the entry
     * @param entry the entry to alter
     * @param mods the attribute and values to add 
     * @throws NamingException if index alteration or attribute addition
     * fails.
     */
    private void add( BigInteger id, Attributes entry, Attribute mods )
        throws NamingException 
    {
        if ( hasUserIndexOn( mods.getID() ) )
        {
            Index idx = getUserIndex( mods.getID() );
            idx.add( mods, id );

            // If the attr didn't exist for this id add it to existance index
            if ( ! existanceIdx.hasValue( mods.getID(), id ) )
            {
                idx.add( mods.getID(), id );
            }
        }
        
        entry.put( mods );

        if ( mods.getID().equals( ContextPartition.ALIAS_ATTRIBUTE ) )
        {
            String ndnStr = ( String ) ndnIdx.reverseLookup( id );
            addAliasIndices( id, new LdapName( ndnStr ), 
                ( String ) mods.get() );
        }
    }
    
    
    /**
     * Completely removes the set of values for an attribute having the values 
     * supplied while affecting the appropriate indices.  The entry is not 
     * persisted: it is only changed in anticipation for a put into the master 
     * table.  Note that an empty attribute w/o values will remove all the 
     * values within the entry where as an attribute w/ values will remove those
     * attribute values it contains.
     *
     * @param id the primary key of the entry
     * @param entry the entry to alter
     * @param mods the attribute and its values to delete
     * @throws NamingException if index alteration or attribute modification 
     * fails.
     */
    private void remove( BigInteger id, Attributes entry, Attribute mods )
        throws NamingException
    {
        if ( hasUserIndexOn( mods.getID() ) )
        {
            Index idx = getUserIndex( mods.getID() );
            idx.drop( mods, id );
    
            /* 
             * If no attribute values exist for this entryId in the index then
             * we remove the existance index entry for the removed attribute.
             */
            if ( null == idx.reverseLookup( id ) )
            {
                existanceIdx.drop( mods.getID(), id );
            }
        }

        /*
         * If there are no attribute values in the modifications then this 
         * implies the compelete removal of the attribute from the entry. Else
         * we remove individual attribute values from the entry in mods one 
         * at a time.
         */
        if ( mods.size() == 0 )
        {
            entry.remove( mods.getID() );
        }
        else
        {
            Attribute entryAttr = entry.get( mods.getID() );
            NamingEnumeration values = mods.getAll();
            while ( values.hasMore() ) 
            {
                entryAttr.remove( values.next() );
            }
        }

        // Aliases->single valued comp/partial attr removal is not relevant here
        if ( mods.getID().equals( ContextPartition.ALIAS_ATTRIBUTE ) )
        {
            dropAliasIndices( id );
        }
    }


    /**
     * Completely replaces the existing set of values for an attribute with the
     * modified values supplied affecting the appropriate indices.  The entry
     * is not persisted: it is only changed in anticipation for a put into the
     * master table.
     *
     * @param id the primary key of the entry
     * @param entry the entry to alter
     * @param mods the replacement attribute and values
     * @throws NamingException if index alteration or attribute modification 
     * fails.
     */
    private void replace( BigInteger id, Attributes entry, Attribute mods )
        throws NamingException
    {
        if ( hasUserIndexOn( mods.getID() ) )
        {
            Index idx = getUserIndex( mods.getID() );
            
            // Drop all existing attribute value index entries and add new ones
            idx.drop( id );
            idx.add( mods, id );
    
            /* 
             * If no attribute values exist for this entryId in the index then
             * we remove the existance index entry for the removed attribute.
             */
            if ( null == idx.reverseLookup( id ) )
            {
                existanceIdx.drop( mods.getID(), id );
            }
        }

        if ( mods.getID().equals( ContextPartition.ALIAS_ATTRIBUTE ) )
        {
            dropAliasIndices( id );
        }
        
        // Automatically replaces old attributes with new modified ones
        entry.put( mods );
        
        if ( mods.getID().equals( ContextPartition.ALIAS_ATTRIBUTE ) )
        {
            String ndnStr = ( String ) ndnIdx.reverseLookup( id );
            addAliasIndices( id, new LdapName( ndnStr ), 
                ( String ) mods.get() );
        }
    }


    public void modify( Name dn, int modOp, Attributes mods ) throws NamingException
    {
        NamingEnumeration attrs = null;
        BigInteger id = getEntryId( dn.toString() );
        Attributes entry = master.get( id );
        
        switch ( modOp )
        {
            case( DirContext.ADD_ATTRIBUTE ):
                attrs = mods.getIDs();
                
                while ( attrs.hasMore() )
                {
                    String attrId = ( String ) attrs.next();
                    Attribute attr = mods.get( attrId );
                    add( id, entry, attr );
                }
                
                break;
            case( DirContext.REMOVE_ATTRIBUTE ):
                attrs = mods.getIDs();
                
                while ( attrs.hasMore() )
                {
                    String attrId = ( String ) attrs.next();
                    Attribute attr = mods.get( attrId );
                    remove( id, entry, attr );
                }
                
                break;
            case( DirContext.REPLACE_ATTRIBUTE ):
                attrs = mods.getIDs();
                
                while ( attrs.hasMore() )
                {
                    String attrId = ( String ) attrs.next();
                    Attribute attr = mods.get( attrId );
                    replace( id, entry, attr );
                }
                
                break;
            default:
                throw new NamingException( 
                    "Unidentified modification operation" );
        }
        
        master.put( entry, id );
    }
    

    public void modify( Name dn, ModificationItem [] mods ) throws NamingException
    {
        BigInteger id = getEntryId( dn.toString() );
        Attributes entry = master.get( id );
        
        for ( int ii = 0; ii < mods.length; ii++ )
        {
            Attribute attrMods = mods[ii].getAttribute();

            switch ( mods[ ii ].getModificationOp() )
            {
                case( DirContext.ADD_ATTRIBUTE ):
                    add( id, entry, attrMods );
                    break;
                case( DirContext.REMOVE_ATTRIBUTE ):
                    remove( id, entry, attrMods );
                    break;
                case( DirContext.REPLACE_ATTRIBUTE ):
                    replace( id, entry, attrMods );
                    break;
                default:
                    throw new NamingException( 
                        "Unidentified modification operation" );
            }
        }
        
        master.put( entry, id );
    }


    /**
     * Changes the relative distinuished name of an entry specified by a 
     * distinguished name with the optional removal of the old Rdn attribute
     * value from the entry.  Name changes propagate down as dn changes to the 
     * descendants of the entry where the Rdn changed. 
     * 
     * An Rdn change operation does not change parent child relationships.  It 
     * merely propagates a name change at a point in the DIT where the Rdn is 
     * changed. The change propagates down the subtree rooted at the 
     * distinguished name specified.
     *
     * @param dn the normalized distinguished name of the entry to alter
     * @param newRdn the new Rdn to set
     * @param deleteOldRdn whether or not to remove the old Rdn attr/val
     * @throws NamingException if there are any errors propagating the name 
     *        changes.
     */
    public void modifyRn( Name dn, String newRdn, boolean deleteOldRdn )
        throws NamingException
    {
        String newRdnAttr = NamespaceTools.getRdnAttribute( newRdn );
        String newRdnValue = NamespaceTools.getRdnValue( newRdn );
        BigInteger id = getEntryId( dn.toString() );
        Attributes entry = lookup( id );
        Name updn = new LdapName( getEntryUpdn( id ) );

        /* 
         * H A N D L E   N E W   R D N
         * ====================================================================
         * Add the new Rdn attribute to the entry.  If an index exists on the 
         * new Rdn attribute we add the index for this attribute value pair.
         * Also we make sure that the existance index shows the existance of the
         * new Rdn attribute within this entry.
         */
        
        entry.put( newRdnAttr, newRdnValue );
        
        if ( hasUserIndexOn( newRdnAttr ) )
        {
            Index idx = getUserIndex( newRdnAttr );
            idx.add( newRdnValue, id );
            
            // Make sure the altered entry shows the existance of the new attrib
            if ( ! existanceIdx.hasValue( newRdnAttr, id ) )
            {
                existanceIdx.add( newRdnAttr, id );
            }
        }

        /*
         * H A N D L E   O L D   R D N
         * ====================================================================
         * If the old Rdn is to be removed we need to get the attribute and 
         * value for it.  Keep in mind the old Rdn need not be based on the 
         * same Rdn as the new one.  We remove the Rdn value from the entry
         * and remove the value/id tuple from the index on the old Rdn attr
         * if any.  We also test if the delete of the old Rdn index tuple 
         * removed all the attribute values of the old Rdn using a reverse
         * lookup.  If so that means we blew away the last value of the old 
         * Rdn attribute.  In this case we need to remove the attrName/id 
         * tuple from the existance index.
         */

        if ( deleteOldRdn )
        {
            String oldRdn = updn.get( updn.size() - 1 );
            String oldRdnAttr = NamespaceTools.getRdnAttribute( oldRdn );
            String oldRdnValue = NamespaceTools.getRdnValue( oldRdn );
            
            entry.get( oldRdnAttr ).remove( oldRdnValue );

            if ( hasUserIndexOn( oldRdnAttr ) )
            {
                Index idx = getUserIndex( oldRdnAttr );
                idx.drop( oldRdnValue, id );
                
                /*
                 * If there is no value for id in this index due to our
                 * drop above we remove the oldRdnAttr from the existance idx
                 */
                if ( null == idx.reverseLookup( id ) )
                {
                    existanceIdx.drop( oldRdnAttr, id );
                }
            }
        }
        
        /*
         * H A N D L E   D N   C H A N G E
         * ====================================================================
         * 1) Build the new user defined distinguished name
         *      - clone / copy old updn
         *      - remove old upRdn from copy
         *      - add the new upRdn to the copy
         * 2) Make call to recursive modifyDn method to change the names of the
         *    entry and its descendants
         */

        Name newUpdn = ( Name ) updn.clone();      // copy da old updn
        newUpdn.remove( newUpdn.size() - 1 );      // remove old upRdn
        newUpdn.add( newUpdn.size(), newRdn );   // add da new upRdn
        modifyDn( id, newUpdn, false );            // propagate dn changes
    }
    
    
    /*
     * The move operation severs a child from a parent creating a new parent
     * child relationship.  As a consequence the relationships between the 
     * old ancestors of the child and its descendants change.  A descendant is
     *   
     */

    /**
     * Recursively modifies the distinguished name of an entry and the names of
     * its descendants calling itself in the recursion.
     *
     * @param id the primary key of the entry
     * @param updn User provided distinguished name to set as the new DN
     * @param isMove whether or not the name change is due to a move operation
     * which affects alias indices.
     * @throws NamingException if something goes wrong
     */
    private void modifyDn( BigInteger id, Name updn, boolean isMove )
        throws  NamingException
    {
        String aliasTarget = null;

        // Now we can handle the appropriate name indices for all cases
        ndnIdx.drop( id );
        ndnIdx.add( ndnIdx.getNormalized( updn.toString() ), id );
        
        updnIdx.drop( id );
        updnIdx.add( updn.toString(), id );
        
        /* 
         * Read Alias Index Tuples
         * 
         * If this is a name change due to a move operation then the one and
         * subtree indices for aliases were purged before the aliases were 
         * moved.  Now we must add them for each alias entry we have moved.  
         * 
         * aliasTarget is used as a marker to tell us if we're moving an 
         * alias.  If it is null then the moved entry is not an alias.
         */
        if ( isMove ) 
        {
            aliasTarget = ( String ) aliasIdx.reverseLookup( id );
    
            if ( null != aliasTarget )
            {
                addAliasIndices( id, new LdapName( getEntryDn( id ) ), 
                    aliasTarget );
            }
        }
        
        NamingEnumeration children = list( id );
        while ( children.hasMore() ) 
        {
            // Get the child and its id
            IndexRecord rec = ( IndexRecord ) children.next();
            BigInteger childId = rec.getEntryId();
            
            /* 
             * Calculate the Dn for the child's new name by copying the parents
             * new name and adding the child's old upRdn to new name as its Rdn
             */
            Name childUpdn = ( Name ) updn.clone();
            Name oldUpdn = new LdapName( getEntryUpdn( childId ) );
            String rdn = LdapName.getRdn( oldUpdn ); 
            childUpdn.add( childUpdn.size(),  rdn );

            // Recursively change the names of the children below
            modifyDn( childId, childUpdn, isMove );
        }
    }


    public void move( Name oldChildDn, Name newParentDn, String newRdn,
        boolean deleteOldRdn ) throws NamingException
    {
        modifyRn( oldChildDn, newRdn, deleteOldRdn );
        move( oldChildDn, newParentDn );
    }


    /**
     * Moves an entry under a new parent.  The operation causes a shift in the
     * parent child relationships between the old parent, new parent and the 
     * child moved.  All other descendant entries under the child never change
     * their direct parent child relationships.  Hence after the parent child
     * relationship changes are broken at the old parent and set at the new
     * parent a modifyDn operation is conducted to handle name changes 
     * propagating down through the moved child and its descendants.
     * 
     * @param oldChildDn the normalized dn of the child to be moved
     * @param newParentDn the normalized dn of the new parent for the child
     * @throws NamingException if something goes wrong
     */
    public void move( Name oldChildDn, Name newParentDn ) throws NamingException
    {
        // Get the child and the new parent to be entries and Ids
        BigInteger childId = getEntryId( oldChildDn.toString() );
        BigInteger newParentId = getEntryId( newParentDn.toString() );
        BigInteger oldParentId = getParentId( childId );
        
        /*
         * All aliases including and below oldChildDn, will be affected by
         * the move operation with respect to one and subtree indices since 
         * their relationship to ancestors above oldChildDn will be 
         * destroyed.  For each alias below and including oldChildDn we will
         * drop the index tuples mapping ancestor ids above oldChildDn to the
         * respective target ids of the aliases.
         */
        dropMovedAliasIndices( oldChildDn );
        
        /*
         * Drop the old parent child relationship and add the new one
         * Set the new parent id for the child replacing the old parent id
         */
        hierarchyIdx.drop( oldParentId, childId );
        hierarchyIdx.add( newParentId, childId );

        /*
         * Build the new user provided DN (updn) for the child using the child's
         * user provided RDN & the new parent's UPDN.  Basically add the child's
         * UpRdn String to the tail of the new parent's Updn Name.
         */
        Name childUpdn = new LdapName( getEntryUpdn( childId ) );
        String childRdn = childUpdn.get( childUpdn.size() - 1 ); 
        Name newUpdn = new LdapName( getEntryUpdn( newParentId ) );
        newUpdn.add( newUpdn.size(), childRdn );

        // Call the modifyDn operation with the new updn
        modifyDn( childId, newUpdn, true );
    }


    /**
     * For all aliases including and under the moved base, this method removes
     * one and subtree alias index tuples for old ancestors above the moved base
     * that will no longer be ancestors after the move.
     * 
     * @param movedBase the base at which the move occured - the moved node
     * @throws NamingException if system indices fail
     */
    private void dropMovedAliasIndices( final Name movedBase ) throws NamingException
    {
        // Find all the aliases from movedBase down
        IndexAssertion isBaseDescendant = new IndexAssertion()
        {
            public boolean assertCandidate( IndexRecord rec )
                throws NamingException
            {
                String dn = getEntryDn( rec.getEntryId() );
                if ( dn.endsWith( movedBase.toString() ) )
                {
                    return true;
                }
                
                return false;
            }
        };
        
        BigInteger movedBaseId = getEntryId( movedBase.toString() );
        if ( aliasIdx.reverseLookup( movedBaseId ) != null ) 
        {
            dropAliasIndices( movedBaseId, movedBase );
        }
        
        NamingEnumeration aliases = new IndexAssertionEnumeration(
            aliasIdx.listIndices( movedBase.toString(), true ), 
            isBaseDescendant );
        while ( aliases.hasMore() )
        {
            IndexRecord entry = ( IndexRecord ) aliases.next();
            dropAliasIndices( entry.getEntryId(), movedBase );
        }
    }
    
    
    /**
     * For the alias id all ancestor one and subtree alias tuples are moved 
     * above the moved base.
     * 
     * @param aliasId the id of the alias 
     * @param movedBase the base where the move occured
     * @throws NamingException if indices fail
     */
    private void dropAliasIndices( BigInteger aliasId, Name movedBase )
        throws NamingException
    {
        String targetDn = ( String ) aliasIdx.reverseLookup( aliasId );
        BigInteger targetId = getEntryId( targetDn );
        String aliasDn = getEntryDn( aliasId );
        
        /*
         * Start droping index tuples with the first ancestor right above the 
         * moved base.  This is the first ancestor effected by the move.
         */
        Name ancestorDn = movedBase.getSuffix( 1 );
        BigInteger ancestorId = getEntryId( ancestorDn.toString() );
        
        /*
         * We cannot just drop all tuples in the one level and subtree indices
         * linking baseIds to the targetId.  If more than one alias refers to
         * the target then droping all tuples with a value of targetId would
         * make all other aliases to the target inconsistent.
         * 
         * We need to walk up the path of alias ancestors right above the moved 
         * base until we reach the upSuffix, deleting each ( ancestorId,
         * targetId ) tuple in the subtree scope alias.  We only need to do 
         * this for the direct parent of the alias on the one level subtree if
         * the moved base is the alias.
         */
        if ( aliasDn.equals( movedBase.toString() ) )
        {
            oneAliasIdx.drop( ancestorId, targetId );
        }
        
        subAliasIdx.drop( ancestorId, targetId );
        
        while ( ! ancestorDn.equals( upSuffix ) )
        {
            ancestorDn = ancestorDn.getSuffix( 1 );
            ancestorId = getEntryId( ancestorDn.toString() );
            
            subAliasIdx.drop( ancestorId, targetId );
        }    
    }
}

