/*
 * 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.shared.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.shared.asn1.util.OID;
import org.apache.directory.shared.i18n.I18n;
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.message.ResultCodeEnum;
import org.apache.directory.shared.ldap.model.schema.MutableAttributeTypeImpl;
import org.apache.directory.shared.ldap.model.schema.SyntaxChecker;
import org.apache.directory.shared.util.Strings;
import org.apache.directory.shared.util.Unicode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * A client side entry attribute. The client is not aware of the schema,
 * so we can't tell if the stored value will be String or Binary. We will
 * default to Binary.<p>
 * To define the kind of data stored, the client must set the isHR flag.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class DefaultEntryAttribute implements EntryAttribute
{
    /** logger for reporting errors that might not be handled properly upstream */
    private static final Logger LOG = LoggerFactory.getLogger( DefaultEntryAttribute.class );

    /** The associated AttributeType */
    private MutableAttributeTypeImpl 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( MutableAttributeTypeImpl attributeType, String value )
    {
        Value<String> stringValue = null;
        
        if ( attributeType != null )
        {
            stringValue = new StringValue( attributeType, value );
            
            try
            {
                stringValue.normalize();
            }
            catch( LdapException ne )
            {
                // The value can't be normalized : we don't add it.
                LOG.error( I18n.err( I18n.ERR_04449, value ) );
                return null;
            }
    
            if ( !stringValue.isValid() )
            {
                // The value is not valid : we don't add it.
                LOG.error( I18n.err( I18n.ERR_04450, value ) );
                return null;
            }
        }
        else
        {
            stringValue = new StringValue( value );
        }
        
        return stringValue;
    }


    private Value<byte[]> createBinaryValue( MutableAttributeTypeImpl attributeType, byte[] value )
    {
        Value<byte[]> binaryValue = null;
        
        if ( attributeType != null )
        {
            binaryValue = new BinaryValue( attributeType, value );
            
            try
            {
                binaryValue.normalize();
            }
            catch( LdapException ne )
            {
                // The value can't be normalized : we don't add it.
                LOG.error( I18n.err( I18n.ERR_04449, value ) );
                return null;
            }
            
            if ( !binaryValue.isValid() )
            {
                // The value is not valid : we don't add it.
                LOG.error( I18n.err( I18n.ERR_04450, value ) );
                return null;
            }
        }
        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 EntryAttribute, without ID nor value.
     */
    public DefaultEntryAttribute()
    {
    }


    /**
     * Create a new instance of a EntryAttribute, without ID nor value.
     */
    /* No qualifier */ DefaultEntryAttribute( MutableAttributeTypeImpl 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 EntryAttribute, without ID nor value.
     * 
     * @param attributeType the attributeType for the empty attribute added into the entry
     */
    public DefaultEntryAttribute( MutableAttributeTypeImpl attributeType )
    {
        if ( attributeType == null )
        {
            String message = I18n.err( I18n.ERR_04442_NULL_AT_NOT_ALLOWED );
            LOG.error( message );
            throw new IllegalArgumentException( message );
        }
        
        setAttributeType( attributeType );
    }


    /**
     * Create a new instance of a EntryAttribute, without value.
     */
    public DefaultEntryAttribute( String upId )
    {
        setUpId( upId );
    }


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

        setAttributeType( attributeType );
        setUpId( upId, attributeType );
    }


    /**
     * 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.
     * 
     * Otherwise, the value is stored, but as a reference. It's not a copy.
     *
     * @param upId
     * @param vals an initial set of values for this attribute
     */
    public DefaultEntryAttribute( String upId, Value<?>... vals )
    {
        // The value can be null, this is a valid value.
        if ( vals[0] == null )
        {
             add( new StringValue() );
        }
        else
        {
            for ( Value<?> val:vals )
            {
                if ( ( val instanceof StringValue) || ( val.isBinary() ) )
                {
                    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 EntryAttribute, without ID but with some values.
     * 
     * @param attributeType The attributeType added on creation
     * @param vals The added value for this attribute
     */
    public DefaultEntryAttribute( MutableAttributeTypeImpl attributeType, String... vals )
    {
        this( null, attributeType, vals );
    }


    /**
     * Create a new instance of a EntryAttribute.
     * 
     * @param upId the ID for the added attribute
     * @param attributeType The attributeType added on creation
     * @param vals the added values for this attribute
     */
    public DefaultEntryAttribute( String upId, MutableAttributeTypeImpl attributeType, String... vals )
    {
        if ( attributeType == null )
        {
            String message = I18n.err( I18n.ERR_04442_NULL_AT_NOT_ALLOWED );
            LOG.error( message );
            throw new IllegalArgumentException( message );
        }

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


    /**
     * Doc me more!
     *
     * 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.
     * 
     * Otherwise, the value is stored, but as a reference. It's not a copy.
     *
     * @param upId the ID of the added attribute
     * @param attributeType the attribute type according to the schema
     * @param vals an initial set of values for this attribute
     */
    public DefaultEntryAttribute( String upId, MutableAttributeTypeImpl attributeType, Value<?>... vals )
    {
        if ( attributeType == null )
        {
            String message = I18n.err( I18n.ERR_04442_NULL_AT_NOT_ALLOWED );
            LOG.error( message );
            throw new IllegalArgumentException( message );
        }
        
        setAttributeType( attributeType );
        setUpId( upId, attributeType );
        add( vals );
    }


    /**
     * Doc me more!
     *
     * 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.
     *
     * @param attributeType the attribute type according to the schema
     * @param vals an initial set of values for this attribute
     */
    public DefaultEntryAttribute( MutableAttributeTypeImpl attributeType, Value<?>... vals )
    {
        this( null, attributeType, vals );
    }


    /**
     * Create a new instance of a EntryAttribute.
     */
    public DefaultEntryAttribute( String upId, String... vals )
    {
        add( vals );
        setUpId( upId );
    }


    /**
     * Create a new instance of a EntryAttribute, with some byte[] values.
     */
    public DefaultEntryAttribute( String upId, byte[]... vals )
    {
        add( vals );
        setUpId( upId );
    }


    /**
     * Create a new instance of a EntryAttribute, with some byte[] values.
     * 
     * @param attributeType The attributeType added on creation
     * @param vals The value for the added attribute
     */
    public DefaultEntryAttribute( MutableAttributeTypeImpl attributeType, byte[]... vals )
    {
        this( null, attributeType, vals );
    }


    /**
     * Create a new instance of a EntryAttribute, with some byte[] values.
     * 
     * @param upId the ID for the added attribute
     * @param attributeType the AttributeType to be added
     * @param vals the values for the added attribute
     */
    public DefaultEntryAttribute( String upId, MutableAttributeTypeImpl attributeType, byte[]... vals )
    {
        if ( attributeType == null )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_04442_NULL_AT_NOT_ALLOWED ) );
        }

        setAttributeType( attributeType );
        add( vals );
        setUpId( upId, attributeType );
    }
    
    
    /**
     * 
     * Creates a new instance of DefaultServerAttribute, by copying
     * another attribute, which can be a ClientAttribute. If the other
     * attribute is a ServerAttribute, it will be copied.
     *
     * @param attributeType The attribute's type 
     * @param attribute The attribute to be copied
     */
    public DefaultEntryAttribute( MutableAttributeTypeImpl attributeType, EntryAttribute attribute )
    {
        // 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.isHR();

            // Copy all the values
            for ( Value<?> value:attribute )
            {
                add( value.clone() );
            }
        }
        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 );
            }
        }
    }

    
    /**
     * <p>
     * Get the byte[] value, if and only if the value is known to be Binary,
     * otherwise a InvalidAttributeValueException will be thrown
     * </p>
     * <p>
     * Note that this method returns the first value only.
     * </p>
     *
     * @return The value as a byte[]
     * @throws LdapInvalidAttributeValueException If the value is a String
     */
    public byte[] getBytes() throws LdapInvalidAttributeValueException
    {
        Value<?> value = get();
        
        if ( value.isBinary() )
        {
            return value.getBytes();
        }
        else
        {
            String message = I18n.err( I18n.ERR_04130 );
            LOG.error( message );
            throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
        }
    }


    /**
     * <p>
     * Get the String value, if and only if the value is known to be a String,
     * otherwise a InvalidAttributeValueException will be thrown
     * </p>
     * <p>
     * Note that this method returns the first value only.
     * </p>
     *
     * @return The value as a String
     * @throws LdapInvalidAttributeValueException If the value is a byte[]
     */
    public String getString() throws LdapInvalidAttributeValueException
    {
        Value<?> value = get();
        
        if ( value instanceof StringValue)
        {
            return value.getString();
        }
        else
        {
            if ( isHR )
            {
                // Try to convert the value from a byte[] to a String
                if ( value != null )
                {
                    String valueStr = Strings.utf8ToString((byte[]) value.getReference());
                
                    return valueStr;
                }
            }
            
            String message = I18n.err( I18n.ERR_04131 );
            LOG.error( message );
            throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
        }
    }


    /**
     * Get's the attribute identifier. Its value is the same than the
     * user provided ID.
     *
     * @return the attribute's identifier
     */
    public String getId()
    {
        return id;
    }


    /**
     * <p>
     * Set the attribute to Human Readable or to Binary. 
     * </p>
     * @param isHR <code>true</code> for a Human Readable attribute, 
     * <code>false</code> for a Binary attribute.
     */
    public void setHR( boolean isHR )
    {
        //TODO : deal with the values, we may have to convert them.

        if ( attributeType == null )
        {
            this.isHR = isHR;
            
            // Compute the hashCode
            rehash();
        }
    }

    
    /**
     * Set the Attribute ID. 
     *
     * @param id The attribute ID
     * @throws IllegalArgumentException If the ID is empty or null or
     * resolve to an empty value after being trimmed
     */
    public void setId( String id )
    {
        String newId = Strings.trim(Strings.lowerCaseAscii(id));

        if ( newId.length() == 0 )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_04132 ) );
        }
        
        if ( attributeType != null )
        {
            if ( attributeType.getName() == null )
            {
                // If the name is null, then we may have to store an OID
                if ( !OID.isOID( newId )  || !attributeType.getOid().equals( newId ) )
                {
                    // This is an error
                    throw new IllegalArgumentException( I18n.err( I18n.ERR_04132 ) );
                }
            }
            else
            {
                // We have at least one name. Check that the normalized upId
                // is one of those names. Otherwise, the upId may be an OID too.
                // In this case, it must be equals to the attributeType OID.
                for ( String atName:attributeType.getNames() )
                {
                    if ( atName.equalsIgnoreCase( newId ) )
                    {
                        // Found ! We can store the upId and get out
                        this.id = newId;
                        this.upId = id;
                        
                        // Compute the hashCode
                        rehash();
                        
                        return;
                    }
                }
                
                // Last case, the UpId is an OID
                if ( !OID.isOID(newId) || !attributeType.getOid().equals( newId ) )
                {
                    // The id is incorrect : this is not allowed 
                    throw new IllegalArgumentException( I18n.err( I18n.ERR_04455, id, attributeType.getName() ) );
                }
            }
        }

        this.id = newId;
        this.upId = id;
        
        // Compute the hashCode
        rehash();
    }

    
    /**
     * Get's the user provided identifier for this entry.  This is the value
     * that will be used as the identifier for the attribute within the
     * entry.  If this is a commonName attribute for example and the user
     * provides "COMMONname" instead when adding the entry then this is
     * the format the user will have that entry returned by the directory
     * server.  To do so we store this value as it was given and track it
     * in the attribute using this property.
     *
     * @return the user provided identifier for this attribute
     */
    public String getUpId()
    {
        return upId;
    }


    /**
     * Set the user provided ID. It will also set the ID, normalizing
     * the upId (removing spaces before and after, and lowercasing it)<br>
     * <br>
     * If the Attribute already has an AttributeType, then the upId must
     * be either the AttributeType name, or OID
     *
     * @param upId The attribute ID
     * @throws IllegalArgumentException If the ID is empty or null or
     * resolve to an empty value after being trimmed
     */
    public void setUpId( String upId )
    {
        setUpId( upId, null );
    }

    
    /**
     * Check that the upId is either a name or the OID of a given AT
     */
    private boolean areCompatible( String id, MutableAttributeTypeImpl 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);
    }
    

    /**
     * <p>
     * Set the user provided ID. If we have none, the upId is assigned
     * the attributetype's name. If it does not have any name, we will
     * use the OID.
     * </p>
     * <p>
     * If we have an upId and an AttributeType, they must be compatible. :
     *  - if the upId is an OID, it must be the AttributeType's OID
     *  - otherwise, its normalized form must be equals to ones of
     *  the attributeType's names.
     * </p>
     * <p>
     * In any case, the ATtributeType will be changed. The caller is responsible for
     * the present values to be compatoble with the new AttributeType.
     * </p>
     *
     * @param upId The attribute ID
     * @param attributeType The associated attributeType
     */
    public void setUpId( String upId, MutableAttributeTypeImpl 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 id = Strings.toLowerCase(trimmed);
        
        if ( attributeType == null )
        {
            if ( this.attributeType == null )
            {
                this.upId = upId;
                this.id = id;
                
                // Compute the hashCode
                rehash();

                return;
            }    
            else
            {
                if ( areCompatible( id, this.attributeType ) )
                {
                    this.upId = upId;
                    this.id = id;
                    
                    // Compute the hashCode
                    rehash();

                    return;
                }
                else
                {
                    return;
                }
            }
        }
        
        if ( Strings.isEmpty(id) )
        {
            this.attributeType = attributeType;
            this.upId = attributeType.getName();
            this.id = Strings.trim(this.upId);
            
            // Compute the hashCode
            rehash();

            return;
        }

        if ( areCompatible( id, attributeType ) )
        {
            this.upId = upId;
            this.id = id;
            this.attributeType = attributeType;
            
            // Compute the hashCode
            rehash();

            return;
        }

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


    /**
     * <p>
     * Tells if the attribute is Human Readable. 
     * </p>
     * <p>This flag is set by the caller, or implicitly when adding String 
     * values into an attribute which is not yet declared as Binary.
     * </p> 
     * @return
     */
    public boolean isHR()
    {
        return isHR != null ? isHR : false; 
    }

    
    /**
     * Checks to see if this attribute is valid along with the values it contains.
     *
     * @return true if the attribute and it's values are valid, false otherwise
     * @throws LdapException if there is a failure to check syntaxes of values
     */
    public boolean isValid() throws LdapException
    {
        if ( attributeType != null )
        {
            // First check if the attribute has more than one value
            // if the attribute is supposed to be SINGLE_VALUE
            if ( attributeType.isSingleValued() && ( values.size() > 1 ) )
            {
                return false;
            }

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

        for ( Value<?> value:values )
        {
            if ( !value.isValid() )
            {
                return false;
            }
        }

        return true;
    }


    /**
     * Checks to see if this attribute is valid along with the values it contains.
     *
     * @return true if the attribute and it's values are valid, false otherwise
     * @throws LdapException if there is a failure to check syntaxes of values
     */
    public boolean isValid( SyntaxChecker checker ) throws LdapException
    {
        for ( Value<?> value : values )
        {
            if ( !value.isValid( checker ) )
            {
                return false;
            }
        }

        return true;
    }


    /**
     * Adds some values to this attribute. If the new values are already present in
     * the attribute values, the method has no effect.
     * <p>
     * The new values are added at the end of list of values.
     * </p>
     * <p>
     * This method returns the number of values that were added.
     * </p>
     * <p>
     * If the value's type is different from the attribute's type,
     * a conversion is done. For instance, if we try to set some 
     * StringValue into a Binary attribute, we just store the UTF-8 
     * byte array encoding for this StringValue.
     * </p>
     * <p>
     * If we try to store some BinaryValue in a HR attribute, we try to 
     * convert those BinaryValue assuming they represent an UTF-8 encoded
     * String. Of course, if it's not the case, the stored value will
     * be incorrect.
     * </p>
     * <p>
     * It's the responsibility of the caller to check if the stored
     * values are consistent with the attribute's type.
     * </p>
     * <p>
     * The caller can set the HR flag in order to enforce a type for 
     * the current attribute, otherwise this type will be set while
     * adding the first value, using the value's type to set the flag.
     * </p>
     * <p>
     * <b>Note : </b>If the entry contains no value, and the unique added value
     * is a null length value, then this value will be considered as
     * a binary value.
     * </p>
     * @param vals some new values to be added which may be null
     * @return the number of added values, or 0 if none has been added
     */
    @edu.umd.cs.findbugs.annotations.SuppressWarnings( value="NP_LOAD_OF_KNOWN_NULL_VALUE", 
        justification="Validity of null depends on the checker")
    public int add( Value<?>... vals )
    {
        int nbAdded = 0;
        BinaryValue nullBinaryValue = null;
        StringValue nullStringValue = null;
        boolean nullValueAdded = false;
        
        if ( attributeType != null )
        {
            for ( Value<?> val:vals )
            {
                if ( attributeType.getSyntax().isHumanReadable() )
                {
                    if ( ( val == null ) || val.isNull() )
                    {
                        Value<String> nullSV = new StringValue( attributeType, (String)null );
                        
                        if ( values.add( nullSV ) )
                        {
                            nbAdded++;
                        }
                    }
                    else if ( val instanceof StringValue)
                    {
                        StringValue stringValue = (StringValue)val;
                        
                        if ( stringValue.getAttributeType() == null )
                        {
                            stringValue.apply( attributeType );
                        }
                        
                        if ( values.add( val ) )
                        {
                            nbAdded++;
                        }
                    }
                    else
                    {
                        String message = I18n.err( I18n.ERR_04451 );
                        LOG.error( message );
                    }
                }
                else
                {
                    if ( val == null )
                    {
                        if ( attributeType.getSyntax().getSyntaxChecker().isValidSyntax( val ) )
                        {
                            Value<byte[]> nullSV = new BinaryValue( attributeType, (byte[])null );
                            
                            if ( values.add( nullSV ) )
                            {
                                nbAdded++;
                            }
                        }
                        else
                        {
                            String message = I18n.err( I18n.ERR_04452 );
                            LOG.error( message );
                        }
                    }
                    else
                    {
                        if ( val instanceof BinaryValue )
                        {
                            BinaryValue binaryValue = (BinaryValue)val;
                            
                            if ( binaryValue.getAttributeType() == null )
                            {
                                binaryValue = new BinaryValue( attributeType, val.getBytes() ); 
                            }
        
                            if ( values.add( binaryValue ) )
                            {
                                nbAdded++;
                            }
                        }
                        else
                        {
                            String message = I18n.err( I18n.ERR_04452 );
                            LOG.error( message );
                        }
                    }
                }
            }
        }
        else
        {
            for ( Value<?> val:vals )
            {
                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;
    }


    /**
     * @see EntryAttribute#add(String...)
     */
    public int add( String... vals )
    {
        int nbAdded = 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:vals )
                {
                    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.error( I18n.err( I18n.ERR_04486_VALUE_ALREADY_EXISTS, val, upId ) );
                    }
                }
            }
            else
            {
                // The attribute is binary. Transform the String to byte[]
                for ( String val:vals )
                {
                    byte[] valBytes = null;
                    
                    if ( val != null )
                    {
                        valBytes = Strings.getBytesUtf8(val);
                    }
                    
                    Value<byte[]> value = createBinaryValue( attributeType, valBytes );
                    
                    if ( value == null )
                    {
                        // The value can't be normalized or is invalid : we don't add it.
                        LOG.error( I18n.err( I18n.ERR_04449, val ) );
                        continue;
                    }
                    
                    // Now call the add(Value) method
                    if ( add( value ) == 1 )
                    {
                        nbAdded++;
                    }
                }
            }
        }
        else
        {
            if ( isHR )
            {
                for ( String val:vals )
                {
                    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.error( I18n.err( I18n.ERR_04486_VALUE_ALREADY_EXISTS, val, upId ) );
                    }
                }
            }
            else
            {
                // The attribute is binary. Transform the String to byte[]
                for ( String val:vals )
                {
                    byte[] valBytes = null;
                    
                    if ( val != null )
                    {
                        valBytes = Strings.getBytesUtf8(val);
                    }
                    
                    Value<byte[]> value = createBinaryValue( attributeType, valBytes );
                    
                    if ( value == null )
                    {
                        // The value can't be normalized or is invalid : we don't add it.
                        LOG.error( I18n.err( I18n.ERR_04449, val ) );
                        continue;
                    }
                    
                    // Now call the add(Value) method
                    if ( add( value ) == 1 )
                    {
                        nbAdded++;
                    }
                }
            }
        }
        
        return nbAdded;
    }    
    
    
    /**
     * Adds some values to this attribute. If the new values are already present in
     * the attribute values, the method has no effect.
     * <p>
     * The new values are added at the end of list of values.
     * </p>
     * <p>
     * This method returns the number of values that were added.
     * </p>
     * If the value's type is different from the attribute's type,
     * a conversion is done. For instance, if we try to set some String
     * into a Binary attribute, we just store the UTF-8 byte array 
     * encoding for this String.
     * If we try to store some byte[] in a HR attribute, we try to 
     * convert those byte[] assuming they represent an UTF-8 encoded
     * String. Of course, if it's not the case, the stored value will
     * be incorrect.
     * <br>
     * It's the responsibility of the caller to check if the stored
     * values are consistent with the attribute's type.
     * <br>
     * The caller can set the HR flag in order to enforce a type for 
     * the current attribute, otherwise this type will be set while
     * adding the first value, using the value's type to set the flag.
     *
     * @param vals some new values to be added which may be null
     * @return the number of added values, or 0 if none has been added
     */
    public int add( byte[]... vals )
    {
        int nbAdded = 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:vals )
            {
                Value<byte[]> value = null;
                
                if ( attributeType == null )
                {
                    value = new BinaryValue( val );
                }
                else
                {
                    value = new BinaryValue( attributeType, val );
                    
                    try
                    {
                        value.normalize();
                    }
                    catch( LdapException ne )
                    {
                        // The value can't be normalized : we don't add it.
                        LOG.error( I18n.err( I18n.ERR_04449, Strings.dumpBytes(val) ) );
                        return 0;
                    }
                }
                
                if ( add( value ) != 0 )
                {
                    nbAdded++;
                }
                else
                {
                    LOG.error( 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;
    }    
    
    
    /**
     * Remove all the values from this attribute.
     */
    public void clear()
    {
        values.clear();
    }


    /**
     * <p>
     * Indicates whether the specified values are some of the attribute's values.
     * </p>
     * <p>
     * If the Attribute is HR, the binary values will be converted to String before
     * being checked.
     * </p>
     *
     * @param vals the values
     * @return true if this attribute contains all the values, otherwise false
     */
    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.isBinary() )
                    {
                        if ( !values.contains( val ) )
                        {
                            return false;
                        }
                    }
                    else
                    {
                        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
        {
            // 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;
                        
                        if ( stringValue.getAttributeType() == null )
                        {
                            stringValue.apply( attributeType );
                        }
                        
                        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;
    }


    /**
     * <p>
     * Indicates whether the specified values are some of the attribute's values.
     * </p>
     * <p>
     * If the Attribute is not HR, the values will be converted to byte[]
     * </p>
     *
     * @param vals the values
     * @return true if this attribute contains all the values, otherwise false
     */
    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 )
                {
                    
                    if ( !contains( new StringValue( val ) ) )
                    {
                        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 )
                {
                    StringValue value = new StringValue( attributeType, val );
                    
                    if ( !values.contains( value ) )
                    {
                        return false;
                    }
                }
                
                return true;
            }
            else
            {
                return false;
            }
        }
        
        return true;
    }
    
    
    /**
     * <p>
     * Indicates whether the specified values are some of the attribute's values.
     * </p>
     * <p>
     * If the Attribute is HR, the values will be converted to String
     * </p>
     *
     * @param vals the values
     * @return true if this attribute contains all the values, otherwise false
     */
    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 )
                {
                    BinaryValue value = new BinaryValue( attributeType, val );
                    
                    try
                    {
                        value.normalize();
                    }
                    catch ( LdapException ne )
                    {
                        return false;
                    }
                    
                    if ( !values.contains( value ) )
                    {
                        return false;
                    }
                }
                
                return true;
            }
            else
            {
                return false;
            }
        }
        
        return true;
    }
    
    
    /**
     * @see EntryAttribute#contains(Object...)
     */
    public boolean contains( Object... vals )
    {
        boolean isHR = true;
        boolean seen = false;
        
        // Iterate through all the values, and quit if we 
        // don't find one in the values
        for ( Object val:vals )
        {
            if ( ( val instanceof String ) ) 
            {
                if ( !seen )
                {
                    isHR = true;
                    seen = true;
                }

                if ( isHR )
                {
                    if ( !contains( (String)val ) )
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            else
            {
                if ( !seen )
                {
                    isHR = false;
                    seen = true;
                }

                if ( !isHR )
                {
                    if ( !contains( (byte[])val ) )
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
        }
        
        return true;
    }

    
    /**
     * <p>
     * Get the first value of this attribute. If there is none, 
     * null is returned.
     * </p>
     * <p>
     * Note : even if we are storing values into a Set, one can assume
     * the values are ordered following the insertion order.
     * </p>
     * <p> 
     * This method is meant to be used if the attribute hold only one value.
     * </p>
     * 
     *  @return The first value for this attribute.
     */
    public Value<?> get()
    {
        if ( values.isEmpty() )
        {
            return null;
        }
        
        return values.iterator().next();
    }


    /**
     * <p>
     * Get the nth value of this attribute. If there is none, 
     * null is returned.
     * </p>
     * <p>
     * Note : even if we are storing values into a Set, one can assume
     * the values are ordered following the insertion order.
     * </p>
     * <p> 
     * 
     * @param i the index  of the value to get
     *  @return The nth value for this attribute.
     */
    public Value<?> get( int i )
    {
        if ( values.size() < i )
        {
            return null;
        }
        else
        {
            int n = 0;
            
            for ( Value<?> value:values )
            {
                if ( n == i )
                {
                    return value;
                }
                
                n++;
            }
        }
        
        // fallback to 
        return null;
    }
    
    
    /**
     * Returns an iterator over all the attribute's values.
     * <p>
     * The effect on the returned enumeration of adding or removing values of
     * the attribute is not specified.
     * </p>
     * <p>
     * This method will throw any <code>LdapException</code> that occurs.
     * </p>
     *
     * @return an enumeration of all values of the attribute
     */
    public Iterator<Value<?>> getAll()
    {
        return iterator();
    }


    /**
     * Retrieves the number of values in this attribute.
     *
     * @return the number of values in this attribute, including any values
     * wrapping a null value if there is one
     */
    public int size()
    {
        return values.size();
    }


    /**
     * <p>
     * Removes all the  values that are equal to the given values.
     * </p>
     * <p>
     * Returns true if all the values are removed.
     * </p>
     * <p>
     * If the attribute type is HR and some value which are not String, we
     * will convert the values first (same thing for a non-HR attribute).
     * </p>
     *
     * @param vals the values to be removed
     * @return true if all the values are removed, otherwise false
     */
    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;
                        
                        if ( stringValue.getAttributeType() == null )
                        {
                            stringValue.apply( attributeType );
                        }
                        
                        removed &= values.remove( stringValue );
                    }
                    else
                    {
                        removed = false;
                    }
                }
            }
            else
            {
                for ( Value<?> val:vals )
                {
                    if ( val instanceof BinaryValue )
                    {
                        BinaryValue binaryValue = (BinaryValue)val;
                        
                        if ( binaryValue.getAttributeType() == null )
                        {
                            binaryValue.apply( attributeType );
                        }
                        
                        removed &= values.remove( binaryValue );
                    }
                    else
                    {
                        removed = false;
                    }
                }
            }
        }
        
        return removed;
    }


    /**
     * <p>
     * Removes all the  values that are equal to the given values.
     * </p>
     * <p>
     * Returns true if all the values are removed.
     * </p>
     * <p>
     * If the attribute type is HR, then the values will be first converted
     * to String
     * </p>
     *
     * @param vals the values to be removed
     * @return true if all the values are removed, otherwise false
     */
    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 ) 
            {
                for ( byte[] val:vals )
                {
                    BinaryValue value = new BinaryValue( attributeType, val );
                    removed &= values.remove( value );
                }
            }
            else
            {
                removed = false;
            }
        }
        
        return removed;
    }


    /**
     * Removes all the  values that are equal to the given values.
     * <p>
     * Returns true if all the values are removed.
     * </p>
     * <p>
     * If the attribute type is not HR, then the values will be first converted
     * to byte[]
     * </p>
     *
     * @param vals the values to be removed
     * @return true if all the values are removed, otherwise false
     */
    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 )
                {
                    StringValue value = new StringValue( attributeType, val );
                    removed &= values.remove( value );
                }
            }
            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();
    }
    
    
    /*
     * Puts some values to this attribute.
     * <p>
     * The new values will replace the previous values.
     * </p>
     * <p>
     * This method returns the number of values that were put.
     * </p>
     *
     * @param val some values to be put which may be null
     * @return the number of added values, or 0 if none has been added
     *
    public int put( String... vals )
    {
        values.clear();
        return add( vals );
    }
    
    
    /**
     * Puts some values to this attribute.
     * <p>
     * The new values will replace the previous values.
     * </p>
     * <p>
     * This method returns the number of values that were put.
     * </p>
     *
     * @param val some values to be put which may be null
     * @return the number of added values, or 0 if none has been added
     *
    public int put( byte[]... vals )
    {
        values.clear();
        return add( vals );
    }

    
    /**
     * Puts some values to this attribute.
     * <p>
     * The new values are replace the previous values.
     * </p>
     * <p>
     * This method returns the number of values that were put.
     * </p>
     *
     * @param val some values to be put which may be null
     * @return the number of added values, or 0 if none has been added
     *
    public int put( Value<?>... vals )
    {
        values.clear();
        return add( vals );
    }
    
    
    /**
     * <p>
     * Puts a list of values into this attribute.
     * </p>
     * <p>
     * The new values will replace the previous values.
     * </p>
     * <p>
     * This method returns the number of values that were put.
     * </p>
     *
     * @param vals the values to be put
     * @return the number of added values, or 0 if none has been added
     *
    public int put( List<Value<?>> vals )
    {
        values.clear();
        
        // Transform the List to an array
        Value<?>[] valArray = new Value<?>[vals.size()];
        return add( vals.toArray( valArray ) );
    }
    */
    


    /**
     * Get the attribute type associated with this ServerAttribute.
     *
     * @return the attributeType associated with this entry attribute
     */
    public MutableAttributeTypeImpl getAttributeType()
    {
        return attributeType;
    }
    
    
    /**
     * <p>
     * Set the attribute type associated with this ServerAttribute.
     * </p>
     * <p>
     * The current attributeType will be replaced. It is the responsibility of
     * the caller to insure that the existing values are compatible with the new
     * AttributeType
     * </p>
     *
     * @param attributeType the attributeType associated with this entry attribute
     */
    public void setAttributeType( MutableAttributeTypeImpl attributeType )
    {
        if ( attributeType == null )
        {
            throw new IllegalArgumentException( "The AttributeType parameter should not be null" );
        }

        this.attributeType = attributeType;
        setUpId( null, attributeType );
        
        isHR = attributeType.getSyntax().isHumanReadable();
        
        // Compute the hashCode
        rehash();
    }
    
    
    /**
     * <p>
     * Check if the current attribute type is of the expected attributeType
     * </p>
     * <p>
     * This method won't tell if the current attribute is a descendant of 
     * the attributeType. For instance, the "CN" serverAttribute will return
     * false if we ask if it's an instance of "Name". 
     * </p> 
     *
     * @param attributeId The AttributeType ID to check
     * @return True if the current attribute is of the expected attributeType
     * @throws LdapInvalidAttributeValueException If there is no AttributeType
     */
    public boolean instanceOf( String attributeId ) throws LdapInvalidAttributeValueException
    {
        String trimmedId = Strings.trim(attributeId);
        
        if ( Strings.isEmpty(trimmedId) )
        {
            return false;
        }
        
        String normId = Strings.lowerCaseAscii(trimmedId);
        
        for ( String name:attributeType.getNames() )
        {
            if ( normId.equalsIgnoreCase( name ) )
            {
                return true;
            }
        }
        
        return normId.equalsIgnoreCase( attributeType.getOid() );
    }


    //-------------------------------------------------------------------------
    // 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();
        }
        
        /*
        // We have to sort the values if we wnt to correctly compare two Attributes
        if ( isHR )
        {
            SortedSet<String> sortedSet = new TreeSet<String>();

            for ( Value<?> value:values )
            {
                sortedSet.add( (String)value.getNormalizedValueReference() );
            }
            
            for ( String value:sortedSet )
            {
                h = h*17 + value.hashCode();
            }
        }
        else
        {
            SortedSet<byte[]> sortedSet = new TreeSet<byte[]>();
            
            for ( Value<?> value:values )
            {
                sortedSet.add( (byte[])value.getNormalizedValueReference() );
            }
            
            for ( byte[] value:sortedSet )
            {
                h = h*17 + ArrayUtils.hashCode( value );
            }
        }
        */
        
        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 EntryAttribute ) )
        {
            return false;
        }
        
        EntryAttribute other = (EntryAttribute)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 ( isHR() !=  other.isHR() )
        {
            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() );
    }
    
    
    /**
     * @see Cloneable#clone()
     */
    public EntryAttribute clone()
    {
        try
        {
            DefaultEntryAttribute attribute = (DefaultEntryAttribute)super.clone();
            attribute.setUpId( upId );
            
            attribute.values = new LinkedHashSet<Value<?>>( values.size() );
            
            for ( Value<?> value:values )
            {
                attribute.values.add( value.clone() );
            }
            
            return attribute;
        }
        catch ( CloneNotSupportedException cnse )
        {
            return null;
        }
    }
    
    
    /**
     * @see Object#toString() 
     */
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        
        if ( ( values != null ) && ( values.size() != 0 ) )
        {
            for ( Value<?> value:values )
            {
                sb.append( "    " ).append( upId ).append( ": " );
                
                if ( value.isNull() )
                {
                    sb.append( "''" );
                }
                else
                {
                    sb.append( value );
                }
                
                sb.append( '\n' );
            }
        }
        else
        {
            sb.append( "    " ).append( upId ).append( ": (null)\n" );
        }
        
        return sb.toString();
    }


    /**
     * This is the place where we serialize attributes, and all theirs
     * elements. 
     * 
     * The inner structure is the same as the client attribute, but we can't call
     * it as we won't be able to serialize the serverValues
     */
    public void serialize( ObjectOutput out ) throws IOException
    {
        // Write the UPId (the id will be deduced from the upID)
        Unicode.writeUTF(out, 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, using the correct method
                if ( value instanceof StringValue)
                {
                    StringValue.serialize( value, out );
                }
                else
                {
                    BinaryValue.serialize( value, out );
                }
            }
        }
    }

    
    /**
     * {@inheritDoc}
     */
    public void deserialize( ObjectInput in ) throws IOException, ClassNotFoundException
    {
        // Read the ID and the UPId
        upId = Unicode.readUTF(in);
        
        // 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 = StringValue.deserialize( null, in );
                }
                else
                {
                    value  = BinaryValue.deserialize( null, in );
                }
                
                try
                {
                    value.normalize();
                }
                catch ( LdapException ne )
                {
                    // Do nothing...
                }
                    
                values.add( value );
            }
        }
    }
    
    
    /**
     * This is the place where we serialize attributes, and all theirs
     * elements. 
     * 
     * The inner structure is :
     * 
     * {@inheritDoc}
     */
    public void writeExternal( ObjectOutput out ) throws IOException
    {
        // Write the UPId (the id will be deduced from the upID)
        Unicode.writeUTF(out, 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
                out.writeObject( value );
            }
        }
        
        out.flush();
    }

    
    /**
     * {@inheritDoc}
     */
    public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
    {
        // Read the ID and the UPId
        upId = Unicode.readUTF(in);
        
        // 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++ )
            {
                values.add( (Value<?>)in.readObject() );
            }
        }
    }
}
