/*
 *  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;


import java.util.Hashtable;

import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NoPermissionException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SchemaViolationException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

import org.apache.directory.server.unit.AbstractServerTest;
import org.apache.directory.shared.ldap.message.AttributeImpl;
import org.apache.directory.shared.ldap.message.AttributesImpl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


/**
 * Testcase with different modify DN operations on a person entry.
 * Originally created to demonstrate DIREVE-173.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class ModifyRdnTest extends AbstractServerTest
{

    private LdapContext ctx = null;


    /**
     * Create attributes for a person entry.
     */
    protected Attributes getPersonAttributes( String sn, String cn )
    {
        Attributes attributes = new AttributesImpl();
        Attribute attribute = new AttributeImpl( "objectClass" );
        attribute.add( "top" );
        attribute.add( "person" );
        attributes.put( attribute );
        attributes.put( "cn", cn );
        attributes.put( "sn", sn );
        attributes.put( "description", cn + " is a person." );

        return attributes;
    }


    /**
     * Create attributes for a organizational unit entry.
     */
    protected Attributes getOrganizationalUnitAttributes( String ou )
    {
        Attributes attributes = new AttributesImpl();
        Attribute attribute = new AttributeImpl( "objectClass" );
        attribute.add( "top" );
        attribute.add( "organizationalUnit" );
        attributes.put( attribute );
        attributes.put( "ou", ou );
        attributes.put( "description", ou + " is an organizational unit." );

        return attributes;
    }


    /**
     * Create context
     */
    @Before
    public void setUp() throws Exception
    {
        super.setUp();

        Hashtable<String, Object> env = new Hashtable<String, Object>();
        env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
        env.put( "java.naming.provider.url", "ldap://localhost:" + port + "/ou=system" );
        env.put( "java.naming.security.principal", "uid=admin,ou=system" );
        env.put( "java.naming.security.credentials", "secret" );
        env.put( "java.naming.security.authentication", "simple" );
        ctx = new InitialLdapContext( env, null );
        assertNotNull( ctx );
    }


    /**
     * Close context
     */
    @After
    public void tearDown() throws Exception
    {
        ctx.close();
        ctx = null;

        super.tearDown();
    }


    /**
     * Just a little test to check wether opening the connection succeeds.
     */
    @Test
    public void testSetUpTearDown()
    {
        assertNotNull( ctx );
    }


    /**
     * Modify Rdn of an entry, delete its old rdn value.
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyRdnAndDeleteOld() throws NamingException
    {
        // Create a person, cn value is rdn
        String oldCn = "Myra Ellen Amos";
        String oldRdn = "cn=" + oldCn;
        Attributes attributes = this.getPersonAttributes( "Amos", oldCn );
        ctx.createSubcontext( oldRdn, attributes );

        // modify Rdn
        String newCn = "Tori Amos";
        String newRdn = "cn=" + newCn;
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        ctx.rename( oldRdn, newRdn );

        // Check, whether old Entry does not exists
        try
        {
            ctx.lookup( oldRdn );
            fail( "Entry must not exist" );
        }
        catch ( NameNotFoundException ignored )
        {
            // expected behaviour
            assertTrue( true );
        }

        // Check, whether new Entry exists
        DirContext tori = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( tori );

        // Check values of cn
        Attribute cn = tori.getAttributes( "" ).get( "cn" );
        assertTrue( cn.contains( newCn ) );
        assertTrue( !cn.contains( oldCn ) ); // old value is gone
        assertEquals( 1, cn.size() );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Modify Rdn of an entry, without deleting its old rdn value.
     * 
     * The JNDI property is set with 'False'
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyRdnAndDontDeleteOldFalse() throws NamingException
    {
        // Create a person, cn value is rdn
        String oldCn = "Myra Ellen Amos";
        String oldRdn = "cn=" + oldCn;
        Attributes attributes = this.getPersonAttributes( "Amos", oldCn );
        ctx.createSubcontext( oldRdn, attributes );

        // modify Rdn
        String newCn = "Tori Amos";
        String newRdn = "cn=" + newCn;
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "False" );
        ctx.rename( oldRdn, newRdn );

        // Check, whether old Entry does not exists
        try
        {
            ctx.lookup( oldRdn );
            fail( "Entry must not exist" );
        }
        catch ( NameNotFoundException ignored )
        {
            // expected behaviour
            assertTrue( true );
        }

        // Check, whether new Entry exists
        DirContext tori = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( tori );

        // Check values of cn
        Attribute cn = tori.getAttributes( "" ).get( "cn" );
        assertTrue( cn.contains( newCn ) );
        assertTrue( cn.contains( oldCn ) ); // old value is still there
        assertEquals( 2, cn.size() );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Modify Rdn of an entry, keep its old rdn value.
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyRdnAndKeepOld() throws NamingException
    {
        // Create a person, cn value is rdn
        String oldCn = "Myra Ellen Amos";
        String oldRdn = "cn=" + oldCn;
        Attributes attributes = this.getPersonAttributes( "Amos", oldCn );
        ctx.createSubcontext( oldRdn, attributes );

        // modify Rdn
        String newCn = "Tori Amos";
        String newRdn = "cn=" + newCn;
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
        ctx.rename( oldRdn, newRdn );

        // Check, whether old entry does not exist
        try
        {
            ctx.lookup( oldRdn );
            fail( "Entry must not exist" );
        }
        catch ( NameNotFoundException ignored )
        {
            // expected behaviour
            assertTrue( true );
        }

        // Check, whether new entry exists
        DirContext tori = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( tori );

        // Check values of cn
        Attribute cn = tori.getAttributes( "" ).get( "cn" );
        assertTrue( cn.contains( newCn ) );
        assertTrue( cn.contains( oldCn ) ); // old value is still there
        assertEquals( 2, cn.size() );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Modify Rdn of an entry, delete its old rdn value. Here, the rdn attribute
     * cn has another value as well.
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyRdnAndDeleteOldVariant() throws NamingException
    {
        // Create a person, cn value is rdn
        String oldCn = "Myra Ellen Amos";
        String oldRdn = "cn=" + oldCn;
        Attributes attributes = this.getPersonAttributes( "Amos", oldCn );

        // add a second cn value
        String alternateCn = "Myra E. Amos";
        Attribute cn = attributes.get( "cn" );
        cn.add( alternateCn );
        assertEquals( 2, cn.size() );

        ctx.createSubcontext( oldRdn, attributes );

        // modify Rdn
        String newCn = "Tori Amos";
        String newRdn = "cn=" + newCn;
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        ctx.rename( oldRdn, newRdn );

        // Check, whether old Entry does not exist anymore
        try
        {
            ctx.lookup( oldRdn );
            fail( "Entry must not exist" );
        }
        catch ( NameNotFoundException ignored )
        {
            // expected behaviour
            assertTrue( true );
        }

        // Check, whether new Entry exists
        DirContext tori = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( tori );

        // Check values of cn
        cn = tori.getAttributes( "" ).get( "cn" );
        assertTrue( cn.contains( newCn ) );
        assertTrue( !cn.contains( oldCn ) ); // old value is gone
        assertTrue( cn.contains( alternateCn ) ); // alternate value is still available
        assertEquals( 2, cn.size() );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Modify DN of an entry, changing RDN from cn to sn.
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyRdnDifferentAttribute() throws NamingException
    {
        // Create a person, cn value is rdn
        String cnVal = "Tori Amos";
        String snVal = "Amos";
        String oldRdn = "cn=" + cnVal;
        Attributes attributes = this.getPersonAttributes( snVal, cnVal );
        ctx.createSubcontext( oldRdn, attributes );

        // modify Rdn from cn=... to sn=...
        String newRdn = "sn=" + snVal;
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
        ctx.rename( oldRdn, newRdn );

        // Check, whether old Entry does not exists
        try
        {
            ctx.lookup( oldRdn );
            fail( "Entry must not exist" );
        }
        catch ( NameNotFoundException ignored )
        {
            // expected behaviour
        }

        // Check, whether new Entry exists
        DirContext tori = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( tori );

        // Check values of cn and sn
        // especially the number of cn and sn occurences
        Attribute cn = tori.getAttributes( "" ).get( "cn" );
        assertTrue( cn.contains( cnVal ) );
        assertEquals( "Number of cn occurences", 1, cn.size() );
        Attribute sn = tori.getAttributes( "" ).get( "sn" );
        assertTrue( sn.contains( snVal ) );
        assertEquals( "Number of sn occurences", 1, sn.size() );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Modify DN of an entry, changing RDN from cn to sn, 
     * delete old RDn, must fail because cn can not be deleted.
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyRdnDifferentAttributeDeleteOldFails() throws NamingException
    {
        // Create a person, cn value is rdn
        String cnVal = "Tori Amos";
        String snVal = "Amos";
        String oldRdn = "cn=" + cnVal;
        Attributes attributes = this.getPersonAttributes( snVal, cnVal );
        ctx.createSubcontext( oldRdn, attributes );

        // modify Rdn from cn=... to sn=...
        String newRdn = "sn=" + snVal;
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        try
        {
            ctx.rename( oldRdn, newRdn );
            fail( "Rename must fail, mandatory attirbute cn can not be deleted." );
        }
        catch ( SchemaViolationException ignored )
        {
            // expected behaviour
        }

        // Remove entry (use old rdn)
        ctx.unbind( oldRdn );
    }


    /**
     * Test for DIRSERVER-1086.
     * Modify Rdn of an entry that has a child entry, delete its old rdn value.
     * Ensure that the tree is not broken.
     *
     * @throws NamingException
     */
    @Test
    public void testModifyRdnAndDeleteOldWithChild() throws NamingException
    {
        // Create an organizational unit, ou value is rdn
        String oldOu = "Writers";
        String oldRdn = "ou=" + oldOu;
        Attributes attributes = this.getOrganizationalUnitAttributes( oldOu );
        DirContext createdCtx = ctx.createSubcontext( oldRdn, attributes );

        // Create a child
        String childCn = "Tori Amos";
        String childRdn = "cn=" + childCn;
        Attributes childAttributes = this.getPersonAttributes( "Amos", childCn );
        createdCtx.createSubcontext( childRdn, childAttributes );

        // modify Rdn
        String newOu = "Singers";
        String newRdn = "ou=" + newOu;
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        ctx.rename( oldRdn, newRdn );

        // Check, whether old Entry does not exists
        try
        {
            ctx.lookup( oldRdn );
            fail( "Entry must not exist" );
        }
        catch ( NameNotFoundException ignored )
        {
            // expected behaviour
            assertTrue( true );
        }

        // Check, whether new Entry exists
        DirContext org = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( org );

        // Check values of ou
        Attribute ou = org.getAttributes( "" ).get( "ou" );
        assertTrue( ou.contains( newOu ) );
        assertTrue( !ou.contains( oldOu ) ); // old value is gone
        assertEquals( 1, ou.size() );

        // Perform a search under renamed ou and check whether exactly one child entry exist
        SearchControls searchControls = new SearchControls();
        searchControls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
        searchControls.setReturningAttributes( new String[]
            { "objectClass" } );
        NamingEnumeration<SearchResult> results = org.search( "", "(objectClass=*)", searchControls );
        assertTrue( results.hasMore() );
        results.next();
        assertTrue( !results.hasMore() );

        // Check whether Tori exists
        DirContext tori = ( DirContext ) org.lookup( childRdn );
        assertNotNull( tori );

        // Remove entry (use new rdn)
        ctx.unbind( childRdn + "," + newRdn );
        ctx.unbind( newRdn );
    }


    /**
     * Test for DIRSERVER-1096.
     * Modify the RDN of an entry with an escaped new RDN. 
     * Ensure that the attribute itself contains the unescaped value.
     *
     * @throws Exception
     */
    @Test
    public void testModifyRdnWithEncodedNewRdn() throws Exception
    {
        // Create a person "cn=Tori Amos", cn value is rdn
        String cnVal = "Tori Amos";
        String snVal = "Amos";
        String oldRdn = "cn=" + cnVal;
        Attributes attributes = this.getPersonAttributes( snVal, cnVal );
        ctx.createSubcontext( oldRdn, attributes );

        // modify Rdn from cn=Tori Amos to cn=<a Umlaut>\+
        String newCnEscapedVal = new String( new byte[]
            { ( byte ) 0xC3, ( byte ) 0xA4, '\\', '+' }, "UTF-8" );
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        String newRdn = "cn=" + newCnEscapedVal;
        ctx.rename( oldRdn, newRdn );

        // Check, whether old Entry does not exists
        try
        {
            ctx.lookup( oldRdn );
            fail( "Entry must not exist" );
        }
        catch ( NameNotFoundException ignored )
        {
            // expected behaviour
        }

        // Check, whether new Entry exists
        DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( newCtx );

        // Check that the DN contains the escaped value
        assertEquals( "cn=" + newCnEscapedVal + "," + ctx.getNameInNamespace(), newCtx.getNameInNamespace() );

        // Check that cn contains the unescaped value
        Attribute cn = newCtx.getAttributes( "" ).get( "cn" );
        assertEquals( "Number of cn occurences", 1, cn.size() );
        assertTrue( cn.contains( "\\C3\\A4\\+" ) );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Test for DIRSERVER-1162 and DIRSERVER-1085.
     * 
     * Modify single valued RDN to a multi valued RDN.
     * - Old Rdn: cn
     * - New Rdn: cn+sn
     * - Keep old Rdn
     * - Attributes: cn, sn, description must exist 
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyMultiValuedRdnVariant1() throws NamingException
    {
        Attributes attributes = createPerson( "cn" );
        String oldRdn = getRdn( attributes, "cn" );
        String newRdn = getRdn( attributes, "cn", "sn" );

        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
        ctx.rename( oldRdn, newRdn );

        // Check whether new Entry exists
        DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( newCtx );

        // Check attributes
        Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
        assertEquals( 1, cnAttr.size() );
        assertTrue( cnAttr.contains( "Tori Amos" ) );
        Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
        assertEquals( 1, snAttr.size() );
        assertTrue( snAttr.contains( "Amos" ) );
        Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
        assertEquals( 1, descriptionAttr.size() );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Test for DIRSERVER-1162 and DIRSERVER-1085.
     * 
     * Modify single valued RDN to a multi valued RDN.
     * - Old Rdn: cn
     * - New Rdn: cn+sn
     * - Delete old Rdn
     * - Attributes: cn, sn, description must exist 
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyMultiValuedRdnVariant2() throws NamingException
    {
        Attributes attributes = createPerson( "cn" );
        String oldRdn = getRdn( attributes, "cn" );
        String newRdn = getRdn( attributes, "cn", "sn" );

        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        ctx.rename( oldRdn, newRdn );

        // Check whether new Entry exists
        DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( newCtx );

        // Check attributes
        Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
        assertEquals( 1, cnAttr.size() );
        assertTrue( cnAttr.contains( "Tori Amos" ) );
        Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
        assertEquals( 1, snAttr.size() );
        assertTrue( snAttr.contains( "Amos" ) );
        Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
        assertEquals( 1, descriptionAttr.size() );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Test for DIRSERVER-1162 and DIRSERVER-1085.
     * 
     * Modify single valued RDN to a multi valued RDN.
     * - Old Rdn: description
     * - New Rdn: cn+sn
     * - Keep old Rdn
     * - Attributes: cn, sn, description must exist 
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyMultiValuedRdnVariant3() throws NamingException
    {
        Attributes attributes = createPerson( "description" );
        String oldRdn = getRdn( attributes, "description" );
        String newRdn = getRdn( attributes, "cn", "sn" );

        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
        ctx.rename( oldRdn, newRdn );

        // Check whether new Entry exists
        DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( newCtx );

        // Check attributes
        Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
        assertEquals( 1, cnAttr.size() );
        assertTrue( cnAttr.contains( "Tori Amos" ) );
        Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
        assertEquals( 1, snAttr.size() );
        assertTrue( snAttr.contains( "Amos" ) );
        Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
        assertEquals( 1, descriptionAttr.size() );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Test for DIRSERVER-1162 and DIRSERVER-1085.
     * 
     * Modify single valued RDN to a multi valued RDN.
     * - Old Rdn: description
     * - New Rdn: cn+sn
     * - Delete old Rdn
     * - Attributes: cn, sn must exist; descriptions must not exist 
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyMultiValuedRdnVariant4() throws NamingException
    {
        Attributes attributes = createPerson( "description" );
        String oldRdn = getRdn( attributes, "description" );
        String newRdn = getRdn( attributes, "cn", "sn" );

        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        ctx.rename( oldRdn, newRdn );

        // Check whether new Entry exists
        DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( newCtx );

        // Check attributes
        Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
        assertEquals( 1, cnAttr.size() );
        assertTrue( cnAttr.contains( "Tori Amos" ) );
        Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
        assertEquals( 1, snAttr.size() );
        assertTrue( snAttr.contains( "Amos" ) );
        Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
        assertNull( descriptionAttr );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Test for DIRSERVER-1162 and DIRSERVER-1085.
     * 
     * Modify single valued RDN to a multi valued RDN.
     * - Old Rdn: cn
     * - New Rdn: sn+telephoneNumber
     * - Keep old Rdn
     * - Attributes: cn, sn, description, telephoneNumber must exist 
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyMultiValuedRdnVariant5() throws NamingException
    {
        Attributes attributes = createPerson( "cn" );
        attributes.put( "telephoneNumber", "12345" );
        String oldRdn = getRdn( attributes, "cn" );
        String newRdn = getRdn( attributes, "sn", "telephoneNumber" );

        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
        ctx.rename( oldRdn, newRdn );

        // Check whether new Entry exists
        DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( newCtx );

        // Check attributes
        Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
        assertEquals( 1, cnAttr.size() );
        assertTrue( cnAttr.contains( "Tori Amos" ) );
        Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
        assertEquals( 1, snAttr.size() );
        assertTrue( snAttr.contains( "Amos" ) );
        Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
        assertEquals( 1, descriptionAttr.size() );
        Attribute telephoneNumberAttr = newCtx.getAttributes( "" ).get( "telephoneNumber" );
        assertEquals( 1, telephoneNumberAttr.size() );
        assertTrue( telephoneNumberAttr.contains( "12345" ) );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Test for DIRSERVER-1162 and DIRSERVER-1085.
     * 
     * Modify single valued RDN to a multi valued RDN.
     * - Old Rdn: cn
     * - New Rdn: sn+telephoneNumber
     * - Delete old Rdn
     * - Must fail with schema violation, cn cannot be deleted
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyMultiValuedRdnVariant6() throws NamingException
    {
        Attributes attributes = createPerson( "cn" );
        attributes.put( "telephoneNumber", "12345" );
        String oldRdn = getRdn( attributes, "cn" );
        String newRdn = getRdn( attributes, "sn", "telephoneNumber" );

        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        try
        {
            ctx.rename( oldRdn, newRdn );
            fail( "Rename must fail, cn can not be deleted from a person." );
        }
        catch ( SchemaViolationException ignored )
        {
            // expected behaviour
        }

        // Check that entry was not changed
        try
        {
            ctx.lookup( newRdn );
            fail( "Previous rename failed as expected, entry must not exist" );
        }
        catch ( NameNotFoundException ignored )
        {
            // expected behaviour
        }

        // Check that entry was not changed
        DirContext oldCtx = ( DirContext ) ctx.lookup( oldRdn );
        assertNotNull( oldCtx );
        Attribute cnAttr = oldCtx.getAttributes( "" ).get( "cn" );
        assertEquals( 1, cnAttr.size() );
        assertTrue( cnAttr.contains( "Tori Amos" ) );
        Attribute snAttr = oldCtx.getAttributes( "" ).get( "sn" );
        assertEquals( 1, snAttr.size() );
        assertTrue( snAttr.contains( "Amos" ) );
        Attribute descriptionAttr = oldCtx.getAttributes( "" ).get( "description" );
        assertEquals( 1, descriptionAttr.size() );

        // Remove entry (use old rdn)
        ctx.unbind( oldRdn );
    }


    /**
     * Test for DIRSERVER-1162 and DIRSERVER-1085.
     * 
     * Modify multi valued RDN to a single valued RDN.
     * - Old Rdn: cn+sn
     * - New Rdn: cn
     * - Keep old Rdn
     * - Attributes: cn, sn, description must exist 
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyMultiValuedRdnVariant7() throws NamingException
    {
        Attributes attributes = createPerson( "cn", "sn" );
        String oldRdn = getRdn( attributes, "cn", "sn" );
        String newRdn = getRdn( attributes, "cn" );

        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
        ctx.rename( oldRdn, newRdn );

        // Check whether new Entry exists
        DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( newCtx );

        // Check attributes
        Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
        assertEquals( 1, cnAttr.size() );
        assertTrue( cnAttr.contains( "Tori Amos" ) );
        Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
        assertEquals( 1, snAttr.size() );
        assertTrue( snAttr.contains( "Amos" ) );
        Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
        assertEquals( 1, descriptionAttr.size() );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Test for DIRSERVER-1162 and DIRSERVER-1085.
     * 
     * Modify multi valued RDN to a single valued RDN.
     * - Old Rdn: cn+sn
     * - New Rdn: cn
     * - Delete old Rdn
     * - Must fail with schema violation, cn cannot be deleted
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyMultiValuedRdnVariant8() throws NamingException
    {
        Attributes attributes = createPerson( "cn", "sn" );
        String oldRdn = getRdn( attributes, "cn", "sn" );
        String newRdn = getRdn( attributes, "cn" );

        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        try
        {
            ctx.rename( oldRdn, newRdn );
            fail( "Rename must fail, cn can not be deleted from a person." );
        }
        catch ( SchemaViolationException ignored )
        {
            // expected behaviour
        }

        // Check that entry was not changed
        try
        {
            ctx.lookup( newRdn );
            fail( "Previous rename failed as expected, entry must not exist" );
        }
        catch ( NameNotFoundException ignored )
        {
            // expected behaviour
        }

        // Check that entry was not changed
        DirContext oldCtx = ( DirContext ) ctx.lookup( oldRdn );
        assertNotNull( oldCtx );
        Attribute cnAttr = oldCtx.getAttributes( "" ).get( "cn" );
        assertEquals( 1, cnAttr.size() );
        assertTrue( cnAttr.contains( "Tori Amos" ) );
        Attribute snAttr = oldCtx.getAttributes( "" ).get( "sn" );
        assertEquals( 1, snAttr.size() );
        assertTrue( snAttr.contains( "Amos" ) );
        Attribute descriptionAttr = oldCtx.getAttributes( "" ).get( "description" );
        assertEquals( 1, descriptionAttr.size() );

        // Remove entry (use old rdn)
        ctx.unbind( oldRdn );
    }


    /**
     * Test for DIRSERVER-1162 and DIRSERVER-1085.
     * 
     * Tries to rename+deleteOldRdn an entry that has an operational attribute
     * in its RDN. Must fail because an operational attribute can not be
     * deleted.
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyRdnOperationalAttribute() throws NamingException
    {
        // create the entry
        Attributes attributes = createPerson( "cn" );
        String oldRdn = getRdn( attributes, "cn" );

        // read createTimestamp
        String createTimestamp = ( String ) ctx.getAttributes( oldRdn, new String[]
            { "createTimestamp" } ).get( "createTimestamp" ).get();

        // rename to createTimstamp=YYYYMMDDHHMMSSZ
        String newRdn = "createTimestamp=" + createTimestamp;
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
        ctx.rename( oldRdn, newRdn );

        // rename back to old Rdn, enable deleteOldRdn, 
        // must fail with NoPermisionException
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        try
        {
            ctx.rename( newRdn, oldRdn );
            fail( "Rename must fail, operational attribute createTimestamp can not be deleted." );
        }
        catch ( NoPermissionException ignored )
        {
            // expected behaviour
        }

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    /**
     * Test for DIRSERVER-1096.
     * Modify the RDN of an entry with an escaped new RDN. 
     * Ensure that the attribute itself contains the unescaped value.
     *
     * @throws Exception
     */
    @Test
    public void testModifyRdnWithEscapedPoundNewRdn() throws Exception
    {
        // Create a person "cn=Tori Amos", cn value is rdn
        String cnVal = "Tori Amos";
        String snVal = "Amos";
        String oldRdn = "cn=" + cnVal;
        Attributes attributes = this.getPersonAttributes( snVal, cnVal );
        ctx.createSubcontext( oldRdn, attributes );

        // modify Rdn from cn=Tori Amos to cn=\#test\+
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        String newRdn = "cn=\\23test";
        ctx.rename( oldRdn, newRdn );

        // Check, whether old Entry does not exists
        try
        {
            ctx.lookup( oldRdn );
            fail( "Entry must not exist" );
        }
        catch ( NameNotFoundException ignored )
        {
            // expected behaviour
        }

        // Check, whether new Entry exists
        DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
        assertNotNull( newCtx );

        // Check that the DN contains the escaped value
        assertEquals( "cn=\\23test," + ctx.getNameInNamespace(), newCtx.getNameInNamespace() );

        // Check that cn contains the unescaped value
        Attribute cn = newCtx.getAttributes( "" ).get( "cn" );
        assertEquals( "Number of cn occurences", 1, cn.size() );
        assertTrue( cn.contains( "\\#test" ) );

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }

    
    /**
     * Test for DIRSERVER-1162 and DIRSERVER-1085.
     * 
     * Tries to rename+deleteOldRdn an entry that has the structural object class
     * person in its RDN (objectClass=person,ou=system). Must fail because the 
     * structural object class can not be deleted.
     * 
     * @throws NamingException
     */
    @Test
    public void testModifyRdnObjectClassAttribute() throws NamingException
    {
        // create the entry
        Attributes attributes = createPerson( "cn" );
        String oldRdn = getRdn( attributes, "cn" );

        // rename to objectClass=person
        String newRdn = "objectClass=person";
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
        ctx.rename( oldRdn, newRdn );

        // rename back to old Rdn, enable deleteOldRdn, 
        // must fail with NoPermisionException
        ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        try
        {
            ctx.rename( newRdn, oldRdn );
            fail( "Rename must fail, structural objectClass person can not be deleted." );
        }
        catch ( SchemaViolationException ignored )
        {
            // expected behaviour
        }

        // Remove entry (use new rdn)
        ctx.unbind( newRdn );
    }


    private String getRdn( Attributes attributes, String... rdnTypes ) throws NamingException
    {
        String rdn = "";
        for ( String type : rdnTypes )
        {
            rdn += type + "=" + attributes.get( type ).get() + "+";
        }
        rdn = rdn.substring( 0, rdn.length() - 1 );
        return rdn;
    }


    private Attributes createPerson( String... rdnTypes ) throws NamingException
    {
        Attributes attributes = new AttributesImpl();
        Attribute attribute = new AttributeImpl( "objectClass" );
        attribute.add( "top" );
        attribute.add( "person" );
        attributes.put( attribute );
        attributes.put( "cn", "Tori Amos" );
        attributes.put( "sn", "Amos" );
        attributes.put( "description", "Tori Amos is a person." );

        String rdn = getRdn( attributes, rdnTypes );

        ctx.createSubcontext( rdn, attributes );

        return attributes;
    }

}
