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


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.naming.directory.InvalidAttributeValueException;

import org.apache.commons.io.FileUtils;
import com.mycila.junit.concurrent.Concurrency;
import com.mycila.junit.concurrent.ConcurrentJunitRunner;
import org.apache.directory.shared.ldap.model.entry.BinaryValue;
import org.apache.directory.shared.ldap.model.entry.DefaultEntryAttribute;
import org.apache.directory.shared.ldap.model.entry.EntryAttribute;
import org.apache.directory.shared.ldap.model.entry.StringValue;
import org.apache.directory.shared.ldap.model.entry.Value;
import org.apache.directory.shared.ldap.model.exception.LdapException;
import org.apache.directory.shared.ldap.model.exception.LdapInvalidAttributeValueException;
import org.apache.directory.shared.ldap.model.schema.MutableAttributeTypeImpl;
import org.apache.directory.shared.ldap.model.schema.SchemaManager;
import org.apache.directory.shared.ldap.schemaextractor.SchemaLdifExtractor;
import org.apache.directory.shared.ldap.schemaextractor.impl.DefaultSchemaLdifExtractor;
import org.apache.directory.shared.ldap.schemaloader.LdifSchemaLoader;
import org.apache.directory.shared.ldap.schemamanager.impl.DefaultSchemaManager;
import org.apache.directory.shared.util.exception.Exceptions;
import org.apache.directory.shared.util.StringConstants;
import org.apache.directory.shared.util.Strings;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;


/**
 * Tests for the DefaultEntryAttribute class
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
@RunWith(ConcurrentJunitRunner.class)
@Concurrency()
public class SchemaAwareEntryAttributeTest
{
    private static LdifSchemaLoader loader;

    private static MutableAttributeTypeImpl atCN;
    private static MutableAttributeTypeImpl atDC;
    private static MutableAttributeTypeImpl atSN;

    // A SINGLE-VALUE attribute
    private static MutableAttributeTypeImpl atC;

    // A Binary attribute
    private static MutableAttributeTypeImpl atPwd;

    private static final Value<String> NULL_STRING_VALUE = new StringValue( ( String ) null );
    private static final Value<byte[]> NULL_BINARY_VALUE = new BinaryValue( ( byte[] ) null );
    private static final byte[] BYTES1 = new byte[]
        { 'a', 'b' };
    private static final byte[] BYTES2 = new byte[]
        { 'b' };
    private static final byte[] BYTES3 = new byte[]
        { 'c' };
    private static final byte[] BYTES4 = new byte[]
        { 'd' };

    private static final StringValue STR_VALUE1 = new StringValue( "a" );
    private static final StringValue STR_VALUE2 = new StringValue( "b" );
    private static final StringValue STR_VALUE3 = new StringValue( "c" );
    private static final StringValue STR_VALUE4 = new StringValue( "d" );

    private static final BinaryValue BIN_VALUE1 = new BinaryValue( BYTES1 );
    private static final BinaryValue BIN_VALUE2 = new BinaryValue( BYTES2 );
    private static final BinaryValue BIN_VALUE3 = new BinaryValue( BYTES3 );
    private static final BinaryValue BIN_VALUE4 = new BinaryValue( BYTES4 );


    /**
     * Initialize the registries once for the whole test suite
     */
    @BeforeClass
    public static void setup() throws Exception
    {
        String workingDirectory = System.getProperty( "workingDirectory" );

        if ( workingDirectory == null )
        {
            String path = SchemaAwareEntryAttributeTest.class.getResource( "" ).getPath();
            int targetPos = path.indexOf( "target" );
            workingDirectory = path.substring( 0, targetPos + 6 );
        }

        // Cleanup the target directory
        File schemaRepository = new File( workingDirectory, "schema" );
        FileUtils.deleteDirectory( schemaRepository );

        SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor( new File( workingDirectory ) );
        extractor.extractOrCopy( true );
        loader = new LdifSchemaLoader( schemaRepository );
        SchemaManager schemaManager = new DefaultSchemaManager( loader );

        schemaManager.loadAllEnabled();

        List<Throwable> errors = schemaManager.getErrors();

        if ( errors.size() != 0 )
        {
            // We have inconsistencies : log them and exit.
            throw new RuntimeException( "Inconsistent schemas : " + Exceptions.printErrors(errors) );
        }

        atCN = schemaManager.lookupAttributeTypeRegistry( "cn" );
        atDC = schemaManager.lookupAttributeTypeRegistry( "dc" );
        atC = schemaManager.lookupAttributeTypeRegistry( "c" );
        atSN = schemaManager.lookupAttributeTypeRegistry( "sn" );
        atPwd = schemaManager.lookupAttributeTypeRegistry( "userpassword" );
    }


    /**
     * Serialize a DefaultEntryAttribute
     */
    private ByteArrayOutputStream serializeValue( DefaultEntryAttribute value ) throws IOException
    {
        ObjectOutputStream oOut = null;
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        try
        {
            oOut = new ObjectOutputStream( out );
            value.serialize( oOut );
        }
        catch ( IOException ioe )
        {
            throw ioe;
        }
        finally
        {
            try
            {
                if ( oOut != null )
                {
                    oOut.flush();
                    oOut.close();
                }
            }
            catch ( IOException ioe )
            {
                throw ioe;
            }
        }

        return out;
    }


    /**
     * Deserialize a DefaultEntryAttribute
     */
    private DefaultEntryAttribute deserializeValue( ByteArrayOutputStream out, MutableAttributeTypeImpl at ) throws IOException,
        ClassNotFoundException
    {
        ObjectInputStream oIn = null;
        ByteArrayInputStream in = new ByteArrayInputStream( out.toByteArray() );

        try
        {
            oIn = new ObjectInputStream( in );

            DefaultEntryAttribute value = new DefaultEntryAttribute( at );
            value.deserialize( oIn );

            return value;
        }
        catch ( IOException ioe )
        {
            throw ioe;
        }
        finally
        {
            try
            {
                if ( oIn != null )
                {
                    oIn.close();
                }
            }
            catch ( IOException ioe )
            {
                throw ioe;
            }
        }
    }


    @Test
    public void testAddOneValue() throws Exception
    {
        MutableAttributeTypeImpl at = TestServerEntryUtils.getIA5StringAttributeType();

        DefaultEntryAttribute attr = new DefaultEntryAttribute( at );

        // Add a String value
        attr.add( "test" );

        assertEquals( 1, attr.size() );

        assertTrue( attr.getAttributeType().getSyntax().isHumanReadable() );

        Value<?> value = attr.get();

        assertTrue( value instanceof StringValue );
        assertEquals( "test", ( ( StringValue ) value ).getString() );

        // Add a binary value
        assertEquals( 0, attr.add( new byte[]
            { 0x01 } ) );

        // Add a Value
        Value<?> ssv = new StringValue( at, "test2" );

        attr.add( ssv );

        assertEquals( 2, attr.size() );

        Set<String> expected = new HashSet<String>();
        expected.add( "test" );
        expected.add( "test2" );

        for ( Value<?> val : attr )
        {
            if ( expected.contains( val.get() ) )
            {
                expected.remove( val.get() );
            }
            else
            {
                fail();
            }
        }

        assertEquals( 0, expected.size() );
    }


    @Test
    public void testAddTwoValue() throws Exception
    {
        MutableAttributeTypeImpl at = TestServerEntryUtils.getIA5StringAttributeType();

        DefaultEntryAttribute attr = new DefaultEntryAttribute( at );

        // Add String values
        attr.add( "test" );
        attr.add( "test2" );

        assertEquals( 2, attr.size() );

        assertTrue( attr.getAttributeType().getSyntax().isHumanReadable() );

        Set<String> expected = new HashSet<String>();
        expected.add( "test" );
        expected.add( "test2" );

        for ( Value<?> val : attr )
        {
            if ( expected.contains( val.get() ) )
            {
                expected.remove( val.get() );
            }
            else
            {
                fail();
            }
        }

        assertEquals( 0, expected.size() );
    }


    @Test
    public void testAddNullValue() throws Exception
    {
        MutableAttributeTypeImpl at = TestServerEntryUtils.getIA5StringAttributeType();

        DefaultEntryAttribute attr = new DefaultEntryAttribute( at );

        // Add a null value
        attr.add( new StringValue( at, null ) );

        assertEquals( 1, attr.size() );

        assertTrue( attr.getAttributeType().getSyntax().isHumanReadable() );

        Value<?> value = attr.get();

        assertTrue( value instanceof StringValue );
        assertNull( ( ( StringValue ) value ).get() );
    }


    @Test
    public void testGetAttribute() throws Exception
    {
        MutableAttributeTypeImpl at = TestServerEntryUtils.getIA5StringAttributeType();

        DefaultEntryAttribute attr = new DefaultEntryAttribute( at );

        attr.add( "Test1" );
        attr.add( "Test2" );
        attr.add( "Test3" );

        assertEquals( "1.1", attr.getId() );
        assertEquals( 3, attr.size() );
        assertTrue( attr.contains( "Test1" ) );
        assertTrue( attr.contains( "Test2" ) );
        assertTrue( attr.contains( "Test3" ) );
    }


    /**
     * Test the contains() method
     */
    @Test
    public void testContains() throws Exception
    {
        MutableAttributeTypeImpl at = TestServerEntryUtils.getIA5StringAttributeType();

        DefaultEntryAttribute attr = new DefaultEntryAttribute( at );

        attr.add( "Test  1" );
        attr.add( "Test  2" );
        attr.add( "Test  3" );

        assertTrue( attr.contains( "test 1" ) );
        assertTrue( attr.contains( "Test 2" ) );
        assertTrue( attr.contains( "TEST     3" ) );
    }


    /**
     * Test method getBytes()
     */
    @Test
    public void testGetBytes() throws LdapInvalidAttributeValueException
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atPwd );

        attr1.add( ( byte[] ) null );
        assertNull( attr1.getBytes() );

        EntryAttribute attr2 = new DefaultEntryAttribute( atPwd );

        attr2.add( BYTES1, BYTES2 );
        assertTrue( Arrays.equals( BYTES1, attr2.getBytes() ) );

        EntryAttribute attr3 = new DefaultEntryAttribute( atCN );

        attr3.add( "a", "b" );

        try
        {
            attr3.getBytes();
            fail();
        }
        catch ( LdapInvalidAttributeValueException ivae )
        {
            assertTrue( true );
        }
    }


    /**
     * Test method getId()
     */
    @Test
    public void testGetId()
    {
        EntryAttribute attr = new DefaultEntryAttribute( atCN );

        assertEquals( "cn", attr.getId() );

        attr.setId( "  CN  " );
        assertEquals( "cn", attr.getId() );

        attr.setId( "  CommonName  " );
        assertEquals( "commonname", attr.getId() );

        attr.setId( "  2.5.4.3  " );
        assertEquals( "2.5.4.3", attr.getId() );
    }


    /**
     * Test method getString()
     */
    @Test
    public void testGetString() throws LdapInvalidAttributeValueException
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atCN );

        assertEquals( 0, attr1.add( ( String ) null ) );

        try
        {
            attr1.getString();
            fail();
        }
        catch ( LdapInvalidAttributeValueException liave )
        {
            // expected
        }

        EntryAttribute attr2 = new DefaultEntryAttribute( atCN );

        attr2.add( "a", "b" );
        assertEquals( "a", attr2.getString() );

        EntryAttribute attr3 = new DefaultEntryAttribute( atPwd );

        attr3.add( BYTES1, BYTES2 );

        try
        {
            attr3.getString();
            fail();
        }
        catch ( LdapInvalidAttributeValueException ivae )
        {
            assertTrue( true );
        }
    }


    /**
     * Test method getUpId
     */
    @Test
    public void testGetUpId()
    {
        EntryAttribute attr = new DefaultEntryAttribute( atCN );

        assertNotNull( attr.getUpId() );
        assertEquals( "cn", attr.getUpId() );

        attr.setUpId( "CN" );
        assertEquals( "CN", attr.getUpId() );

        attr.setUpId( "  Cn  " );
        assertEquals( "  Cn  ", attr.getUpId() );

        attr.setUpId( "  2.5.4.3  " );
        assertEquals( "  2.5.4.3  ", attr.getUpId() );
    }


    /**
     * Test method hashCode()
     */
    @Test
    public void testHashCode()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atCN );
        EntryAttribute attr2 = new DefaultEntryAttribute( atSN );
        assertNotSame( attr1.hashCode(), attr2.hashCode() );

        attr2.setAttributeType( atCN );
        assertEquals( attr1.hashCode(), attr2.hashCode() );

        attr1.add( ( String ) null );
        assertNotSame( attr1.hashCode(), attr2.hashCode() );

        attr1.clear();
        assertEquals( attr1.hashCode(), attr2.hashCode() );

        attr1.add( "a", "b" );
        assertNotSame( attr1.hashCode(), attr2.hashCode() );

        attr2.add( "a", "b" );
        assertEquals( attr1.hashCode(), attr2.hashCode() );

        // Order matters
        attr2.clear();
        attr2.add( "b", "a" );
        assertNotSame( attr1.hashCode(), attr2.hashCode() );

        EntryAttribute attr3 = new DefaultEntryAttribute( atPwd );
        EntryAttribute attr4 = new DefaultEntryAttribute( atPwd );
        assertNotSame( attr3.hashCode(), attr4.hashCode() );

        attr3.add( ( byte[] ) null );
        assertNotSame( attr3.hashCode(), attr4.hashCode() );

        attr3.clear();
        assertEquals( attr3.hashCode(), attr4.hashCode() );

        attr3.add( new byte[]
            { 0x01, 0x02 }, new byte[]
            { 0x03, 0x04 } );
        assertNotSame( attr1.hashCode(), attr2.hashCode() );

        attr4.add( new byte[]
            { 0x01, 0x02 }, new byte[]
            { 0x03, 0x04 } );
        assertNotSame( attr1.hashCode(), attr2.hashCode() );

        // Order matters
        attr4.clear();
        attr4.add( new byte[]
            { 0x03, 0x04 }, new byte[]
            { 0x01, 0x02 } );
        assertNotSame( attr1.hashCode(), attr2.hashCode() );
    }


    /**
     * Test method SetId(String)
     */
    @Test
    public void testSetId()
    {
        EntryAttribute attr = new DefaultEntryAttribute( atCN );

        attr.setId( "Cn" );
        assertEquals( "cn", attr.getId() );

        attr.setId( " CN " );
        assertEquals( "cn", attr.getId() );

        attr.setId( " 2.5.4.3 " );
        assertEquals( "2.5.4.3", attr.getId() );

        attr.setId( " commonName " );
        assertEquals( "commonname", attr.getId() );

        try
        {
            attr.setId( null );
            fail();
        }
        catch ( IllegalArgumentException iae )
        {
            assertTrue( true );
        }

        try
        {
            attr.setId( "" );
            fail();
        }
        catch ( IllegalArgumentException iae )
        {
            assertTrue( true );
        }

        try
        {
            attr.setId( "  " );
            fail();
        }
        catch ( IllegalArgumentException iae )
        {
            assertTrue( true );
        }

        try
        {
            attr.setId( " SN " );
            fail();
        }
        catch ( IllegalArgumentException iae )
        {
            assertTrue( true );
        }
    }


    /**
     * Test method isValid()
     */
    @Test
    public void testIsValid() throws Exception
    {
        EntryAttribute attr = new DefaultEntryAttribute( atCN );

        // No value, this should not be valid
        assertFalse( attr.isValid() );

        attr.add( "test", "test2", "A123\\;" );
        assertTrue( attr.isValid() );

        // If we try to add a wrong value, it will not be added. The
        // attribute remains valid.
        assertEquals( 0, attr.add( new byte[]
            { 0x01 } ) );
        assertTrue( attr.isValid() );

        // test a SINGLE-VALUE attribute. CountryName is SINGLE-VALUE
        attr.clear();
        attr.setAttributeType( atC );
        attr.add( "FR" );
        assertTrue( attr.isValid() );
        attr.add( "US" );
        assertFalse( attr.isValid() );
    }


    /**
     * Test method add( Value... )
     */
    @Test
    public void testAddValueArray()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atCN );

        int nbAdded = attr1.add( new StringValue( atCN, null ) );
        assertEquals( 1, nbAdded );
        assertTrue( attr1.isHR() );
        assertEquals( NULL_STRING_VALUE, attr1.get() );

        EntryAttribute attr2 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr2.add( new BinaryValue( atPwd, null ) );
        assertEquals( 1, nbAdded );
        assertFalse( attr2.isHR() );
        assertEquals( NULL_BINARY_VALUE, attr2.get() );

        EntryAttribute attr3 = new DefaultEntryAttribute( atCN );

        nbAdded = attr3.add( new StringValue( atCN, "a" ), new StringValue( atCN, "b" ) );
        assertEquals( 2, nbAdded );
        assertTrue( attr3.isHR() );
        assertTrue( attr3.contains( "a" ) );
        assertTrue( attr3.contains( "b" ) );

        EntryAttribute attr4 = new DefaultEntryAttribute( atCN );

        nbAdded = attr4.add( new BinaryValue( atPwd, BYTES1 ), new BinaryValue( atPwd, BYTES2 ) );
        assertEquals( 0, nbAdded );
        assertTrue( attr4.isHR() );
        assertFalse( attr4.contains( BYTES1 ) );
        assertFalse( attr4.contains( BYTES2 ) );

        EntryAttribute attr5 = new DefaultEntryAttribute( atCN );

        nbAdded = attr5.add( new StringValue( atCN, "c" ), new BinaryValue( atPwd, BYTES1 ) );
        assertEquals( 1, nbAdded );
        assertTrue( attr5.isHR() );
        assertFalse( attr5.contains( "ab" ) );
        assertTrue( attr5.contains( "c" ) );

        EntryAttribute attr6 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr6.add( new BinaryValue( atPwd, BYTES1 ), new StringValue( atCN, "c" ) );
        assertEquals( 1, nbAdded );
        assertFalse( attr6.isHR() );
        assertTrue( attr6.contains( BYTES1 ) );
        assertFalse( attr6.contains( BYTES3 ) );

        EntryAttribute attr7 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr7.add( new BinaryValue( atPwd, null ), new StringValue( atCN, "c" ) );
        assertEquals( 1, nbAdded );
        assertFalse( attr7.isHR() );
        assertTrue( attr7.contains( NULL_BINARY_VALUE ) );
        assertFalse( attr7.contains( BYTES3 ) );

        EntryAttribute attr8 = new DefaultEntryAttribute( atDC );

        nbAdded = attr8.add( new StringValue( atDC, null ), new BinaryValue( atPwd, BYTES1 ) );
        assertEquals( 1, nbAdded );
        assertTrue( attr8.isHR() );
        assertTrue( attr8.contains( NULL_STRING_VALUE ) );
        assertFalse( attr8.contains( "ab" ) );

        EntryAttribute attr9 = new DefaultEntryAttribute( atDC );

        nbAdded = attr9.add( new StringValue( ( String ) null ), new StringValue( "ab" ) );
        assertEquals( 2, nbAdded );
        assertTrue( attr9.isHR() );
        assertTrue( attr9.contains( NULL_STRING_VALUE ) );
        assertTrue( attr9.contains( "ab" ) );

        EntryAttribute attr10 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr10.add( new BinaryValue( ( byte[] ) null ), new BinaryValue( BYTES1 ) );
        assertEquals( 2, nbAdded );
        assertFalse( attr10.isHR() );
        assertTrue( attr10.contains( NULL_BINARY_VALUE ) );
        assertTrue( attr10.contains( BYTES1 ) );
    }


    /**
     * Test method add( String... )
     */
    @Test
    public void testAddStringArray() throws LdapInvalidAttributeValueException
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atDC );

        int nbAdded = attr1.add( ( String ) null );
        assertEquals( 1, nbAdded );
        assertTrue( attr1.isHR() );
        assertEquals( NULL_STRING_VALUE, attr1.get() );

        EntryAttribute attr2 = new DefaultEntryAttribute( atDC );

        nbAdded = attr2.add( "" );
        assertEquals( 1, nbAdded );
        assertTrue( attr2.isHR() );
        assertEquals( "", attr2.getString() );

        EntryAttribute attr3 = new DefaultEntryAttribute( atCN );

        nbAdded = attr3.add( "t" );
        assertEquals( 1, nbAdded );
        assertTrue( attr3.isHR() );
        assertEquals( "t", attr3.getString() );

        EntryAttribute attr4 = new DefaultEntryAttribute( atCN );

        nbAdded = attr4.add( "a", "b", "c", "d" );
        assertEquals( 4, nbAdded );
        assertTrue( attr4.isHR() );
        assertEquals( "a", attr4.getString() );
        assertTrue( attr4.contains( "a" ) );
        assertTrue( attr4.contains( "b" ) );
        assertTrue( attr4.contains( "c" ) );
        assertTrue( attr4.contains( "d" ) );

        nbAdded = attr4.add( "e" );
        assertEquals( 1, nbAdded );
        assertTrue( attr4.isHR() );
        assertEquals( "a", attr4.getString() );
        assertTrue( attr4.contains( "a" ) );
        assertTrue( attr4.contains( "b" ) );
        assertTrue( attr4.contains( "c" ) );
        assertTrue( attr4.contains( "d" ) );
        assertTrue( attr4.contains( "e" ) );

        nbAdded = attr4.add( BYTES1 );
        assertEquals( 0, nbAdded );
        assertTrue( attr4.isHR() );
        assertEquals( "a", attr4.getString() );
        assertTrue( attr4.contains( "a" ) );
        assertTrue( attr4.contains( "b" ) );
        assertTrue( attr4.contains( "c" ) );
        assertTrue( attr4.contains( "d" ) );
        assertTrue( attr4.contains( "e" ) );
        assertFalse( attr4.contains( "ab" ) );

        EntryAttribute attr5 = new DefaultEntryAttribute( atDC );

        nbAdded = attr5.add( "a", "b", ( String ) null, "d" );
        assertEquals( 4, nbAdded );
        assertTrue( attr5.isHR() );
        assertTrue( attr5.contains( "a" ) );
        assertTrue( attr5.contains( "b" ) );
        assertTrue( attr5.contains( NULL_STRING_VALUE ) );
        assertTrue( attr5.contains( "d" ) );

        EntryAttribute attr6 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr6.add( "a", ( String ) null );
        assertEquals( 2, nbAdded );
        assertFalse( attr6.isHR() );
    }


    /**
     * Test method add( byte[]... )
     */
    @Test
    public void testAddByteArray() throws LdapInvalidAttributeValueException
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atPwd );

        int nbAdded = attr1.add( ( byte[] ) null );
        assertEquals( 1, nbAdded );
        assertFalse( attr1.isHR() );
        assertTrue( Arrays.equals( NULL_BINARY_VALUE.getBytes(), attr1.getBytes() ) );

        EntryAttribute attr2 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr2.add( StringConstants.EMPTY_BYTES );
        assertEquals( 1, nbAdded );
        assertFalse( attr2.isHR() );
        assertTrue( Arrays.equals( StringConstants.EMPTY_BYTES, attr2.getBytes() ) );

        EntryAttribute attr3 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr3.add( BYTES1 );
        assertEquals( 1, nbAdded );
        assertFalse( attr3.isHR() );
        assertTrue( Arrays.equals( BYTES1, attr3.getBytes() ) );

        EntryAttribute attr4 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr4.add( BYTES1, BYTES2, BYTES3, BYTES4 );
        assertEquals( 4, nbAdded );
        assertFalse( attr4.isHR() );
        assertTrue( attr4.contains( BYTES1 ) );
        assertTrue( attr4.contains( BYTES2 ) );
        assertTrue( attr4.contains( BYTES3 ) );
        assertTrue( attr4.contains( BYTES4 ) );

        EntryAttribute attr5 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr5.add( BYTES1, BYTES2, ( byte[] ) null, BYTES3 );
        assertEquals( 4, nbAdded );
        assertFalse( attr5.isHR() );
        assertTrue( attr5.contains( BYTES1 ) );
        assertTrue( attr5.contains( BYTES2 ) );
        assertTrue( attr5.contains( ( byte[] ) null ) );
        assertTrue( attr5.contains( BYTES3 ) );

        EntryAttribute attr6 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr6.add( "ab", ( String ) null );
        assertEquals( 2, nbAdded );
        assertFalse( attr6.isHR() );
    }


    /**
     * Test method clear()
     */
    @Test
    public void testClear()
    {
        EntryAttribute attr = new DefaultEntryAttribute( "dc", atDC );

        assertEquals( 0, attr.size() );

        attr.add( ( String ) null, "a", "b" );
        assertEquals( 3, attr.size() );

        attr.clear();
        assertTrue( attr.isHR() );
        assertEquals( 0, attr.size() );
        assertEquals( atDC, attr.getAttributeType() );
    }


    /**
     * Test method contains( Value... )
     */
    @Test
    public void testContainsValueArray()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atDC );

        assertEquals( 0, attr1.size() );
        assertFalse( attr1.contains( STR_VALUE1 ) );
        assertFalse( attr1.contains( NULL_STRING_VALUE ) );

        attr1.add( ( String ) null );
        assertEquals( 1, attr1.size() );
        assertTrue( attr1.contains( NULL_STRING_VALUE ) );

        attr1.remove( ( String ) null );
        assertFalse( attr1.contains( NULL_STRING_VALUE ) );
        assertEquals( 0, attr1.size() );

        attr1.add( "a", "b", "c" );
        assertEquals( 3, attr1.size() );
        assertTrue( attr1.contains( STR_VALUE1 ) );
        assertTrue( attr1.contains( STR_VALUE2 ) );
        assertTrue( attr1.contains( STR_VALUE3 ) );
        assertTrue( attr1.contains( STR_VALUE1, STR_VALUE3 ) );
        assertFalse( attr1.contains( STR_VALUE4 ) );
        assertFalse( attr1.contains( NULL_STRING_VALUE ) );

        EntryAttribute attr2 = new DefaultEntryAttribute( atPwd );
        assertEquals( 0, attr2.size() );
        assertFalse( attr2.contains( BYTES1 ) );
        assertFalse( attr2.contains( NULL_BINARY_VALUE ) );

        attr2.add( ( byte[] ) null );
        assertEquals( 1, attr2.size() );
        assertTrue( attr2.contains( NULL_BINARY_VALUE ) );

        attr2.remove( ( byte[] ) null );
        assertFalse( attr2.contains( NULL_BINARY_VALUE ) );
        assertEquals( 0, attr2.size() );

        attr2.add( BYTES1, BYTES2, BYTES3 );
        assertEquals( 3, attr2.size() );
        assertTrue( attr2.contains( BIN_VALUE1 ) );
        assertTrue( attr2.contains( BIN_VALUE2 ) );
        assertTrue( attr2.contains( BIN_VALUE3 ) );
        assertFalse( attr2.contains( NULL_BINARY_VALUE ) );
    }


    /**
     * Test method contains( String... )
     */
    @Test
    public void testContainsStringArray()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atDC );

        assertEquals( 0, attr1.size() );
        assertFalse( attr1.contains( "a" ) );
        assertFalse( attr1.contains( ( String ) null ) );

        attr1.add( ( String ) null );
        assertEquals( 1, attr1.size() );
        assertTrue( attr1.contains( ( String ) null ) );

        attr1.remove( ( String ) null );
        assertFalse( attr1.contains( ( String ) null ) );
        assertEquals( 0, attr1.size() );

        attr1.add( "a", "b", "c" );
        assertEquals( 3, attr1.size() );
        assertTrue( attr1.contains( "a" ) );
        assertTrue( attr1.contains( "b" ) );
        assertTrue( attr1.contains( "c" ) );
        assertFalse( attr1.contains( "e" ) );
        assertFalse( attr1.contains( ( String ) null ) );
    }


    /**
     * Test method contains( byte[]... )
     */
    @Test
    public void testContainsByteArray()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atPwd );

        assertEquals( 0, attr1.size() );
        assertFalse( attr1.contains( BYTES1 ) );
        assertFalse( attr1.contains( ( byte[] ) null ) );

        attr1.add( ( byte[] ) null );
        assertEquals( 1, attr1.size() );
        assertTrue( attr1.contains( ( byte[] ) null ) );

        attr1.remove( ( byte[] ) null );
        assertFalse( attr1.contains( ( byte[] ) null ) );
        assertEquals( 0, attr1.size() );

        attr1.add( BYTES1, BYTES2, BYTES3 );
        assertEquals( 3, attr1.size() );
        assertTrue( attr1.contains( BYTES1 ) );
        assertTrue( attr1.contains( BYTES2 ) );
        assertTrue( attr1.contains( BYTES3 ) );
        assertFalse( attr1.contains( BYTES4 ) );
        assertFalse( attr1.contains( ( byte[] ) null ) );
    }


    /**
     * Test method testEquals()
     */
    @Test
    public void testEquals()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atCN );

        assertFalse( attr1.equals( null ) );

        EntryAttribute attr2 = new DefaultEntryAttribute( atCN );

        assertTrue( attr1.equals( attr2 ) );

        attr2.setId( "CN" );
        assertTrue( attr1.equals( attr2 ) );

        attr1.setId( "CommonName" );
        assertTrue( attr1.equals( attr2 ) );

        attr1.setUpId( "CN" );
        assertTrue( attr1.equals( attr2 ) );

        attr1.add( "a", "b", "c" );
        attr2.add( "c", "b", "a" );
        assertTrue( attr1.equals( attr2 ) );

        attr1.setHR( true );
        attr2.setHR( false );
        assertTrue( attr1.equals( attr2 ) );

        EntryAttribute attr3 = new DefaultEntryAttribute( atPwd );
        EntryAttribute attr4 = new DefaultEntryAttribute( atPwd );

        attr3.add( NULL_BINARY_VALUE );
        attr4.add( NULL_BINARY_VALUE );
        assertTrue( attr3.equals( attr4 ) );

        EntryAttribute attr5 = new DefaultEntryAttribute( atPwd );
        EntryAttribute attr6 = new DefaultEntryAttribute( atCN );
        assertFalse( attr5.equals( attr6 ) );

        attr5.add( NULL_BINARY_VALUE );
        attr6.add( NULL_STRING_VALUE );
        assertFalse( attr5.equals( attr6 ) );

        EntryAttribute attr7 = new DefaultEntryAttribute( atCN );
        EntryAttribute attr8 = new DefaultEntryAttribute( atPwd );

        attr7.add( "a" );
        attr8.add( BYTES2 );
        assertFalse( attr7.equals( attr8 ) );

        EntryAttribute attr9 = new DefaultEntryAttribute( atCN );
        EntryAttribute attr10 = new DefaultEntryAttribute( atPwd );

        attr9.add( "a" );
        attr9.add( BYTES2 );
        attr10.add( "a", "b" );
        assertFalse( attr9.equals( attr10 ) );
    }


    /**
     * Test method get()
     */
    @Test
    public void testGet()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( "dc", atDC );

        attr1.add( ( String ) null );
        assertEquals( NULL_STRING_VALUE, attr1.get() );

        EntryAttribute attr2 = new DefaultEntryAttribute( "dc", atDC );

        attr2.add( "a", "b", "c" );
        assertEquals( "a", attr2.get().getString() );

        attr2.remove( "a" );
        assertEquals( "b", attr2.get().getString() );

        attr2.remove( "b" );
        assertEquals( "c", attr2.get().getString() );

        attr2.remove( "c" );
        assertNull( attr2.get() );

        EntryAttribute attr3 = new DefaultEntryAttribute( "userPassword", atPwd );

        attr3.add( BYTES1, BYTES2, BYTES3 );
        assertTrue( Arrays.equals( BYTES1, attr3.get().getBytes() ) );

        attr3.remove( BYTES1 );
        assertTrue( Arrays.equals( BYTES2, attr3.get().getBytes() ) );

        attr3.remove( BYTES2 );
        assertTrue( Arrays.equals( BYTES3, attr3.get().getBytes() ) );

        attr3.remove( BYTES3 );
        assertNull( attr2.get() );
    }


    /**
     * Test method getAll()
     */
    @Test
    public void testGetAll()
    {
        EntryAttribute attr = new DefaultEntryAttribute( atCN );

        Iterator<Value<?>> iterator = attr.getAll();
        assertFalse( iterator.hasNext() );

        attr.add( NULL_STRING_VALUE );
        iterator = attr.getAll();
        assertTrue( iterator.hasNext() );

        Value<?> value = iterator.next();
        assertEquals( NULL_STRING_VALUE, value );

        attr.clear();
        iterator = attr.getAll();
        assertFalse( iterator.hasNext() );

        attr.add( "a", "b", "c" );
        iterator = attr.getAll();
        assertTrue( iterator.hasNext() );
        assertEquals( "a", iterator.next().getString() );
        assertEquals( "b", iterator.next().getString() );
        assertEquals( "c", iterator.next().getString() );
        assertFalse( iterator.hasNext() );
    }


    /**
     * Test method size()
     */
    @Test
    public void testSize() throws Exception
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atDC );

        assertEquals( 0, attr1.size() );

        attr1.add( ( String ) null );
        assertEquals( 1, attr1.size() );

        EntryAttribute attr2 = new DefaultEntryAttribute( atCN );

        attr2.add( "a", "b" );
        assertEquals( 2, attr2.size() );

        attr2.clear();
        assertEquals( 0, attr2.size() );

        EntryAttribute attr3 = new DefaultEntryAttribute( atC );

        attr3.add( "US" );
        assertEquals( 1, attr3.size() );

        // TODO : forbid addition of more than 1 value for SINGLE-VALUE attributes
        attr3.add( "FR" );
        assertEquals( 2, attr3.size() );
    }


    /**
     * Test method put( byte[]... )
     */
    @Test
    public void testPutByteArray() throws InvalidAttributeValueException, Exception
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atPwd );

        int nbAdded = attr1.add( ( byte[] ) null );
        assertEquals( 1, nbAdded );
        assertFalse( attr1.isHR() );
        assertTrue( Arrays.equals( NULL_BINARY_VALUE.getBytes(), attr1.getBytes() ) );

        EntryAttribute attr2 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr2.add( StringConstants.EMPTY_BYTES );
        assertEquals( 1, nbAdded );
        assertFalse( attr2.isHR() );
        assertTrue( Arrays.equals( StringConstants.EMPTY_BYTES, attr2.getBytes() ) );

        EntryAttribute attr3 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr3.add( BYTES1 );
        assertEquals( 1, nbAdded );
        assertFalse( attr3.isHR() );
        assertTrue( Arrays.equals( BYTES1, attr3.getBytes() ) );

        EntryAttribute attr4 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr4.add( BYTES1, BYTES2 );
        assertEquals( 2, nbAdded );
        assertFalse( attr4.isHR() );
        assertTrue( attr4.contains( BYTES1 ) );
        assertTrue( attr4.contains( BYTES2 ) );

        attr4.clear();
        nbAdded = attr4.add( BYTES3, BYTES4 );
        assertEquals( 2, nbAdded );
        assertFalse( attr4.isHR() );
        assertTrue( attr4.contains( BYTES3 ) );
        assertTrue( attr4.contains( BYTES4 ) );

        EntryAttribute attr5 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr5.add( BYTES1, BYTES2, ( byte[] ) null, BYTES3 );
        assertEquals( 4, nbAdded );
        assertFalse( attr5.isHR() );
        assertTrue( attr5.contains( BYTES1 ) );
        assertTrue( attr5.contains( BYTES2 ) );
        assertTrue( attr5.contains( ( byte[] ) null ) );
        assertTrue( attr5.contains( BYTES3 ) );

        EntryAttribute attr6 = new DefaultEntryAttribute( atPwd );

        attr6.setHR( true );
        assertFalse( attr6.isHR() );
        nbAdded = attr6.add( BYTES1, ( byte[] ) null );
        assertEquals( 2, nbAdded );
        assertTrue( attr6.contains( BYTES1 ) );
        assertTrue( attr6.contains( ( byte[] ) null ) );
    }


    /**
     * Test method put( String... )
     */
    @Test
    public void testPutStringArray() throws LdapInvalidAttributeValueException
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atDC );

        int nbAdded = attr1.add( ( String ) null );
        assertEquals( 1, nbAdded );
        assertTrue( attr1.isHR() );
        assertEquals( NULL_STRING_VALUE, attr1.get() );

        EntryAttribute attr2 = new DefaultEntryAttribute( atDC );

        nbAdded = attr2.add( "" );
        assertEquals( 1, nbAdded );
        assertTrue( attr2.isHR() );
        assertEquals( "", attr2.getString() );

        EntryAttribute attr3 = new DefaultEntryAttribute( atDC );

        nbAdded = attr3.add( "t" );
        assertEquals( 1, nbAdded );
        assertTrue( attr3.isHR() );
        assertEquals( "t", attr3.getString() );

        EntryAttribute attr4 = new DefaultEntryAttribute( atDC );

        nbAdded = attr4.add( "a", "b", "c", "d" );
        assertEquals( 4, nbAdded );
        assertTrue( attr4.isHR() );
        assertEquals( "a", attr4.getString() );
        assertTrue( attr4.contains( "a" ) );
        assertTrue( attr4.contains( "b" ) );
        assertTrue( attr4.contains( "c" ) );
        assertTrue( attr4.contains( "d" ) );

        attr4.clear();
        nbAdded = attr4.add( "e" );
        assertEquals( 1, nbAdded );
        assertTrue( attr4.isHR() );
        assertEquals( "e", attr4.getString() );
        assertFalse( attr4.contains( "a" ) );
        assertFalse( attr4.contains( "b" ) );
        assertFalse( attr4.contains( "c" ) );
        assertFalse( attr4.contains( "d" ) );
        assertTrue( attr4.contains( "e" ) );

        attr4.clear();
        nbAdded = attr4.add( BYTES1 );
        assertEquals( 0, nbAdded );
        assertTrue( attr4.isHR() );

        EntryAttribute attr5 = new DefaultEntryAttribute( atDC );

        nbAdded = attr5.add( "a", "b", ( String ) null, "d" );
        assertEquals( 4, nbAdded );
        assertTrue( attr5.isHR() );
        assertTrue( attr5.contains( "a" ) );
        assertTrue( attr5.contains( "b" ) );
        assertTrue( attr5.contains( NULL_STRING_VALUE ) );
        assertTrue( attr5.contains( "d" ) );

        EntryAttribute attr6 = new DefaultEntryAttribute( atPwd );

        nbAdded = attr6.add( "a", ( String ) null );
        assertEquals( 2, nbAdded );
        assertFalse( attr6.isHR() );
    }


    /**
     * Test method put( Value... )
     */
    @Test
    public void testPutValueArray() throws Exception
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atDC );

        assertEquals( 0, attr1.size() );

        attr1.add( NULL_STRING_VALUE );
        assertEquals( 1, attr1.size() );
        assertTrue( attr1.contains( NULL_STRING_VALUE ) );

        attr1.clear();
        attr1.add( STR_VALUE1, STR_VALUE2, STR_VALUE3 );
        assertEquals( 3, attr1.size() );
        assertTrue( attr1.contains( STR_VALUE1 ) );
        assertTrue( attr1.contains( STR_VALUE2 ) );
        assertTrue( attr1.contains( STR_VALUE3 ) );

        attr1.clear();
        attr1.add( STR_VALUE1, NULL_STRING_VALUE, STR_VALUE3 );
        assertEquals( 3, attr1.size() );
        assertTrue( attr1.contains( STR_VALUE1 ) );
        assertTrue( attr1.contains( NULL_STRING_VALUE ) );
        assertTrue( attr1.contains( STR_VALUE3 ) );

        attr1.clear();
        attr1.add( STR_VALUE1, NULL_STRING_VALUE, BIN_VALUE3 );
        assertEquals( 2, attr1.size() );
        assertTrue( attr1.contains( STR_VALUE1 ) );
        assertTrue( attr1.contains( NULL_STRING_VALUE ) );
        assertFalse( attr1.contains( STR_VALUE3 ) );

        EntryAttribute attr2 = new DefaultEntryAttribute( atPwd );
        assertEquals( 0, attr2.size() );

        attr2.add( NULL_BINARY_VALUE );
        assertEquals( 1, attr2.size() );
        assertTrue( attr2.contains( NULL_BINARY_VALUE ) );

        attr2.clear();
        attr2.add( BIN_VALUE1, BIN_VALUE2, BIN_VALUE3 );
        assertEquals( 3, attr2.size() );
        assertTrue( attr2.contains( BIN_VALUE1 ) );
        assertTrue( attr2.contains( BIN_VALUE2 ) );
        assertTrue( attr2.contains( BIN_VALUE3 ) );

        attr2.clear();
        attr2.add( BIN_VALUE1, NULL_BINARY_VALUE, STR_VALUE3 );
        assertEquals( 2, attr2.size() );
        assertTrue( attr2.contains( BIN_VALUE1 ) );
        assertTrue( attr2.contains( NULL_BINARY_VALUE ) );
        assertFalse( attr2.contains( BIN_VALUE3 ) );
    }


    /**
     * Test method remove( Value... )
     */
    @Test
    public void testRemoveValueArray() throws Exception
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atDC );

        assertFalse( attr1.remove( STR_VALUE1 ) );

        attr1.setHR( true );
        assertFalse( attr1.remove( STR_VALUE1 ) );

        attr1.add( "a", "b", "c" );
        assertTrue( attr1.remove( STR_VALUE1 ) );
        assertEquals( 2, attr1.size() );

        assertTrue( attr1.remove( STR_VALUE2, STR_VALUE3 ) );
        assertEquals( 0, attr1.size() );

        assertFalse( attr1.remove( STR_VALUE4 ) );

        attr1.clear();
        attr1.add( "a", "b", "c" );
        assertFalse( attr1.remove( STR_VALUE2, STR_VALUE4 ) );
        assertEquals( 2, attr1.size() );

        attr1.clear();
        attr1.add( "a", ( String ) null, "b" );
        assertTrue( attr1.remove( NULL_STRING_VALUE, STR_VALUE1 ) );
        assertEquals( 1, attr1.size() );

        attr1.clear();
        attr1.add( "a", ( String ) null, "b" );
        attr1.add( BYTES3 );
        assertFalse( attr1.remove( NULL_STRING_VALUE, STR_VALUE1, BIN_VALUE3 ) );
        assertEquals( 1, attr1.size() );

        EntryAttribute attr2 = new DefaultEntryAttribute( atPwd );

        assertFalse( attr2.remove( BIN_VALUE1 ) );

        attr2.setHR( true );
        assertFalse( attr2.remove( BIN_VALUE1 ) );

        attr2.add( BYTES1, BYTES2, BYTES3 );
        assertTrue( attr2.remove( BIN_VALUE1 ) );
        assertEquals( 2, attr2.size() );

        assertTrue( attr2.remove( BIN_VALUE2, BIN_VALUE3 ) );
        assertEquals( 0, attr2.size() );

        assertFalse( attr2.remove( BIN_VALUE4 ) );

        attr2.clear();
        attr2.add( BYTES1, BYTES2, BYTES3 );
        assertFalse( attr2.remove( BIN_VALUE2, STR_VALUE4 ) );
        assertEquals( 2, attr2.size() );

        attr2.clear();
        attr2.add( BYTES1, ( byte[] ) null, BYTES3 );
        assertFalse( attr2.remove( NULL_STRING_VALUE, BIN_VALUE1 ) );
        assertEquals( 2, attr2.size() );

        attr2.clear();
        attr2.add( BYTES1, ( byte[] ) null, BYTES2 );
        attr2.add( "c" );
        assertEquals( 4, attr2.size() );
        assertFalse( attr2.remove( NULL_STRING_VALUE, BIN_VALUE1, STR_VALUE3 ) );
        assertEquals( 3, attr2.size() );
    }


    /**
     * Test method remove( byte... )
     */
    @Test
    public void testRemoveByteArray() throws Exception
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atPwd );

        assertFalse( attr1.remove( BYTES1 ) );

        attr1.add( BYTES1, BYTES2, BYTES3 );
        assertTrue( attr1.remove( BYTES1 ) );
        assertEquals( 2, attr1.size() );

        assertTrue( attr1.remove( BYTES2, BYTES3 ) );
        assertEquals( 0, attr1.size() );

        assertFalse( attr1.remove( BYTES4 ) );

        attr1.clear();
        attr1.add( BYTES1, BYTES2, BYTES3 );
        assertFalse( attr1.remove( BYTES3, BYTES4 ) );
        assertEquals( 2, attr1.size() );

        attr1.clear();
        attr1.add( BYTES1, ( byte[] ) null, BYTES2 );
        assertTrue( attr1.remove( ( byte[] ) null, BYTES1 ) );
        assertEquals( 1, attr1.size() );
    }


    /**
     * Test method remove( String... )
     */
    @Test
    public void testRemoveStringArray() throws Exception
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atDC );

        assertFalse( attr1.remove( "a" ) );

        attr1.setHR( true );
        assertFalse( attr1.remove( "a" ) );

        attr1.add( "a", "b", "c" );
        assertTrue( attr1.remove( "a" ) );
        assertEquals( 2, attr1.size() );

        assertTrue( attr1.remove( "b", "c" ) );
        assertEquals( 0, attr1.size() );

        assertFalse( attr1.remove( "d" ) );

        attr1.clear();
        attr1.add( "a", "b", "c" );
        assertFalse( attr1.remove( "b", "e" ) );
        assertEquals( 2, attr1.size() );

        attr1.clear();
        attr1.add( "a", ( String ) null, "b" );
        assertTrue( attr1.remove( ( String ) null, "a" ) );
        assertEquals( 1, attr1.size() );

        EntryAttribute attr2 = new DefaultEntryAttribute( "test" );

        attr2.add( BYTES1, BYTES2, BYTES3 );

        assertFalse( attr2.remove( ( String ) null ) );
        assertTrue( attr2.remove( "ab", "c" ) );
        assertFalse( attr2.remove( "d" ) );
    }


    /**
     * Test method iterator()
     */
    @Test
    public void testIterator()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atCN );
        attr1.add( "a", "b", "c" );

        Iterator<Value<?>> iter = attr1.iterator();

        assertTrue( iter.hasNext() );

        String[] values = new String[]
            { "a", "b", "c" };
        int pos = 0;

        for ( Value<?> val : attr1 )
        {
            assertTrue( val instanceof StringValue );
            assertEquals( values[pos++], val.getString() );
        }
    }


    /**
     * Test method toString
     */
    @Test
    public void testToString()
    {
        EntryAttribute attr = new DefaultEntryAttribute( atDC );

        assertEquals( "    dc: (null)\n", attr.toString() );

        attr.setUpId( "DomainComponent" );
        assertEquals( "    DomainComponent: (null)\n", attr.toString() );

        attr.add( ( String ) null );
        assertEquals( "    DomainComponent: ''\n", attr.toString() );

        attr.clear();
        attr.add( "a", "b" );
        assertEquals( "    DomainComponent: a\n    DomainComponent: b\n", attr.toString() );
    }


    /**
     * Test method instanceOf()
     */
    @Test
    public void testInstanceOf() throws Exception
    {
        EntryAttribute attr = new DefaultEntryAttribute( atCN );

        assertTrue( attr.instanceOf( "CommonName" ) );
        assertTrue( attr.instanceOf( "2.5.4.3" ) );
        assertTrue( attr.instanceOf( "  Cn  " ) );
        assertFalse( attr.instanceOf( "  " ) );
        assertFalse( attr.instanceOf( "sn" ) );
        assertFalse( attr.instanceOf( "name" ) );
    }


    /**
     * Test method setUpId( String, AttributeType )
     */
    @Test
    public void testSetUpIdStringAttributeType() throws Exception
    {
        EntryAttribute attr = new DefaultEntryAttribute( atSN );

        attr.setUpId( null, atCN );
        assertEquals( "cn", attr.getId() );
        assertEquals( "cn", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );

        attr.setUpId( "  ", atCN );
        assertEquals( "cn", attr.getId() );
        assertEquals( "cn", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );

        attr.setUpId( "  CN  ", atCN );
        assertEquals( "cn", attr.getId() );
        assertEquals( "  CN  ", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );

        attr.setUpId( "  CommonName  ", atCN );
        assertEquals( "commonname", attr.getId() );
        assertEquals( "  CommonName  ", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );

        attr.setUpId( "  2.5.4.3  ", atCN );
        assertEquals( "2.5.4.3", attr.getId() );
        assertEquals( "  2.5.4.3  ", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );

        // Check with wrong IDs
        try
        {
            attr.setUpId( "sn", atCN );
            fail();
        }
        catch ( IllegalArgumentException iae )
        {
            assertTrue( true );
        }

        try
        {
            attr.setUpId( "  2.5.4.4  ", atCN );
            fail();
        }
        catch ( IllegalArgumentException iae )
        {
            assertTrue( true );
        }
    }


    /**
     * Test method setUpId( String ) inherited from ClientAttribute
     */
    @Test
    public void testSetUpIdString() throws Exception
    {
        EntryAttribute attr = new DefaultEntryAttribute( atCN );

        attr.setUpId( "cn" );
        assertEquals( "cn", attr.getId() );
        assertEquals( "cn", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );

        attr.setUpId( "  CN  " );
        assertEquals( "cn", attr.getId() );
        assertEquals( "  CN  ", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );

        attr.setUpId( "  CommonName  " );
        assertEquals( "commonname", attr.getId() );
        assertEquals( "  CommonName  ", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );

        attr.setUpId( "  2.5.4.3  " );
        assertEquals( "  2.5.4.3  ", attr.getUpId() );
        assertEquals( "2.5.4.3", attr.getId() );
        assertEquals( atCN, attr.getAttributeType() );

        // Now check wrong IDs
        attr = new DefaultEntryAttribute( atCN );
        attr.setUpId( "sn" );
        assertEquals( "cn", attr.getId() );
        assertEquals( "cn", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );

        attr.setUpId( "  SN  " );
        assertEquals( "cn", attr.getId() );
        assertEquals( "cn", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );

        attr.setUpId( "  surname  " );
        assertEquals( "cn", attr.getId() );
        assertEquals( "cn", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );

        attr.setUpId( "  2.5.4.4  " );
        assertEquals( "cn", attr.getId() );
        assertEquals( "cn", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );
    }


    /**
     * Test method setAttributeType( AttributeType )
     */
    @Test
    public void testSetAttributeType() throws Exception
    {
        EntryAttribute attr = new DefaultEntryAttribute( atCN );

        try
        {
            attr.setAttributeType( null );
            fail();
        }
        catch ( IllegalArgumentException iae )
        {
            assertTrue( true );
        }

        attr.setAttributeType( atSN );

        assertTrue( attr.instanceOf( "Surname" ) );
        assertEquals( "sn", attr.getId() );
        assertEquals( "sn", attr.getUpId() );
    }


    /**
     * Test method getAttributeType()
     */
    @Test
    public void testGetAttributeType() throws Exception
    {
        EntryAttribute attr = new DefaultEntryAttribute( atSN );
        assertEquals( atSN, attr.getAttributeType() );
    }


    /**
     * Test constructor DefaultEntryAttribute( AttributeType )
     */
    @Test
    public void testDefaultServerAttributeAttributeType()
    {
        EntryAttribute attr = new DefaultEntryAttribute( atCN );

        assertTrue( attr.isHR() );
        assertEquals( 0, attr.size() );
        assertEquals( "cn", attr.getId() );
        assertEquals( "cn", attr.getUpId() );
        assertEquals( atCN, attr.getAttributeType() );
    }


    /**
     * Test constructor DefaultEntryAttribute( String, AttributeType )
     */
    @Test
    public void testDefaultServerAttributeStringAttributeType()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( "cn", atCN );

        assertTrue( attr1.isHR() );
        assertEquals( 0, attr1.size() );
        assertEquals( "cn", attr1.getId() );
        assertEquals( "cn", attr1.getUpId() );
        assertEquals( atCN, attr1.getAttributeType() );

        EntryAttribute attr2 = new DefaultEntryAttribute( "  CommonName  ", atCN );

        assertTrue( attr2.isHR() );
        assertEquals( 0, attr2.size() );
        assertEquals( "commonname", attr2.getId() );
        assertEquals( "  CommonName  ", attr2.getUpId() );
        assertEquals( atCN, attr2.getAttributeType() );

        EntryAttribute attr3 = new DefaultEntryAttribute( "  ", atCN );

        assertTrue( attr3.isHR() );
        assertEquals( 0, attr3.size() );
        assertEquals( "cn", attr3.getId() );
        assertEquals( "cn", attr3.getUpId() );
        assertEquals( atCN, attr3.getAttributeType() );
    }


    /**
     * Test constructor DefaultEntryAttribute( AttributeType, Value... )
     */
    @Test
    public void testDefaultServerAttributeAttributeTypeValueArray() throws Exception
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atDC, STR_VALUE1, STR_VALUE2, NULL_STRING_VALUE );

        assertTrue( attr1.isHR() );
        assertEquals( 3, attr1.size() );
        assertEquals( "dc", attr1.getId() );
        assertEquals( "dc", attr1.getUpId() );
        assertEquals( atDC, attr1.getAttributeType() );
        assertTrue( attr1.contains( "a", "b" ) );
        assertTrue( attr1.contains( NULL_STRING_VALUE ) );

        EntryAttribute attr2 = new DefaultEntryAttribute( atDC, STR_VALUE1, BIN_VALUE2, NULL_STRING_VALUE );

        assertTrue( attr2.isHR() );
        assertEquals( 2, attr2.size() );
        assertEquals( "dc", attr2.getId() );
        assertEquals( "dc", attr2.getUpId() );
        assertEquals( atDC, attr2.getAttributeType() );
        assertTrue( attr2.contains( "a" ) );
        assertTrue( attr2.contains( NULL_STRING_VALUE ) );
    }


    /**
     * Test constructor DefaultEntryAttribute( String, AttributeType, Value... )
     */
    @Test
    public void testDefaultServerAttributeStringAttributeTypeValueArray()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( "dc", atDC, STR_VALUE1, STR_VALUE2, NULL_STRING_VALUE );

        assertTrue( attr1.isHR() );
        assertEquals( 3, attr1.size() );
        assertEquals( "dc", attr1.getId() );
        assertEquals( "dc", attr1.getUpId() );
        assertEquals( atDC, attr1.getAttributeType() );
        assertTrue( attr1.contains( "a", "b" ) );
        assertTrue( attr1.contains( NULL_STRING_VALUE ) );

        EntryAttribute attr2 = new DefaultEntryAttribute( atDC, STR_VALUE1, BIN_VALUE2, NULL_STRING_VALUE );

        assertTrue( attr2.isHR() );
        assertEquals( 2, attr2.size() );
        assertEquals( "dc", attr2.getId() );
        assertEquals( "dc", attr2.getUpId() );
        assertEquals( atDC, attr2.getAttributeType() );
        assertTrue( attr2.contains( "a" ) );
        assertTrue( attr2.contains( NULL_STRING_VALUE ) );

        EntryAttribute attr3 = new DefaultEntryAttribute( "DomainComponent", atDC, STR_VALUE1, STR_VALUE2,
            NULL_STRING_VALUE );

        assertTrue( attr3.isHR() );
        assertEquals( 3, attr3.size() );
        assertEquals( "domaincomponent", attr3.getId() );
        assertEquals( "DomainComponent", attr3.getUpId() );
        assertEquals( atDC, attr3.getAttributeType() );
        assertTrue( attr3.contains( "a", "b" ) );
        assertTrue( attr3.contains( NULL_STRING_VALUE ) );

        EntryAttribute attr4 = new DefaultEntryAttribute( " 0.9.2342.19200300.100.1.25 ", atDC, STR_VALUE1, STR_VALUE2,
            NULL_STRING_VALUE );

        assertTrue( attr4.isHR() );
        assertEquals( 3, attr4.size() );
        assertEquals( "0.9.2342.19200300.100.1.25", attr4.getId() );
        assertEquals( " 0.9.2342.19200300.100.1.25 ", attr4.getUpId() );
        assertEquals( atDC, attr4.getAttributeType() );
        assertTrue( attr4.contains( "a", "b" ) );
        assertTrue( attr4.contains( NULL_STRING_VALUE ) );
    }


    /**
     * Test constructor DefaultEntryAttribute( AttributeType, String... ) 
     */
    @Test
    public void testDefaultServerAttributeAttributeTypeStringArray()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atDC, "a", "b", ( String ) null );

        assertTrue( attr1.isHR() );
        assertEquals( 3, attr1.size() );
        assertEquals( "dc", attr1.getId() );
        assertEquals( "dc", attr1.getUpId() );
        assertEquals( atDC, attr1.getAttributeType() );
        assertTrue( attr1.contains( "a", "b" ) );
        assertTrue( attr1.contains( NULL_STRING_VALUE ) );

        EntryAttribute attr2 = new DefaultEntryAttribute( atDC, STR_VALUE1, BIN_VALUE2, NULL_STRING_VALUE );

        assertTrue( attr2.isHR() );
        assertEquals( 2, attr2.size() );
        assertEquals( "dc", attr2.getId() );
        assertEquals( "dc", attr2.getUpId() );
        assertEquals( atDC, attr2.getAttributeType() );
        assertTrue( attr2.contains( "a" ) );
        assertTrue( attr2.contains( NULL_STRING_VALUE ) );
    }


    /**
     * Test constructor DefaultEntryAttribute( String, AttributeType, String... )
     */
    @Test
    public void testDefaultServerAttributeStringAttributeTypeStringArray()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( "dc", atDC, "a", "b", ( String ) null );

        assertTrue( attr1.isHR() );
        assertEquals( 3, attr1.size() );
        assertEquals( "dc", attr1.getId() );
        assertEquals( "dc", attr1.getUpId() );
        assertEquals( atDC, attr1.getAttributeType() );
        assertTrue( attr1.contains( "a", "b" ) );
        assertTrue( attr1.contains( NULL_STRING_VALUE ) );

        EntryAttribute attr2 = new DefaultEntryAttribute( "DomainComponent", atDC, "a", "b", ( String ) null );

        assertTrue( attr2.isHR() );
        assertEquals( 3, attr2.size() );
        assertEquals( "domaincomponent", attr2.getId() );
        assertEquals( "DomainComponent", attr2.getUpId() );
        assertEquals( atDC, attr2.getAttributeType() );
        assertTrue( attr2.contains( "a", "b" ) );
        assertTrue( attr2.contains( NULL_STRING_VALUE ) );

        EntryAttribute attr3 = new DefaultEntryAttribute( " 0.9.2342.19200300.100.1.25 ", atDC, "a", "b",
            ( String ) null );

        assertTrue( attr3.isHR() );
        assertEquals( 3, attr3.size() );
        assertEquals( "0.9.2342.19200300.100.1.25", attr3.getId() );
        assertEquals( " 0.9.2342.19200300.100.1.25 ", attr3.getUpId() );
        assertEquals( atDC, attr3.getAttributeType() );
        assertTrue( attr3.contains( "a", "b" ) );
        assertTrue( attr3.contains( NULL_STRING_VALUE ) );
    }


    /**
     * Test method DefaultEntryAttribute( AttributeType, byte[]... ) 
     */
    @Test
    public void testDefaultServerAttributeAttributeTypeByteArray()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( atPwd, BYTES1, BYTES2, ( byte[] ) null );

        assertFalse( attr1.isHR() );
        assertEquals( 3, attr1.size() );
        assertEquals( "userPassword", attr1.getId() );
        assertEquals( "userPassword", attr1.getUpId() );
        assertEquals( atPwd, attr1.getAttributeType() );
        assertTrue( attr1.contains( BYTES1, BYTES2 ) );
        assertTrue( attr1.contains( NULL_BINARY_VALUE ) );

        EntryAttribute attr2 = new DefaultEntryAttribute( atPwd, STR_VALUE1, BIN_VALUE2, NULL_BINARY_VALUE );

        assertFalse( attr2.isHR() );
        assertEquals( 2, attr2.size() );
        assertEquals( "userPassword", attr2.getId() );
        assertEquals( "userPassword", attr2.getUpId() );
        assertEquals( atPwd, attr2.getAttributeType() );
        assertTrue( attr2.contains( BYTES2 ) );
        assertTrue( attr2.contains( NULL_BINARY_VALUE ) );
    }


    /**
     * Test method DefaultEntryAttribute( String, AttributeType, byte[]... )
     */
    @Test
    public void testDefaultServerAttributeStringAttributeTypeByteArray()
    {
        EntryAttribute attr1 = new DefaultEntryAttribute( "userPassword", atPwd, BYTES1, BYTES2, ( byte[] ) null );

        assertFalse( attr1.isHR() );
        assertEquals( 3, attr1.size() );
        assertEquals( "userpassword", attr1.getId() );
        assertEquals( "userPassword", attr1.getUpId() );
        assertEquals( atPwd, attr1.getAttributeType() );
        assertTrue( attr1.contains( BYTES1, BYTES2 ) );
        assertTrue( attr1.contains( NULL_BINARY_VALUE ) );

        EntryAttribute attr2 = new DefaultEntryAttribute( "2.5.4.35", atPwd, STR_VALUE1, BIN_VALUE2, NULL_BINARY_VALUE );

        assertFalse( attr2.isHR() );
        assertEquals( 2, attr2.size() );
        assertEquals( "2.5.4.35", attr2.getId() );
        assertEquals( "2.5.4.35", attr2.getUpId() );
        assertEquals( atPwd, attr2.getAttributeType() );
        assertTrue( attr2.contains( BYTES2 ) );
        assertTrue( attr2.contains( NULL_BINARY_VALUE ) );
    }


    /**
     * Test method testClone()
     */
    @Test
    public void testClone()
    {
        EntryAttribute attr = new DefaultEntryAttribute( atCN );

        EntryAttribute clone = attr.clone();

        assertEquals( attr, clone );
        attr.setUpId( "CommonName" );
        assertEquals( "cn", clone.getId() );

        attr.add( "a", ( String ) null, "b" );
        clone = attr.clone();
        assertEquals( attr, clone );

        attr.remove( "a" );
        assertNotSame( attr, clone );

        clone = attr.clone();
        assertEquals( attr, clone );
    }


    /**
     * Test the copy constructor of a EntryAttribute
     */
    @Test
    public void testCopyConstructorServerAttribute() throws LdapInvalidAttributeValueException
    {
        EntryAttribute attribute = new DefaultEntryAttribute( atCN );

        EntryAttribute copy = new DefaultEntryAttribute( atCN, attribute );

        assertEquals( copy, attribute );

        EntryAttribute attribute2 = new DefaultEntryAttribute( atCN, "test" );

        EntryAttribute copy2 = new DefaultEntryAttribute( atCN, attribute2 );

        assertEquals( copy2, attribute2 );
        attribute2.add( "test2" );
        assertNotSame( copy2, attribute2 );
        assertEquals( "test", copy2.getString() );
    }


    /**
     * Test the copy constructor of a ClientAttribute
     */
    @Test
    public void testCopyConstructorClientAttribute() throws LdapInvalidAttributeValueException
    {
        EntryAttribute attribute = new DefaultEntryAttribute( "commonName" );
        attribute.add( "test" );

        EntryAttribute copy = new DefaultEntryAttribute( atCN, attribute );

        assertEquals( atCN, copy.getAttributeType() );
        assertEquals( "test", copy.getString() );
        assertTrue( copy.isHR() );

        attribute.add( "test2" );
        assertFalse( copy.contains( "test2" ) );
    }


    /**
     * Test the conversion method 
     */
    @Test
    public void testToClientAttribute()
    {
        EntryAttribute attribute = new DefaultEntryAttribute( atCN, "test", "test2" );

        EntryAttribute clientAttribute = attribute.clone();

        assertTrue( clientAttribute instanceof EntryAttribute );

        assertTrue( clientAttribute.contains( "test", "test2" ) );
        assertEquals( "cn", clientAttribute.getId() );

        attribute.remove( "test", "test2" );
        assertTrue( clientAttribute.contains( "test", "test2" ) );
    }


    /**
     * Test the serialization of a complete server attribute
     */
    @Test
    public void testSerializeCompleteAttribute() throws LdapException, IOException, ClassNotFoundException
    {
        DefaultEntryAttribute dsa = new DefaultEntryAttribute( atCN );
        dsa.setHR( true );
        dsa.setUpId( "CommonName" );
        dsa.add( "test1", "test2" );

        DefaultEntryAttribute dsaSer = deserializeValue( serializeValue( dsa ), atCN );
        assertEquals( dsa.toString(), dsaSer.toString() );
        assertEquals( "commonname", dsaSer.getId() );
        assertEquals( "CommonName", dsaSer.getUpId() );
        assertEquals( "test1", dsaSer.getString() );
        assertTrue( dsaSer.contains( "test2", "test1" ) );
        assertTrue( dsaSer.isHR() );
        assertTrue( dsaSer.isValid() );
    }


    /**
     * Test the serialization of a server attribute with no value
     */
    @Test
    public void testSerializeAttributeWithNoValue() throws LdapException, IOException, ClassNotFoundException
    {
        DefaultEntryAttribute dsa = new DefaultEntryAttribute( atCN );
        dsa.setHR( true );
        dsa.setId( "cn" );

        DefaultEntryAttribute dsaSer = deserializeValue( serializeValue( dsa ), atCN );
        assertEquals( dsa.toString(), dsaSer.toString() );
        assertEquals( "cn", dsaSer.getId() );
        assertEquals( "cn", dsaSer.getUpId() );
        assertEquals( 0, dsaSer.size() );
        assertTrue( dsaSer.isHR() );
        assertFalse( dsaSer.isValid() );
    }


    /**
     * Test the serialization of a server attribute with a null value
     */
    @Test
    public void testSerializeAttributeNullValue() throws LdapException, IOException, ClassNotFoundException
    {
        DefaultEntryAttribute dsa = new DefaultEntryAttribute( atDC );
        dsa.setHR( true );
        dsa.setUpId( "DomainComponent" );
        dsa.add( ( String ) null );

        DefaultEntryAttribute dsaSer = deserializeValue( serializeValue( dsa ), atDC );
        assertEquals( dsa.toString(), dsaSer.toString() );
        assertEquals( "domaincomponent", dsaSer.getId() );
        assertEquals( "DomainComponent", dsaSer.getUpId() );
        assertEquals( "", dsaSer.getString() );
        assertEquals( 1, dsaSer.size() );
        assertTrue( dsaSer.contains( ( String ) null ) );
        assertTrue( dsaSer.isHR() );
        assertTrue( dsaSer.isValid() );
    }


    /**
     * Test the serialization of a server attribute with a binary value
     */
    @Test
    public void testSerializeAttributeBinaryValue() throws LdapException, IOException, ClassNotFoundException
    {
        DefaultEntryAttribute dsa = new DefaultEntryAttribute( atPwd );
        dsa.setHR( false );
        byte[] password = Strings.getBytesUtf8("secret");
        dsa.add( password );

        DefaultEntryAttribute dsaSer = deserializeValue( serializeValue( dsa ), atPwd );
        assertEquals( dsa.toString(), dsaSer.toString() );
        assertEquals( "userpassword", dsaSer.getId() );
        assertEquals( "userPassword", dsaSer.getUpId() );
        assertTrue( Arrays.equals( dsa.getBytes(), dsaSer.getBytes() ) );
        assertEquals( 1, dsaSer.size() );
        assertTrue( dsaSer.contains( password ) );
        assertFalse( dsaSer.isHR() );
        assertTrue( dsaSer.isValid() );
    }
}
