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


import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.directory.api.asn1.util.Oid;
import org.apache.directory.api.i18n.I18n;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.ldap.model.schema.LdapSyntax;
import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
import org.apache.directory.api.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * An LDAP attribute.<p>
 * To define the kind of data stored, the client must set the isHR flag, or inject an AttributeType.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class DefaultAttribute implements Attribute, Cloneable
{
    /** logger for reporting errors that might not be handled properly upstream */
    private static final Logger LOG = LoggerFactory.getLogger( DefaultAttribute.class );

    /** The associated AttributeType */
    private AttributeType attributeType;

    /** The set of contained values */
    private Set<Value<?>> values = new LinkedHashSet<Value<?>>();

    /** The User provided ID */
    private String upId;

    /** The normalized ID (will be the OID if we have a AttributeType) */
    private String id;

    /** Tells if the attribute is Human Readable or not. When not set,
     * this flag is null. */
    private Boolean isHR;

    /** The computed hashcode. We don't want to compute it each time the hashcode() method is called */
    private volatile int h;


    //-------------------------------------------------------------------------
    // Helper methods
    //-------------------------------------------------------------------------
    private Value<String> createStringValue( AttributeType attributeType, String value )
    {
        Value<String> stringValue = null;

        if ( attributeType != null )
        {
            try
            {
                stringValue = new StringValue( attributeType, value );
            }
            catch ( LdapInvalidAttributeValueException iae )
            {
                return null;
            }
        }
        else
        {
            stringValue = new StringValue( value );
        }

        return stringValue;
    }


    private Value<byte[]> createBinaryValue( AttributeType attributeType, byte[] value )
        throws LdapInvalidAttributeValueException
    {
        Value<byte[]> binaryValue = null;

        if ( attributeType != null )
        {
            binaryValue = new BinaryValue( attributeType, value );
        }
        else
        {
            binaryValue = new BinaryValue( value );
        }

        return binaryValue;
    }


    //-------------------------------------------------------------------------
    // Constructors
    //-------------------------------------------------------------------------
    // maybe have some additional convenience constructors which take
    // an initial value as a string or a byte[]
    /**
     * Create a new instance of a Attribute, without ID nor value.
     * Used by the serializer
     */
    /* No protection*/DefaultAttribute()
    {
    }


    /**
     * Create a new instance of a schema aware Attribute, without ID nor value.
     * Used by the serializer
     */
    /* No protection*/DefaultAttribute( AttributeType attributeType, String upId, String normId, boolean isHR,
        int hashCode, Value<?>... values )
    {
        this.attributeType = attributeType;
        this.upId = upId;
        this.id = normId;
        this.isHR = isHR;
        this.h = hashCode;

        if ( values != null )
        {
            for ( Value<?> value : values )
            {
                this.values.add( value );
            }
        }
    }


    /**
     * Create a new instance of a schema aware Attribute, without ID nor value.
     * 
     * @param attributeType the attributeType for the empty attribute added into the entry
     */
    public DefaultAttribute( AttributeType attributeType )
    {
        if ( attributeType != null )
        {
            try
            {
                apply( attributeType );
            }
            catch ( LdapInvalidAttributeValueException liave )
            {
                // Do nothing, it can't happen, there is no value
            }
        }
    }


    /**
     * Create a new instance of an Attribute, without value.
     * @param upId The user provided ID
     */
    public DefaultAttribute( String upId )
    {
        setUpId( upId );
    }


    /**
     * Create a new instance of an Attribute, without value.
     * @param upId The user provided ID
     */
    public DefaultAttribute( byte[] upId )
    {
        setUpId( upId );
    }


    /**
     * Create a new instance of a schema aware Attribute, without value.
     * 
     * @param upId the ID for the added attributeType
     * @param attributeType the added AttributeType
     */
    public DefaultAttribute( String upId, AttributeType attributeType )
    {
        if ( attributeType == null )
        {
            String message = I18n.err( I18n.ERR_04460_ATTRIBUTE_TYPE_NULL_NOT_ALLOWED );
            LOG.error( message );
            throw new IllegalArgumentException( message );
        }

        try
        {
            apply( attributeType );
        }
        catch ( LdapInvalidAttributeValueException liave )
        {
            // Do nothing, it can't happen, there is no value
        }

        setUpId( upId, attributeType );
    }


    /**
     * Create a new instance of an Attribute, with some values, and a user provided ID.<br>
     * If the value does not correspond to the same attributeType, then it's
     * wrapped value is copied into a new ClientValue which uses the specified
     * attributeType.
     * <p>
     * Otherwise, the value is stored, but as a reference. It's not a copy.
     * </p>
     * @param upId the attributeType ID
     * @param vals an initial set of values for this attribute
     */
    public DefaultAttribute( String upId, Value<?>... vals )
    {
        // The value can be null, this is a valid value.
        if ( vals[0] == null )
        {
            add( new StringValue( ( String ) null ) );
        }
        else
        {
            for ( Value<?> val : vals )
            {
                if ( ( val instanceof StringValue ) || ( !val.isHumanReadable() ) )
                {
                    add( val );
                }
                else
                {
                    String message = I18n.err( I18n.ERR_04129, val.getClass().getName() );
                    LOG.error( message );
                    throw new IllegalStateException( message );
                }
            }
        }

        setUpId( upId );
    }


    /**
     * Create a new instance of a schema aware Attribute, without ID but with some values.
     * 
     * @param attributeType The attributeType added on creation
     * @param vals The added value for this attribute
     * @throws LdapInvalidAttributeValueException If any of the
     * added values is not valid
     */
    public DefaultAttribute( AttributeType attributeType, String... vals ) throws LdapInvalidAttributeValueException
    {
        this( null, attributeType, vals );
    }


    /**
     * Create a new instance of a schema aware Attribute, with some values, and a user provided ID.
     * 
     * @param upId the ID for the created attribute
     * @param attributeType The attributeType added on creation
     * @param vals the added values for this attribute
     * @throws LdapInvalidAttributeValueException If any of the
     * added values is not valid
     */
    public DefaultAttribute( String upId, AttributeType attributeType, String... vals )
        throws LdapInvalidAttributeValueException
    {
        if ( attributeType == null )
        {
            String message = I18n.err( I18n.ERR_04460_ATTRIBUTE_TYPE_NULL_NOT_ALLOWED );
            LOG.error( message );
            throw new IllegalArgumentException( message );
        }

        apply( attributeType );

        if ( ( vals != null ) && ( vals.length > 0 ) )
        {
            add( vals );
        }

        setUpId( upId, attributeType );
    }


    /**
     * Create a new instance of a schema aware Attribute, with some values, and a user provided ID.<br>
     * If the value does not correspond to the same attributeType, then it's
     * wrapped value is copied into a new Value which uses the specified
     * attributeType.
     * <p>
     * Otherwise, the value is stored, but as a reference. It's not a copy.
     * </p>
     * @param upId the ID of the created attribute
     * @param attributeType the attribute type according to the schema
     * @param vals an initial set of values for this attribute
     * @throws LdapInvalidAttributeValueException If any of the
     * added values is not valid
     */
    public DefaultAttribute( String upId, AttributeType attributeType, Value<?>... vals )
        throws LdapInvalidAttributeValueException
    {
        if ( attributeType == null )
        {
            String message = I18n.err( I18n.ERR_04460_ATTRIBUTE_TYPE_NULL_NOT_ALLOWED );
            LOG.error( message );
            throw new IllegalArgumentException( message );
        }

        apply( attributeType );
        setUpId( upId, attributeType );
        add( vals );
    }


    /**
     * Create a new instance of a schema aware Attribute, with some values.
     * <p>
     * If the value does not correspond to the same attributeType, then it's
     * wrapped value is copied into a new Value which uses the specified
     * attributeType.
     * </p>
     * @param attributeType the attribute type according to the schema
     * @param vals an initial set of values for this attribute
     */
    public DefaultAttribute( AttributeType attributeType, Value<?>... vals ) throws LdapInvalidAttributeValueException
    {
        this( null, attributeType, vals );
    }


    /**
     * Create a new instance of an Attribute, with some String values, and a user provided ID.
     * 
     * @param upId the ID of the created attribute
     * @param vals an initial set of String values for this attribute
     */
    public DefaultAttribute( String upId, String... vals )
    {
        try
        {
            add( vals );
        }
        catch ( LdapInvalidAttributeValueException liave )
        {
            // Do nothing, it can't happen
        }

        setUpId( upId );
    }


    /**
     * Create a new instance of an Attribute, with some binary values, and a user provided ID.
     * 
     * @param upId the ID of the created attribute
     * @param vals an initial set of binary values for this attribute
     */
    public DefaultAttribute( String upId, byte[]... vals )
    {
        try
        {
            add( vals );
        }
        catch ( LdapInvalidAttributeValueException liave )
        {
            // Do nothing, this can't happen
        }

        setUpId( upId );
    }


    /**
     * Create a new instance of a schema aware Attribute, with some byte[] values.
     * 
     * @param attributeType The attributeType added on creation
     * @param vals The added binary values
     * @throws LdapInvalidAttributeValueException If any of the
     * added values is not valid
     */
    public DefaultAttribute( AttributeType attributeType, byte[]... vals ) throws LdapInvalidAttributeValueException
    {
        this( null, attributeType, vals );
    }


    /**
     * Create a new instance of a schema aware Attribute, with some byte[] values, and
     * a user provided ID.
     * 
     * @param upId the ID for the added attribute
     * @param attributeType the AttributeType to be added
     * @param vals the binary values for the added attribute
     * @throws LdapInvalidAttributeValueException If any of the
     * added values is not valid
     */
    public DefaultAttribute( String upId, AttributeType attributeType, byte[]... vals )
        throws LdapInvalidAttributeValueException
    {
        if ( attributeType == null )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_04460_ATTRIBUTE_TYPE_NULL_NOT_ALLOWED ) );
        }

        apply( attributeType );
        add( vals );
        setUpId( upId, attributeType );
    }


    /**
     * Creates a new instance of schema aware Attribute, by copying another attribute.
     * If the initial Attribute is not schema aware, the copy will be if the attributeType
     * argument is not null.
     *
     * @param attributeType The attribute's type
     * @param attribute The attribute to be copied
     */
    public DefaultAttribute( AttributeType attributeType, Attribute attribute ) throws LdapException
    {
        // Copy the common values. isHR is only available on a ServerAttribute
        this.attributeType = attributeType;
        this.id = attribute.getId();
        this.upId = attribute.getUpId();

        if ( attributeType == null )
        {
            isHR = attribute.isHumanReadable();

            // Copy all the values
            for ( Value<?> value : attribute )
            {
                add( value.clone() );
            }

            if ( attribute.getAttributeType() != null )
            {
                apply( attribute.getAttributeType() );
            }
        }
        else
        {

            isHR = attributeType.getSyntax().isHumanReadable();

            // Copy all the values
            for ( Value<?> clientValue : attribute )
            {
                Value<?> serverValue = null;

                // We have to convert the value first
                if ( clientValue instanceof StringValue )
                {
                    if ( isHR )
                    {
                        serverValue = new StringValue( attributeType, clientValue.getString() );
                    }
                    else
                    {
                        // We have to convert the value to a binary value first
                        serverValue = new BinaryValue( attributeType,
                            clientValue.getBytes() );
                    }
                }
                else if ( clientValue instanceof BinaryValue )
                {
                    if ( isHR )
                    {
                        // We have to convert the value to a String value first
                        serverValue = new StringValue( attributeType,
                            clientValue.getString() );
                    }
                    else
                    {
                        serverValue = new BinaryValue( attributeType, clientValue.getBytes() );
                    }
                }

                add( serverValue );
            }
        }
    }


    /**
     * {@inheritDoc}
     */
    public byte[] getBytes() throws LdapInvalidAttributeValueException
    {
        Value<?> value = get();

        if ( !isHR && ( value != null ) )
        {
            return value.getBytes();
        }

        String message = I18n.err( I18n.ERR_04130 );
        LOG.error( message );
        throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
    }


    /**
     * {@inheritDoc}
     */
    public String getString() throws LdapInvalidAttributeValueException
    {
        Value<?> value = get();

        if ( isHR && ( value != null ) )
        {
            return value.getString();
        }

        String message = I18n.err( I18n.ERR_04131 );
        LOG.error( message );
        throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
    }


    /**
     * {@inheritDoc}
     */
    public String getId()
    {
        return id;
    }


    /**
     * {@inheritDoc}
     */
    public String getUpId()
    {
        return upId;
    }


    /**
     * {@inheritDoc}
     */
    public void setUpId( String upId )
    {
        setUpId( upId, attributeType );
    }


    /**
     * {@inheritDoc}
     */
    public void setUpId( byte[] upId )
    {
        setUpId( upId, attributeType );
    }


    /**
     * Check that the upId is either a name or the OID of a given AT
     */
    private boolean areCompatible( String id, AttributeType attributeType )
    {
        // First, get rid of the options, if any
        int optPos = id.indexOf( ';' );
        String idNoOption = id;

        if ( optPos != -1 )
        {
            idNoOption = id.substring( 0, optPos );
        }

        // Check that we find the ID in the AT names
        for ( String name : attributeType.getNames() )
        {
            if ( name.equalsIgnoreCase( idNoOption ) )
            {
                return true;
            }
        }

        // Not found in names, check the OID
        return Oid.isOid( id ) && attributeType.getOid().equals( id );
    }


    /**
     * {@inheritDoc}
     */
    public void setUpId( String upId, AttributeType attributeType )
    {
        String trimmed = Strings.trim( upId );

        if ( Strings.isEmpty( trimmed ) && ( attributeType == null ) )
        {
            throw new IllegalArgumentException( "Cannot set a null ID with a null AttributeType" );
        }

        String newId = Strings.toLowerCase( trimmed );

        setUpIdInternal( upId, newId, attributeType );
    }


    /**
     * {@inheritDoc}
     */
    public void setUpId( byte[] upId, AttributeType attributeType )
    {
        byte[] trimmed = Strings.trim( upId );

        if ( Strings.isEmpty( trimmed ) && ( attributeType == null ) )
        {
            throw new IllegalArgumentException( "Cannot set a null ID with a null AttributeType" );
        }

        String newId = Strings.toLowerCase( trimmed );

        setUpIdInternal( Strings.utf8ToString( upId ), newId, attributeType );
    }


    /**
     * {@inheritDoc}
     */
    private void setUpIdInternal( String upId, String newId, AttributeType attributeType )
    {
        if ( attributeType == null )
        {
            if ( this.attributeType == null )
            {
                this.upId = upId;
                this.id = newId;

                // Compute the hashCode
                rehash();

                return;
            }
            else
            {
                if ( areCompatible( newId, this.attributeType ) )
                {
                    this.upId = upId;
                    this.id = this.attributeType.getOid();

                    // Compute the hashCode
                    rehash();

                    return;
                }
                else
                {
                    return;
                }
            }
        }

        if ( Strings.isEmpty( newId ) )
        {
            this.attributeType = attributeType;
            this.upId = attributeType.getName();
            this.id = attributeType.getOid();

            // Compute the hashCode
            rehash();

            return;
        }

        if ( areCompatible( newId, attributeType ) )
        {
            this.upId = upId;
            this.id = attributeType.getOid();
            this.attributeType = attributeType;

            // Compute the hashCode
            rehash();

            return;
        }

        throw new IllegalArgumentException( "ID '" + id + "' and AttributeType '" + attributeType.getName()
            + "' are not compatible " );
    }


    /**
     * {@inheritDoc}
     */
    public boolean isHumanReadable()
    {
        return isHR != null ? isHR : false;
    }


    /**
     * {@inheritDoc}
     */
    public boolean isValid( AttributeType attributeType ) throws LdapInvalidAttributeValueException
    {
        LdapSyntax syntax = attributeType.getSyntax();

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

        SyntaxChecker syntaxChecker = syntax.getSyntaxChecker();

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

        // Check that we can have no value for this attributeType
        if ( values.size() == 0 )
        {
            return syntaxChecker.isValidSyntax( null );
        }

        // Check that we can't have more than one value if the AT is single-value
        if ( ( attributeType.isSingleValued() ) && ( values.size() > 1 ) )
        {
            return false;
        }

        // Now check the values
        for ( Value<?> value : values )
        {
            try
            {
                if ( !value.isValid( syntaxChecker ) )
                {
                    return false;
                }
            }
            catch ( LdapException le )
            {
                return false;
            }
        }

        return true;
    }


    /**
     * {@inheritDoc}
     */
    public int add( Value<?>... vals )
    {
        int nbAdded = 0;
        BinaryValue nullBinaryValue = null;
        StringValue nullStringValue = null;
        boolean nullValueAdded = false;
        Value<?>[] valArray = vals;

        if ( vals == null )
        {
            valArray = new Value[0];
        }

        if ( attributeType != null )
        {
            for ( Value<?> val : valArray )
            {
                if ( attributeType.getSyntax().isHumanReadable() )
                {
                    if ( ( val == null ) || val.isNull() )
                    {
                        try
                        {
                            Value<String> nullSV = new StringValue( attributeType, ( String ) null );

                            if ( values.add( nullSV ) )
                            {
                                nbAdded++;
                            }
                        }
                        catch ( LdapInvalidAttributeValueException iae )
                        {
                            continue;
                        }
                    }
                    else if ( val instanceof StringValue )
                    {
                        StringValue stringValue = ( StringValue ) val;

                        try
                        {
                            if ( stringValue.getAttributeType() == null )
                            {
                                stringValue.apply( attributeType );
                            }

                            if ( values.contains( val ) )
                            {
                                // Replace the value
                                values.remove( val );
                                values.add( val );
                            }
                            else if ( values.add( val ) )
                            {
                                nbAdded++;
                            }
                        }
                        catch ( LdapInvalidAttributeValueException iae )
                        {
                            continue;
                        }
                    }
                    else
                    {
                        String message = I18n.err( I18n.ERR_04451 );
                        LOG.error( message );
                    }
                }
                else
                {
                    if ( val == null )
                    {
                        if ( attributeType.getSyntax().getSyntaxChecker().isValidSyntax( val ) )
                        {
                            try
                            {
                                Value<byte[]> nullSV = new BinaryValue( attributeType, ( byte[] ) null );

                                if ( values.add( nullSV ) )
                                {
                                    nbAdded++;
                                }
                            }
                            catch ( LdapInvalidAttributeValueException iae )
                            {
                                continue;
                            }
                        }
                        else
                        {
                            String message = I18n.err( I18n.ERR_04452 );
                            LOG.error( message );
                        }
                    }
                    else
                    {
                        if ( val instanceof BinaryValue )
                        {
                            BinaryValue binaryValue = ( BinaryValue ) val;

                            try
                            {
                                if ( binaryValue.getAttributeType() == null )
                                {
                                    binaryValue = new BinaryValue( attributeType, val.getBytes() );
                                }

                                if ( values.add( binaryValue ) )
                                {
                                    nbAdded++;
                                }
                            }
                            catch ( LdapInvalidAttributeValueException iae )
                            {
                                continue;
                            }
                        }
                        else
                        {
                            String message = I18n.err( I18n.ERR_04452 );
                            LOG.error( message );
                        }
                    }
                }
            }
        }
        else
        {
            for ( Value<?> val : valArray )
            {
                if ( val == null )
                {
                    // We have a null value. If the HR flag is not set, we will consider
                    // that the attribute is not HR. We may change this later
                    if ( isHR == null )
                    {
                        // This is the first value. Add both types, as we
                        // don't know yet the attribute type's, but we may
                        // know later if we add some new value.
                        // We have to do that because we are using a Set,
                        // and we can't remove the first element of the Set.
                        nullBinaryValue = new BinaryValue( ( byte[] ) null );
                        nullStringValue = new StringValue( ( String ) null );

                        values.add( nullBinaryValue );
                        values.add( nullStringValue );
                        nullValueAdded = true;
                        nbAdded++;
                    }
                    else if ( !isHR )
                    {
                        // The attribute type is binary.
                        nullBinaryValue = new BinaryValue( ( byte[] ) null );

                        // Don't add a value if it already exists.
                        if ( !values.contains( nullBinaryValue ) )
                        {
                            values.add( nullBinaryValue );
                            nbAdded++;
                        }

                    }
                    else
                    {
                        // The attribute is HR
                        nullStringValue = new StringValue( ( String ) null );

                        // Don't add a value if it already exists.
                        if ( !values.contains( nullStringValue ) )
                        {
                            values.add( nullStringValue );
                        }
                    }
                }
                else
                {
                    // Let's check the value type.
                    if ( val instanceof StringValue )
                    {
                        // We have a String value
                        if ( isHR == null )
                        {
                            // The attribute type will be set to HR
                            isHR = true;
                            values.add( val );
                            nbAdded++;
                        }
                        else if ( !isHR )
                        {
                            // The attributeType is binary, convert the
                            // value to a BinaryValue
                            BinaryValue bv = new BinaryValue( val.getBytes() );

                            if ( !contains( bv ) )
                            {
                                values.add( bv );
                                nbAdded++;
                            }
                        }
                        else
                        {
                            // The attributeType is HR, simply add the value
                            if ( !contains( val ) )
                            {
                                values.add( val );
                                nbAdded++;
                            }
                        }
                    }
                    else
                    {
                        // We have a Binary value
                        if ( isHR == null )
                        {
                            // The attribute type will be set to binary
                            isHR = false;
                            values.add( val );
                            nbAdded++;
                        }
                        else if ( !isHR )
                        {
                            // The attributeType is not HR, simply add the value if it does not already exist
                            if ( !contains( val ) )
                            {
                                values.add( val );
                                nbAdded++;
                            }
                        }
                        else
                        {
                            // The attribute Type is HR, convert the
                            // value to a StringValue
                            StringValue sv = new StringValue( val.getString() );

                            if ( !contains( sv ) )
                            {
                                values.add( sv );
                                nbAdded++;
                            }
                        }
                    }
                }
            }
        }

        // Last, not least, if a nullValue has been added, and if other
        // values are all String, we have to keep the correct nullValue,
        // and to remove the other
        if ( nullValueAdded )
        {
            if ( isHR )
            {
                // Remove the Binary value
                values.remove( nullBinaryValue );
            }
            else
            {
                // Remove the String value
                values.remove( nullStringValue );
            }
        }

        return nbAdded;
    }


    /**
     * {@inheritDoc}
     */
    public int add( String... vals ) throws LdapInvalidAttributeValueException
    {
        int nbAdded = 0;
        String[] valArray = vals;

        if ( vals == null )
        {
            valArray = new String[0];
        }

        // First, if the isHR flag is not set, we assume that the
        // attribute is HR, because we are asked to add some strings.
        if ( isHR == null )
        {
            isHR = true;
        }

        // Check the attribute type.
        if ( attributeType == null )
        {
            if ( isHR )
            {
                for ( String val : valArray )
                {
                    Value<String> value = createStringValue( attributeType, val );

                    if ( value == null )
                    {
                        // The value can't be normalized : we don't add it.
                        LOG.error( I18n.err( I18n.ERR_04449, val ) );
                        continue;
                    }

                    // Call the add(Value) method, if not already present
                    if ( add( value ) == 1 )
                    {
                        nbAdded++;
                    }
                    else
                    {
                        LOG.warn( I18n.err( I18n.ERR_04486_VALUE_ALREADY_EXISTS, val, upId ) );
                    }
                }
            }
            else
            {
                // The attribute is binary. Transform the String to byte[]
                for ( String val : valArray )
                {
                    byte[] valBytes = null;

                    if ( val != null )
                    {
                        valBytes = Strings.getBytesUtf8( val );
                    }

                    Value<byte[]> value = createBinaryValue( attributeType, valBytes );

                    // Now call the add(Value) method
                    if ( add( value ) == 1 )
                    {
                        nbAdded++;
                    }
                }
            }
        }
        else
        {
            if ( attributeType.isSingleValued() && ( values.size() + valArray.length > 1 ) )
            {
                LOG.error( I18n.err( I18n.ERR_04487_ATTRIBUTE_IS_SINGLE_VALUED, attributeType.getName() ) );
                return 0;
            }

            if ( isHR )
            {
                for ( String val : valArray )
                {
                    Value<String> value = createStringValue( attributeType, val );

                    if ( value == null )
                    {
                        // The value can't be normalized : we don't add it.
                        LOG.error( I18n.err( I18n.ERR_04449, val ) );
                        continue;
                    }

                    // Call the add(Value) method, if not already present
                    if ( add( value ) == 1 )
                    {
                        nbAdded++;
                    }
                    else
                    {
                        LOG.warn( I18n.err( I18n.ERR_04486_VALUE_ALREADY_EXISTS, val, upId ) );
                    }
                }
            }
            else
            {
                // The attribute is binary. Transform the String to byte[]
                for ( String val : valArray )
                {
                    byte[] valBytes = null;

                    if ( val != null )
                    {
                        valBytes = Strings.getBytesUtf8( val );
                    }

                    Value<byte[]> value = createBinaryValue( attributeType, valBytes );

                    // Now call the add(Value) method
                    if ( add( value ) == 1 )
                    {
                        nbAdded++;
                    }
                }
            }
        }

        return nbAdded;
    }


    /**
     * {@inheritDoc}
     */
    public int add( byte[]... vals ) throws LdapInvalidAttributeValueException
    {
        int nbAdded = 0;
        byte[][] valArray = vals;

        if ( vals == null )
        {
            valArray = new byte[0][];
        }

        // First, if the isHR flag is not set, we assume that the
        // attribute is not HR, because we are asked to add some byte[].
        if ( isHR == null )
        {
            isHR = false;
        }

        if ( !isHR )
        {
            for ( byte[] val : valArray )
            {
                Value<byte[]> value = null;

                if ( attributeType == null )
                {
                    value = new BinaryValue( val );
                }
                else
                {
                    value = createBinaryValue( attributeType, val );
                }

                if ( add( value ) != 0 )
                {
                    nbAdded++;
                }
                else
                {
                    LOG.warn( I18n.err( I18n.ERR_04486_VALUE_ALREADY_EXISTS, Strings.dumpBytes( val ), upId ) );
                }
            }
        }
        else
        {
            // We can't add Binary values into a String Attribute
            LOG.info( I18n.err( I18n.ERR_04451 ) );
            return 0;
        }

        return nbAdded;
    }


    /**
     * {@inheritDoc}
     */
    public void clear()
    {
        values.clear();
    }


    /**
     * {@inheritDoc}
     */
    public boolean contains( Value<?>... vals )
    {
        if ( isHR == null )
        {
            // If this flag is null, then there is no values.
            return false;
        }

        if ( attributeType == null )
        {
            if ( isHR )
            {
                // Iterate through all the values, convert the Binary values
                // to String values, and quit id any of the values is not
                // contained in the object
                for ( Value<?> val : vals )
                {
                    if ( val instanceof StringValue )
                    {
                        if ( !values.contains( val ) )
                        {
                            return false;
                        }
                    }
                    else
                    {
                        byte[] binaryVal = val.getBytes();

                        // We have to convert the binary value to a String
                        if ( !values.contains( new StringValue( Strings.utf8ToString( binaryVal ) ) ) )
                        {
                            return false;
                        }
                    }
                }
            }
            else
            {
                // Iterate through all the values, convert the String values
                // to binary values, and quit id any of the values is not
                // contained in the object
                for ( Value<?> val : vals )
                {
                    if ( val.isHumanReadable() )
                    {
                        String stringVal = val.getString();

                        // We have to convert the binary value to a String
                        if ( !values.contains( new BinaryValue( Strings.getBytesUtf8( stringVal ) ) ) )
                        {
                            return false;
                        }
                    }
                    else
                    {
                        if ( !values.contains( val ) )
                        {
                            return false;
                        }
                    }
                }
            }
        }
        else
        {
            // Iterate through all the values, and quit if we
            // don't find one in the values. We have to separate the check
            // depending on the isHR flag value.
            if ( isHR )
            {
                for ( Value<?> val : vals )
                {
                    if ( val instanceof StringValue )
                    {
                        StringValue stringValue = ( StringValue ) val;

                        try
                        {
                            if ( stringValue.getAttributeType() == null )
                            {
                                stringValue.apply( attributeType );
                            }
                        }
                        catch ( LdapInvalidAttributeValueException liave )
                        {
                            return false;
                        }

                        if ( !values.contains( val ) )
                        {
                            return false;
                        }
                    }
                    else
                    {
                        // Not a String value
                        return false;
                    }
                }
            }
            else
            {
                for ( Value<?> val : vals )
                {
                    if ( val instanceof BinaryValue )
                    {
                        if ( !values.contains( val ) )
                        {
                            return false;
                        }
                    }
                    else
                    {
                        // Not a Binary value
                        return false;
                    }
                }
            }
        }

        return true;
    }


    /**
     * {@inheritDoc}
     */
    public boolean contains( String... vals )
    {
        if ( isHR == null )
        {
            // If this flag is null, then there is no values.
            return false;
        }

        if ( attributeType == null )
        {
            if ( isHR )
            {
                for ( String val : vals )
                {
                    try
                    {
                        if ( !contains( new StringValue( val ) ) )
                        {
                            return false;
                        }
                    }
                    catch ( IllegalArgumentException iae )
                    {
                        return false;
                    }
                }
            }
            else
            {
                // As the attribute type is binary, we have to convert
                // the values before checking for them in the values
                // Iterate through all the values, and quit if we
                // don't find one in the values
                for ( String val : vals )
                {
                    byte[] binaryVal = Strings.getBytesUtf8( val );

                    if ( !contains( new BinaryValue( binaryVal ) ) )
                    {
                        return false;
                    }
                }
            }
        }
        else
        {
            if ( isHR )
            {
                // Iterate through all the values, and quit if we
                // don't find one in the values
                for ( String val : vals )
                {
                    try
                    {
                        StringValue value = new StringValue( attributeType, val );

                        if ( !values.contains( value ) )
                        {
                            return false;
                        }
                    }
                    catch ( LdapInvalidAttributeValueException liave )
                    {
                        return false;
                    }
                }

                return true;
            }
            else
            {
                return false;
            }
        }

        return true;
    }


    /**
     * {@inheritDoc}
     */
    public boolean contains( byte[]... vals )
    {
        if ( isHR == null )
        {
            // If this flag is null, then there is no values.
            return false;
        }

        if ( attributeType == null )
        {
            if ( !isHR )
            {
                // Iterate through all the values, and quit if we
                // don't find one in the values
                for ( byte[] val : vals )
                {
                    if ( !contains( new BinaryValue( val ) ) )
                    {
                        return false;
                    }
                }
            }
            else
            {
                // As the attribute type is String, we have to convert
                // the values before checking for them in the values
                // Iterate through all the values, and quit if we
                // don't find one in the values
                for ( byte[] val : vals )
                {
                    String stringVal = Strings.utf8ToString( val );

                    if ( !contains( new StringValue( stringVal ) ) )
                    {
                        return false;
                    }
                }
            }
        }
        else
        {
            if ( !isHR )
            {
                // Iterate through all the values, and quit if we
                // don't find one in the values
                for ( byte[] val : vals )
                {
                    try
                    {
                        BinaryValue value = new BinaryValue( attributeType, val );

                        if ( !values.contains( value ) )
                        {
                            return false;
                        }
                    }
                    catch ( LdapInvalidAttributeValueException liave )
                    {
                        return false;
                    }
                }

                return true;
            }
            else
            {
                return false;
            }
        }

        return true;
    }


    /**
     * {@inheritDoc}
     */
    public Value<?> get()
    {
        if ( values.isEmpty() )
        {
            return null;
        }

        return values.iterator().next();
    }


    /**
     * {@inheritDoc}
     */
    public int size()
    {
        return values.size();
    }


    /**
     * {@inheritDoc}
     */
    public boolean remove( Value<?>... vals )
    {
        if ( ( isHR == null ) || ( values.size() == 0 ) )
        {
            // Trying to remove a value from an empty list will fail
            return false;
        }

        boolean removed = true;

        if ( attributeType == null )
        {
            if ( isHR )
            {
                for ( Value<?> val : vals )
                {
                    if ( val instanceof StringValue )
                    {
                        removed &= values.remove( val );
                    }
                    else
                    {
                        // Convert the binary value to a string value
                        byte[] binaryVal = val.getBytes();
                        removed &= values.remove( new StringValue( Strings.utf8ToString( binaryVal ) ) );
                    }
                }
            }
            else
            {
                for ( Value<?> val : vals )
                {
                    removed &= values.remove( val );
                }
            }
        }
        else
        {
            // Loop through all the values to remove. If one of
            // them is not present, the method will return false.
            // As the attribute may be HR or not, we have two separated treatments
            if ( isHR )
            {
                for ( Value<?> val : vals )
                {
                    if ( val instanceof StringValue )
                    {
                        StringValue stringValue = ( StringValue ) val;

                        try
                        {
                            if ( stringValue.getAttributeType() == null )
                            {
                                stringValue.apply( attributeType );
                            }

                            removed &= values.remove( stringValue );
                        }
                        catch ( LdapInvalidAttributeValueException liave )
                        {
                            removed = false;
                        }
                    }
                    else
                    {
                        removed = false;
                    }
                }
            }
            else
            {
                for ( Value<?> val : vals )
                {
                    if ( val instanceof BinaryValue )
                    {
                        try
                        {
                            BinaryValue binaryValue = ( BinaryValue ) val;

                            if ( binaryValue.getAttributeType() == null )
                            {
                                binaryValue.apply( attributeType );
                            }

                            removed &= values.remove( binaryValue );
                        }
                        catch ( LdapInvalidAttributeValueException liave )
                        {
                            removed = false;
                        }
                    }
                    else
                    {
                        removed = false;
                    }
                }
            }
        }

        return removed;
    }


    /**
     * {@inheritDoc}
     */
    public boolean remove( byte[]... vals )
    {
        if ( ( isHR == null ) || ( values.size() == 0 ) )
        {
            // Trying to remove a value from an empty list will fail
            return false;
        }

        boolean removed = true;

        if ( attributeType == null )
        {
            if ( !isHR )
            {
                // The attribute type is not HR, we can directly process the values
                for ( byte[] val : vals )
                {
                    BinaryValue value = new BinaryValue( val );
                    removed &= values.remove( value );
                }
            }
            else
            {
                // The attribute type is String, we have to convert the values
                // to String before removing them
                for ( byte[] val : vals )
                {
                    StringValue value = new StringValue( Strings.utf8ToString( val ) );
                    removed &= values.remove( value );
                }
            }
        }
        else
        {
            if ( !isHR )
            {
                try
                {
                    for ( byte[] val : vals )
                    {
                        BinaryValue value = new BinaryValue( attributeType, val );
                        removed &= values.remove( value );
                    }
                }
                catch ( LdapInvalidAttributeValueException liave )
                {
                    removed = false;
                }
            }
            else
            {
                removed = false;
            }
        }

        return removed;
    }


    /**
     * {@inheritDoc}
     */
    public boolean remove( String... vals )
    {
        if ( ( isHR == null ) || ( values.size() == 0 ) )
        {
            // Trying to remove a value from an empty list will fail
            return false;
        }

        boolean removed = true;

        if ( attributeType == null )
        {
            if ( isHR )
            {
                // The attribute type is HR, we can directly process the values
                for ( String val : vals )
                {
                    StringValue value = new StringValue( val );
                    removed &= values.remove( value );
                }
            }
            else
            {
                // The attribute type is binary, we have to convert the values
                // to byte[] before removing them
                for ( String val : vals )
                {
                    BinaryValue value = new BinaryValue( Strings.getBytesUtf8( val ) );
                    removed &= values.remove( value );
                }
            }
        }
        else
        {
            if ( isHR )
            {
                for ( String val : vals )
                {
                    try
                    {
                        StringValue value = new StringValue( attributeType, val );
                        removed &= values.remove( value );
                    }
                    catch ( LdapInvalidAttributeValueException liave )
                    {
                        removed = false;
                    }
                }
            }
            else
            {
                removed = false;
            }
        }

        return removed;
    }


    /**
     * An iterator on top of the stored values.
     * 
     * @return an iterator over the stored values.
     */
    public Iterator<Value<?>> iterator()
    {
        return values.iterator();
    }


    /**
     * {@inheritDoc}
     */
    public AttributeType getAttributeType()
    {
        return attributeType;
    }


    /**
     * {@inheritDoc}
     */
    public void apply( AttributeType attributeType ) throws LdapInvalidAttributeValueException
    {
        if ( attributeType == null )
        {
            throw new IllegalArgumentException( "The AttributeType parameter should not be null" );
        }

        this.attributeType = attributeType;
        this.id = attributeType.getOid();

        if ( Strings.isEmpty( this.upId ) )
        {
            this.upId = attributeType.getName();
        }
        else
        {
            if ( !areCompatible( this.upId, attributeType ) )
            {
                this.upId = attributeType.getName();
            }
        }

        if ( values != null )
        {
            Set<Value<?>> newValues = new LinkedHashSet<Value<?>>( values.size() );

            for ( Value<?> value : values )
            {
                if ( value instanceof StringValue )
                {
                    newValues.add( new StringValue( attributeType, value.getString() ) );
                }
                else
                {
                    newValues.add( new BinaryValue( attributeType, value.getBytes() ) );
                }
            }

            values = newValues;
        }

        isHR = attributeType.getSyntax().isHumanReadable();

        // Compute the hashCode
        rehash();
    }


    /**
     * {@inheritDoc}
     */
    public boolean isInstanceOf( AttributeType attributeType ) throws LdapInvalidAttributeValueException
    {
        return ( attributeType != null )
            && ( this.attributeType.equals( attributeType ) || this.attributeType.isDescendantOf( attributeType ) );
    }


    //-------------------------------------------------------------------------
    // Overloaded Object classes
    //-------------------------------------------------------------------------
    /**
     * A helper method to rehash the hashCode
     */
    private void rehash()
    {
        h = 37;

        if ( isHR != null )
        {
            h = h * 17 + isHR.hashCode();
        }

        if ( id != null )
        {
            h = h * 17 + id.hashCode();
        }

        if ( attributeType != null )
        {
            h = h * 17 + attributeType.hashCode();
        }
    }


    /**
     * The hashCode is based on the id, the isHR flag and
     * on the internal values.
     * 
     * @see Object#hashCode()
     * @return the instance's hashcode
     */
    public int hashCode()
    {
        if ( h == 0 )
        {
            rehash();
        }

        return h;
    }


    /**
     * @see Object#equals(Object)
     */
    public boolean equals( Object obj )
    {
        if ( obj == this )
        {
            return true;
        }

        if ( !( obj instanceof Attribute ) )
        {
            return false;
        }

        Attribute other = ( Attribute ) obj;

        if ( id == null )
        {
            if ( other.getId() != null )
            {
                return false;
            }
        }
        else
        {
            if ( other.getId() == null )
            {
                return false;
            }
            else
            {
                if ( attributeType != null )
                {
                    if ( !attributeType.equals( other.getAttributeType() ) )
                    {
                        return false;
                    }
                }
                else if ( !id.equals( other.getId() ) )
                {
                    return false;
                }
            }
        }

        if ( isHumanReadable() != other.isHumanReadable() )
        {
            return false;
        }

        if ( values.size() != other.size() )
        {
            return false;
        }

        for ( Value<?> val : values )
        {
            if ( !other.contains( val ) )
            {
                return false;
            }
        }

        if ( attributeType == null )
        {
            return other.getAttributeType() == null;
        }

        return attributeType.equals( other.getAttributeType() );
    }


    /**
     * {@inheritDoc}
     */
    public Attribute clone()
    {
        try
        {
            DefaultAttribute attribute = ( DefaultAttribute ) super.clone();

            if ( this.attributeType != null )
            {
                attribute.id = attributeType.getOid();
                attribute.attributeType = attributeType;
            }

            attribute.values = new LinkedHashSet<Value<?>>( values.size() );

            for ( Value<?> value : values )
            {
                // No need to clone the value, it will never be changed
                attribute.values.add( value );
            }

            return attribute;
        }
        catch ( CloneNotSupportedException cnse )
        {
            return null;
        }
    }


    /**
     * This is the place where we serialize attributes, and all theirs
     * elements.
     * 
     * {@inheritDoc}
     */
    public void writeExternal( ObjectOutput out ) throws IOException
    {
        // Write the UPId (the id will be deduced from the upID)
        out.writeUTF( upId );

        // Write the HR flag, if not null
        if ( isHR != null )
        {
            out.writeBoolean( true );
            out.writeBoolean( isHR );
        }
        else
        {
            out.writeBoolean( false );
        }

        // Write the number of values
        out.writeInt( size() );

        if ( size() > 0 )
        {
            // Write each value
            for ( Value<?> value : values )
            {
                // Write the value
                value.writeExternal( out );
            }
        }

        out.flush();
    }


    /**
     * {@inheritDoc}
     */
    public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
    {
        // Read the ID and the UPId
        upId = in.readUTF();

        // Compute the id
        setUpId( upId );

        // Read the HR flag, if not null
        if ( in.readBoolean() )
        {
            isHR = in.readBoolean();
        }

        // Read the number of values
        int nbValues = in.readInt();

        if ( nbValues > 0 )
        {
            for ( int i = 0; i < nbValues; i++ )
            {
                Value<?> value = null;

                if ( isHR )
                {
                    value = new StringValue( attributeType );
                }
                else
                {
                    value = new BinaryValue( attributeType );
                }

                value.readExternal( in );

                values.add( value );
            }
        }
    }


    /**
     * @see Object#toString()
     */
    public String toString()
    {
        return toString( "" );
    }


    /**
     * {@inheritDoc}
     */
    public String toString( String tabs )
    {
        StringBuilder sb = new StringBuilder();

        if ( ( values != null ) && ( values.size() != 0 ) )
        {
            boolean isFirst = true;

            for ( Value<?> value : values )
            {
                if ( isFirst )
                {
                    isFirst = false;
                }
                else
                {
                    sb.append( '\n' );
                }

                sb.append( tabs ).append( upId ).append( ": " );

                if ( value.isNull() )
                {
                    sb.append( "''" );
                }
                else
                {
                    sb.append( value );
                }
            }
        }
        else
        {
            sb.append( tabs ).append( upId ).append( ": (null)" );
        }

        return sb.toString();
    }
}
