/*
 *  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.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Arrays;

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.LdapComparator;
import org.apache.directory.api.ldap.model.schema.LdapSyntax;
import org.apache.directory.api.ldap.model.schema.MatchingRule;
import org.apache.directory.api.ldap.model.schema.Normalizer;
import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
import org.apache.directory.api.ldap.model.schema.comparators.StringComparator;
import org.apache.directory.api.ldap.model.schema.normalizers.NoOpNormalizer;
import org.apache.directory.api.util.Serialize;
import org.apache.directory.api.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * A Class for wrapping attribute values stored into an Entry Attribute, or a AVA.
 * 
 * We keep the value as byte[] unless we need to convert them to a String (if we have
 * a HR Value).
 * 
 * The serialized Value will be stored as :
 * 
 * <pre>
 *  +---------+
 *  | boolean | isHR flag
 *  +---------+
 *  | boolean | TRUE if the value is not null, FALSE otherwise
 *  +---------+
 * [|   int   |]  If the previous flag is TRUE, the length of the value
 * [+---------+]
 * [| byte[]  |] The value itself
 * [+---------+]
 *  | boolean | TRUE if we have a prepared String
 *  +---------+
 * [| String  |] The prepared String if we have it
 * [+---------+]
 * </pre>
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class Value implements Cloneable, Externalizable, Comparable<Value>
{
    /** Used for serialization */
    private static final long serialVersionUID = 2L;

    /** logger for reporting errors that might not be handled properly upstream */
    private static final Logger LOG = LoggerFactory.getLogger( Value.class );

    /** reference to the attributeType associated with the value */
    private transient AttributeType attributeType;

    /** the User Provided value if it's a String */
    private String upValue;

    /** the prepared representation of the user provided value if it's a String */
    private String normValue;

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

    /** The UTF-8 bytes for this value (we use the UP value) */
    private byte[] bytes;

    /** Two flags used to tell if the value is HR or not in serialization */
    private boolean isHR = true;
    
    /** A default comparator if we don't have an EQUALITY MR */
    private static StringComparator stringComparator = new StringComparator( null );
    
    // -----------------------------------------------------------------------
    // Constructors
    // -----------------------------------------------------------------------
    /**
     * Creates a Value with an initial user provided String value.
     *
     * @param upValue the value to wrap. It can be null
     */
    public Value( String upValue )
    {
        this.upValue = upValue;
        
        // We can't normalize the value, we store it as is
        normValue = upValue;
        
        if ( upValue != null )
        {
            bytes = Strings.getBytesUtf8( upValue );
        }
        
        hashCode();
    }
    
    
    /**
     * Creates a Value with an initial user provided binary value.
     *
     * @param value the binary value to wrap which may be null, or a zero length byte array
     */
    public Value( byte[] value )
    {
        if ( value != null )
        {
            bytes = new byte[value.length];
            System.arraycopy( value, 0, bytes, 0, value.length );
        }
        else
        {
            bytes = null;
        }
        
        isHR = false;

        hashCode();
    }


    /**
     * Creates a schema aware binary Value with an initial value.
     *
     * @param attributeType the schema type associated with this Value
     * @param upValue the value to wrap
     * @throws LdapInvalidAttributeValueException If the added value is invalid accordingly
     * to the schema
     */
    public Value( AttributeType attributeType, byte[] upValue ) throws LdapInvalidAttributeValueException
    {
        init( attributeType );
        
        if ( upValue != null )
        {
            bytes = new byte[upValue.length];
            System.arraycopy( upValue, 0, bytes, 0, upValue.length );

            if ( isHR )
            {
                this.upValue = Strings.utf8ToString( upValue );
            }
        }
        else
        {
            bytes = null;
        }
        
        if ( ( attributeType != null ) && !attributeType.isRelaxed() )
        {
            // Check the value
            SyntaxChecker syntaxChecker = attributeType.getSyntax().getSyntaxChecker();

            if ( syntaxChecker != null )
            {
                if ( !syntaxChecker.isValidSyntax( bytes ) )
                {
                    throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, 
                        I18n.err( I18n.ERR_13246_INVALID_VALUE_PER_SYNTAX ) );
                }
            }
            else
            {
                // We should always have a SyntaxChecker
                throw new IllegalArgumentException( I18n.err( I18n.ERR_13219_NULL_SYNTAX_CHECKER, normValue ) );
            }
        }

        hashCode();
    }
    
    
    private void init( AttributeType attributeType )
    {
        if ( attributeType != null )
        {
            if ( attributeType.getSyntax() == null )
            {
                // Some broken LDAP servers do not have proper syntax definitions, default to HR
                // Log this on trace level only. Otherwise we get logs full of errors when working
                // with AD and similar not-really-LDAP-compliant servers.
                if ( LOG.isTraceEnabled() )
                {
                    LOG.trace( I18n.err( I18n.ERR_13225_NO_SYNTAX ) );
                }
                
                isHR = true;
            }
            else
            {
                isHR = attributeType.getSyntax().isHumanReadable();
            }
        }
        else
        {
            if ( LOG.isWarnEnabled() )
            {
                LOG.warn( I18n.msg( I18n.MSG_13202_AT_IS_NULL ) );
            }
        }
        
        this.attributeType = attributeType;
    }


    /**
     * Creates a schema aware binary Value with an initial value. This method is
     * only to be used by deserializers.
     *
     * @param attributeType the schema type associated with this Value
     */
    /* Package protected*/ Value( AttributeType attributeType )
    {
        init( attributeType );
    }
    
    
    /**
     * Creates a schema aware StringValue with an initial user provided String value.
     *
     * @param attributeType the schema type associated with this StringValue
     * @param upValue the value to wrap
     * @throws LdapInvalidAttributeValueException If the added value is invalid accordingly
     * to the schema
     */
    public Value( AttributeType attributeType, String upValue ) throws LdapInvalidAttributeValueException
    {
        init( attributeType );
        this.upValue = upValue;
        
        if ( upValue != null )
        {
            bytes = Strings.getBytesUtf8( upValue );
        }
        else
        {
            bytes = null;
        }
        
        try
        {
            computeNormValue();
        }
        catch ( LdapException le )
        {
            LOG.error( le.getMessage() );
            throw new IllegalArgumentException( I18n.err( I18n.ERR_13247_INVALID_VALUE_CANT_NORMALIZE, upValue ) );
        }
        
        if ( !attributeType.isRelaxed() )
        {
            // Check the value
            LdapSyntax syntax = attributeType.getSyntax();
            
            if ( ( syntax != null ) && ( syntax.getSyntaxChecker() != null ) ) 
            {
                if ( !attributeType.getSyntax().getSyntaxChecker().isValidSyntax( upValue ) )
                {
                    throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, 
                        I18n.err( I18n.ERR_13246_INVALID_VALUE_PER_SYNTAX ) );
                }
            }
            else
            {
                // We should always have a SyntaxChecker
                throw new IllegalArgumentException( I18n.err( I18n.ERR_13219_NULL_SYNTAX_CHECKER, normValue ) );
            }
        }
        
        hashCode();
    }
    
    
    /**
     * Creates a schema aware StringValue with an initial user provided String value and 
     * its normalized Value
     *
     * @param attributeType the schema type associated with this StringValue
     * @param upValue the value to wrap
     * @param normValue the normalized value to wrap
     * @throws LdapInvalidAttributeValueException If the added value is invalid accordingly
     * to the schema
     */
    public Value( AttributeType attributeType, String upValue, String normValue ) throws LdapInvalidAttributeValueException
    {
        init( attributeType );
        this.upValue = upValue;
        
        if ( upValue != null )
        {
            bytes = Strings.getBytesUtf8( upValue );
        }
        else
        {
            bytes = null;
        }
        
        this.normValue = normValue;
        
        if ( !attributeType.isRelaxed() )
        {
            // Check the value
            if ( attributeType.getSyntax().getSyntaxChecker() != null )
            {
                if ( !attributeType.getSyntax().getSyntaxChecker().isValidSyntax( upValue ) )
                {
                    throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, 
                        I18n.err( I18n.ERR_13246_INVALID_VALUE_PER_SYNTAX ) );
                }
            }
            else
            {
                // We should always have a SyntaxChecker
                throw new IllegalArgumentException( I18n.err( I18n.ERR_13219_NULL_SYNTAX_CHECKER, normValue ) );
            }
        }
        
        hashCode();
    }


    /**
     * Creates a Value from an existing Value with an AttributeType
     *
     * @param attributeType the schema attribute type associated with this StringValue
     * @param value the original Value
     * @throws LdapInvalidAttributeValueException If the value is invalid
     */
    public Value( AttributeType attributeType, Value value ) throws LdapInvalidAttributeValueException
    {
        init( attributeType );
        
        if ( isHR )
        {
            if ( value.isHR )
            {
                this.upValue = value.upValue;
            }
            else
            {
                this.upValue = Strings.utf8ToString( value.bytes );
            }
        }

        try
        {
            computeNormValue();
        }
        catch ( LdapException le )
        {
            LOG.error( le.getMessage() );
            throw new IllegalArgumentException( I18n.err( I18n.ERR_13247_INVALID_VALUE_CANT_NORMALIZE, upValue ) );
        }
        
        // Check the normValue
        if ( !attributeType.isRelaxed() )
        {
            // Check the value
            if ( attributeType.getSyntax().getSyntaxChecker() != null )
            {
                attributeType.getSyntax().getSyntaxChecker().isValidSyntax( value.normValue );
            }
            else
            {
                // We should always have a SyntaxChecker
                throw new IllegalArgumentException( I18n.err( I18n.ERR_13219_NULL_SYNTAX_CHECKER, normValue ) );
            }
        }
            
        // We have to copy the byte[], they are just referenced by super.clone()
        if ( value.bytes != null )
        {
            bytes = new byte[value.bytes.length];
            System.arraycopy( value.bytes, 0, bytes, 0, value.bytes.length );
        }

        hashCode();
    }

    
    /**
     * Create a Value with an AttributeType. It will not contain anything and will only be used by
     * the deserializer.
     * 
     * @param attributeType The ATttributeType to use
     * @return An instance of value.
     */
    public static Value createValue( AttributeType attributeType )
    {
        return new Value( attributeType );
    }
    

    /**
     * Clone a Value
     * 
     * @return A cloned value
     */
    @Override
    public Value clone()
    {
        try
        {
            Value clone = ( Value ) super.clone();
            
            if ( isHR )
            {
                return clone;
            }
            else
            {
                // We have to copy the byte[], they are just referenced by suoer.clone()
                if ( bytes != null )
                {
                    clone.bytes = new byte[bytes.length];
                    System.arraycopy( bytes, 0, clone.bytes, 0, bytes.length );
                }
            }
            
            return clone;
        }
        catch ( CloneNotSupportedException cnse )
        {
            // Do nothing
            return null;
        }
    }


    /**
     * Check if the contained value is null or not
     * 
     * @return <code>true</code> if the inner value is null.
     */
    public boolean isNull()
    {
        if ( isHR )
        {
            return upValue == null;
        }
        else
        {
            return bytes == null;
        }
    }


    /**
     * Get the associated AttributeType
     * 
     * @return The AttributeType
     */
    public AttributeType getAttributeType()
    {
        return attributeType;
    }


    /**
     * Check if the value is stored into an instance of the given
     * AttributeType, or one of its ascendant.
     * 
     * For instance, if the Value is associated with a CommonName,
     * checking for Name will match.
     * 
     * @param attributeType The AttributeType we are looking at
     * @return <code>true</code> if the value is associated with the given
     * attributeType or one of its ascendant
     */
    public boolean isInstanceOf( AttributeType attributeType )
    {
        return ( attributeType != null )
            && ( this.attributeType.equals( attributeType ) || this.attributeType.isDescendantOf( attributeType ) );
    }

    
    
    
    /**
     * @return The value as an escaped String
     */
    public String getEscaped()
    {
        if ( Strings.isEmpty( bytes ) )
        {
            return Strings.EMPTY_STRING;
        }

        StringBuilder sb = new StringBuilder();
        
        boolean leadChar = true;
        
        for ( int pos = 0; pos < bytes.length; pos++  )
        {
            boolean trailChar = pos == bytes.length - 1;
            byte b = bytes[pos];

            switch ( b )
            {
                case 0x00 :
                    sb.append( "\\00" );
                    break;

                case 0x01 :
                case 0x02 :
                case 0x03 :
                case 0x04 :
                case 0x05 :
                case 0x06 :
                case 0x07 :
                case 0x08 :
                case 0x09 :
                case 0x0A :
                case 0x0B :
                case 0x0C :
                case 0x0D :
                case 0x0E :
                case 0x0F :
                case 0x10 :
                case 0x11 :
                case 0x12 :
                case 0x13 :
                case 0x14 :
                case 0x15 :
                case 0x16 :
                case 0x17 :
                case 0x18 :
                case 0x19 :
                case 0x1A :
                case 0x1B :
                case 0x1C :
                case 0x1D :
                case 0x1E :
                case 0x1F :
                    sb.append( ( char ) b );
                    break;
                    
                case 0x20 :
                    if ( leadChar || trailChar )
                    {
                        sb.append( "\\ " );
                    }
                    else
                    {
                        sb.append( ( char ) b );
                    }
                    
                    break;
                    
                case 0x21 :
                    sb.append( ( char ) b );
                    break;
                    
                    
                case 0x22 :
                    sb.append( "\\\"" );
                    break;

                case 0x23 :
                    if ( leadChar )
                    {
                        sb.append( "\\#" );
                    }
                    else
                    {
                        sb.append( '#' );
                    }
                    
                    break;

                case 0x24 :
                case 0x25 :
                case 0x26 :
                case 0x27 :
                case 0x28 :
                case 0x29 :
                case 0x2A :
                    sb.append( ( char ) b );
                    break;
                    
                case 0x2B :
                    sb.append( "\\+" );
                    break;

                case 0x2C :
                    sb.append( "\\," );
                    break;

                case 0x2D :
                case 0x2E :
                case 0x2F :
                case 0x30 :
                case 0x31 :
                case 0x32 :
                case 0x33 :
                case 0x34 :
                case 0x35 :
                case 0x36 :
                case 0x37 :
                case 0x38 :
                case 0x39 :
                case 0x3A :
                    sb.append( ( char ) b );
                    break;
                    
                case 0x3B :
                    sb.append( "\\;" );
                    break;

                case 0x3C :
                    sb.append( "\\<" );
                    break;

                case 0x3D :
                    sb.append( ( char ) b );
                    break;
                    
                case 0x3E :
                    sb.append( "\\>" );
                    break;
                
                case 0x3F :
                case 0x40 :
                case 0x41 :
                case 0x42 :
                case 0x43 :
                case 0x44 :
                case 0x45 :
                case 0x46 :
                case 0x47 :
                case 0x48 :
                case 0x49 :
                case 0x4A :
                case 0x4B :
                case 0x4C :
                case 0x4D :
                case 0x4E :
                case 0x4F :
                case 0x50 :
                case 0x51 :
                case 0x52 :
                case 0x53 :
                case 0x54 :
                case 0x55 :
                case 0x56 :
                case 0x57 :
                case 0x58 :
                case 0x59 :
                case 0x5A :
                case 0x5B :
                    sb.append( ( char ) b );
                    break;
                    
                case 0x5C :
                    sb.append( "\\\\" );
                    break;

                case 0x5D :
                case 0x5E :
                case 0x5F :
                case 0x60 :
                case 0x61 :
                case 0x62 :
                case 0x63 :
                case 0x64 :
                case 0x65 :
                case 0x66 :
                case 0x67 :
                case 0x68 :
                case 0x69 :
                case 0x6A :
                case 0x6B :
                case 0x6C :
                case 0x6D :
                case 0x6E :
                case 0x6F :
                case 0x70 :
                case 0x71 :
                case 0x72 :
                case 0x73 :
                case 0x74 :
                case 0x75 :
                case 0x76 :
                case 0x77 :
                case 0x78 :
                case 0x79 :
                case 0x7A :
                case 0x7B :
                case 0x7C :
                case 0x7D :
                case 0x7E :
                case 0x7F :
                    sb.append( ( char ) b );
                    break;

                // Between 0x80 and 0xC1, this is an octet
                case ( byte ) 0x80 :
                case ( byte ) 0x81 :
                case ( byte ) 0x82 :
                case ( byte ) 0x83 :
                case ( byte ) 0x84 :
                case ( byte ) 0x85 :
                case ( byte ) 0x86 :
                case ( byte ) 0x87 :
                case ( byte ) 0x88 :
                case ( byte ) 0x89 :
                case ( byte ) 0x8A :
                case ( byte ) 0x8B :
                case ( byte ) 0x8C :
                case ( byte ) 0x8D :
                case ( byte ) 0x8E :
                case ( byte ) 0x8F :
                case ( byte ) 0x90 :
                case ( byte ) 0x91 :
                case ( byte ) 0x92 :
                case ( byte ) 0x93 :
                case ( byte ) 0x94 :
                case ( byte ) 0x95 :
                case ( byte ) 0x96 :
                case ( byte ) 0x97 :
                case ( byte ) 0x98 :
                case ( byte ) 0x99 :
                case ( byte ) 0x9A :
                case ( byte ) 0x9B :
                case ( byte ) 0x9C :
                case ( byte ) 0x9D :
                case ( byte ) 0x9E :
                case ( byte ) 0x9F :
                case ( byte ) 0xA0 :
                case ( byte ) 0xA1 :
                case ( byte ) 0xA2 :
                case ( byte ) 0xA3 :
                case ( byte ) 0xA4 :
                case ( byte ) 0xA5 :
                case ( byte ) 0xA6 :
                case ( byte ) 0xA7 :
                case ( byte ) 0xA8 :
                case ( byte ) 0xA9 :
                case ( byte ) 0xAA :
                case ( byte ) 0xAB :
                case ( byte ) 0xAC :
                case ( byte ) 0xAD :
                case ( byte ) 0xAE :
                case ( byte ) 0xAF :
                case ( byte ) 0xB0 :
                case ( byte ) 0xB1 :
                case ( byte ) 0xB2 :
                case ( byte ) 0xB3 :
                case ( byte ) 0xB4 :
                case ( byte ) 0xB5 :
                case ( byte ) 0xB6 :
                case ( byte ) 0xB7 :
                case ( byte ) 0xB8 :
                case ( byte ) 0xB9 :
                case ( byte ) 0xBA :
                case ( byte ) 0xBB :
                case ( byte ) 0xBC :
                case ( byte ) 0xBD :
                case ( byte ) 0xBE :
                case ( byte ) 0xBF :
                case ( byte ) 0xC0 :
                case ( byte ) 0xC1 :
                    sb.append( '\\' ).append( Strings.byteToString( b ) );
                    break;

                // Between 0xC2 and 0xDF, we may have a UTF-2 char
                case ( byte ) 0xC2 :
                case ( byte ) 0xC3 :
                case ( byte ) 0xC4 :
                case ( byte ) 0xC5 :
                case ( byte ) 0xC6 :
                case ( byte ) 0xC7 :
                case ( byte ) 0xC8 :
                case ( byte ) 0xC9 :
                case ( byte ) 0xCA :
                case ( byte ) 0xCB :
                case ( byte ) 0xCC :
                case ( byte ) 0xCD :
                case ( byte ) 0xCE :
                case ( byte ) 0xCF :
                case ( byte ) 0xD0 :
                case ( byte ) 0xD1 :
                case ( byte ) 0xD2 :
                case ( byte ) 0xD3 :
                case ( byte ) 0xD4 :
                case ( byte ) 0xD5 :
                case ( byte ) 0xD6 :
                case ( byte ) 0xD7 :
                case ( byte ) 0xD8 :
                case ( byte ) 0xD9 :
                case ( byte ) 0xDA :
                case ( byte ) 0xDB :
                case ( byte ) 0xDC :
                case ( byte ) 0xDD :
                case ( byte ) 0xDE :
                case ( byte ) 0xDF :
                    // UTF2, if the following byte is in [0x80-0xBF]
                    if ( trailChar )
                    {
                        // No next byte : this is an octet
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                    }
                    else
                    {
                        int b2 = bytes[pos + 1] & 0x00FF;
                        
                        if ( ( b2 >= 0x0080 ) && ( b2 <= 0x00BF ) )
                        {
                            // This is an UTF-2 char
                            sb.append( Strings.utf8ToString( bytes, pos, 2 ) );
                            pos++;
                        }
                        else
                        {
                            // Not an UTF-2
                            sb.append( '\\' ).append( Strings.byteToString( b ) );
                        }
                    }
                
                    break;

                case ( byte ) 0xE0 :
                    // May be an UTF-3, if the next byte is in [0xA0-0xBF], followed by a byte in [0x80-0xBF]
                    if ( trailChar )
                    {
                        // No next byte : this is an octet
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                        break;
                    }
                    
                    if ( pos == bytes.length - 2 )
                    {
                        // We only have 2 bytes : not an UTF-3
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                    }
                    else
                    {
                        int b2 = bytes[pos + 1] & 0x00FF;
                        
                        if ( ( b2 >= 0x00A0 ) && ( b2 <= 0x00BF ) )
                        {
                            int b3 = bytes[pos + 2] & 0x00FF;
                            
                            // Check that the third byte is in between 0x80-0xBF
                            if ( ( b3 >= 0x0080 ) && ( b3 <= 0x00BF ) )
                            {
                                // UTF-3
                                sb.append( Strings.utf8ToString( bytes, pos, 3 ) );
                                pos += 2;
                            }
                            else
                            {
                                // Not an UTF-3, dump one bytes
                                sb.append( '\\' ).append( Strings.byteToString( b ) );
                            }
                        }
                        else
                        {
                            // Not an UTF-3 : dump two byte
                            sb.append( '\\' ).append( Strings.byteToString( b ) );
                        }
                    }
                    
                    break;
                    

                // Between E1 and EC, this may be an UTF-3 if the next two bytes are between 0x80 and 0xBF
                case ( byte ) 0xE1 :
                case ( byte ) 0xE2 :
                case ( byte ) 0xE3 :
                case ( byte ) 0xE4 :
                case ( byte ) 0xE5 :
                case ( byte ) 0xE6 :
                case ( byte ) 0xE7 :
                case ( byte ) 0xE8 :
                case ( byte ) 0xE9 :
                case ( byte ) 0xEA :
                case ( byte ) 0xEB :
                case ( byte ) 0xEC :
                case ( byte ) 0xEE :
                case ( byte ) 0xEF :
                    if ( trailChar )
                    {
                        // No next byte : this is an octet
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                        break;
                    }
                    
                    if ( pos == bytes.length - 2 )
                    {
                        // We only have 2 bytes : not an UTF-3
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                    }
                    else
                    {
                        int b2 = bytes[pos + 1] & 0x00FF;
                        
                        if ( ( b2 >= 0x0080 ) && ( b2 <= 0x00BF ) )
                        {
                            int b3 = bytes[pos + 2] & 0x00FF;
                            
                            // Check that the third byte is in between 0x80-0xBF
                            if ( ( b3 >= 0x0080 ) && ( b3 <= 0x00BF ) )
                            {
                                // UTF-3
                                sb.append( Strings.utf8ToString( bytes, pos, 3 ) );
                                pos += 2;
                            }
                            else
                            {
                                // Not an UTF-3, dump one byte
                                sb.append( '\\' ).append( Strings.byteToString( b ) );
                            }
                        }
                        else
                        {
                            // Not an UTF-3 : dump one byte
                            sb.append( '\\' ).append( Strings.byteToString( b ) );
                            pos++;
                        }
                    }
                    
                    break;

                case ( byte ) 0xED :
                    // May be an UTF-3 if the second byte is in [0x80-0x9F] and the third byte in [0x80-0xBF]
                    if ( trailChar )
                    {
                        // No next byte : this is an octet
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                        break;
                    }
                    
                    if ( pos == bytes.length - 2 )
                    {
                        // We only have 2 bytes : not an UTF-3
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                    }
                    else
                    {
                        int b2 = bytes[pos + 1] & 0x00FF;
                        
                        if ( ( b2 >= 0x0080 ) && ( b2 <= 0x009F ) )
                        {
                            int b3 = bytes[pos + 2] & 0x00FF;
                            
                            // Check that the third byte is in between 0x80-0xBF
                            if ( ( b3 >= 0x0080 ) && ( b3 <= 0x00BF ) )
                            {
                                // UTF-3
                                sb.append( Strings.utf8ToString( bytes, pos, 3 ) );
                                pos += 2;
                            }
                            else
                            {
                                // Not an UTF-3, dump one byte
                                sb.append( '\\' ).append( Strings.byteToString( b ) );
                            }
                        }
                        else
                        {
                            // Not an UTF-3 : dump one byte
                            sb.append( '\\' ).append( Strings.byteToString( b ) );
                            pos++;
                        }
                    }
                    
                    break;

                case ( byte ) 0xF0 :
                    // May be an UTF-4 if the second byte is in [0x90-0xBF] followed by two bytes in [0x80-0xBF]
                    if ( trailChar )
                    {
                        // No next byte : this is an octet
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                        break;
                    }
                    
                    if ( pos == bytes.length - 3 )
                    {
                        // We only have 2 bytes : not an UTF-4
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                    }
                    else
                    {
                        int b2 = bytes[pos + 1] & 0x00FF;
                        
                        if ( ( b2 >= 0x0090 ) && ( b2 <= 0x00BF ) )
                        {
                            int b3 = bytes[pos + 2] & 0x00FF;
                            
                            // Check that the third byte is in between 0x80-0xBF
                            if ( ( b3 >= 0x0080 ) && ( b3 <= 0x00BF ) )
                            {
                                int b4 = bytes[pos + 3] & 0x00FF;
                                
                                // Check that the forth byte is in between 0x80-0xBF
                                if ( ( b4 >= 0x0080 ) && ( b4 <= 0x00BF ) )
                                {
                                    // UTF-4
                                    sb.append( Strings.utf8ToString( bytes, pos, 4 ) );
                                    pos += 3;
                                }
                                else
                                {
                                    // Not an UTF-4, dump one byte
                                    sb.append( '\\' ).append( Strings.byteToString( b ) );
                                }
                            }
                            else
                            {
                                // Not an UTF-4, dump one byte
                                sb.append( '\\' ).append( Strings.byteToString( b ) );
                            }
                        }
                        else
                        {
                            // Not an UTF-4 : dump one byte
                            sb.append( '\\' ).append( Strings.byteToString( b ) );
                            pos++;
                        }
                    }
                    
                    break;

                case ( byte ) 0xF1 :
                case ( byte ) 0xF2 :
                case ( byte ) 0xF3 :
                    // May be an UTF-4
                    // May be an UTF-4 if it's followed by three bytes in [0x80-0xBF]
                    if ( trailChar )
                    {
                        // No next byte : this is an octet
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                        break;
                    }
                    
                    if ( pos == bytes.length - 3 )
                    {
                        // We only have 2 bytes : not an UTF-4
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                    }
                    else
                    {
                        int b2 = bytes[pos + 1] & 0x00FF;
                        
                        if ( ( b2 >= 0x0080 ) && ( b2 <= 0x00BF ) )
                        {
                            int b3 = bytes[pos + 2] & 0x00FF;
                            
                            // Check that the third byte is in between 0x80-0xBF
                            if ( ( b3 >= 0x0080 ) && ( b3 <= 0x00BF ) )
                            {
                                int b4 = bytes[pos + 3] & 0x00FF;
                                
                                // Check that the forth byte is in between 0x80-0xBF
                                if ( ( b4 >= 0x0080 ) && ( b4 <= 0x00BF ) )
                                {
                                    // UTF-4
                                    sb.append( Strings.utf8ToString( bytes, pos, 4 ) );
                                    pos += 3;
                                }
                                else
                                {
                                    // Not an UTF-4, dump one byte
                                    sb.append( '\\' ).append( Strings.byteToString( b ) );
                                }
                            }
                            else
                            {
                                // Not an UTF-4, dump one byte
                                sb.append( '\\' ).append( Strings.byteToString( b ) );
                            }
                        }
                        else
                        {
                            // Not an UTF-4 : dump one byte
                            sb.append( '\\' ).append( Strings.byteToString( b ) );
                            pos++;
                        }
                    }
                    
                    break;

                case ( byte ) 0xF4 :
                    // May be an UTF-4 if the second byte is in [0x80-0x8F] followed by two bytes in [0x80-0xBF]
                    if ( trailChar )
                    {
                        // No next byte : this is an octet
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                        break;
                    }
                    
                    if ( pos == bytes.length - 3 )
                    {
                        // We only have 2 bytes : not an UTF-4
                        sb.append( '\\' ).append( Strings.byteToString( b ) );
                    }
                    else
                    {
                        int b2 = bytes[pos + 1] & 0x00FF;
                        
                        if ( ( b2 >= 0x0080 ) && ( b2 <= 0x008F ) )
                        {
                            int b3 = bytes[pos + 2] & 0x00FF;
                            
                            // Check that the third byte is in between 0x80-0xBF
                            if ( ( b3 >= 0x0080 ) && ( b3 <= 0x00BF ) )
                            {
                                int b4 = bytes[pos + 3] & 0x00FF;
                                
                                // Check that the forth byte is in between 0x80-0xBF
                                if ( ( b4 >= 0x0080 ) && ( b4 <= 0x00BF ) )
                                {
                                    // UTF-4
                                    sb.append( Strings.utf8ToString( bytes, pos, 4 ) );
                                    pos += 3;
                                }
                                else
                                {
                                    // Not an UTF-4, dump one byte
                                    sb.append( '\\' ).append( Strings.byteToString( b ) );
                                }
                            }
                            else
                            {
                                // Not an UTF-4, dump one byte
                                sb.append( '\\' ).append( Strings.byteToString( b ) );
                            }
                        }
                        else
                        {
                            // Not an UTF-4 : dump one byte
                            sb.append( '\\' ).append( Strings.byteToString( b ) );
                            pos++;
                        }
                    }
                    
                    break;


                default :
                    // octet
                    sb.append( '\\' ).append( Strings.byteToString( b ) );

                    break;
                    
            }
            
            if ( leadChar )
            {
                leadChar = false;
            }
        }
        
        return sb.toString();
    }


    /**
     * Get the User Provided value. If the value is Human Readable, it will return
     * the stored String, otherwise it will returns a String based on the bytes - which may be 
     * invalid if the value is a pure binary -.
     *
     * @return The user provided value
     */
    public String getString()
    {
        if ( isHR )
        {
            return upValue;
        }
        else
        {
            return Strings.utf8ToString( bytes );
        }
    }


    /**
     * Compute the normalized value
     * 
     * @throws LdapException If we were'nt able to normalize the value
     */
    private void computeNormValue() throws LdapException
    {
        if ( upValue == null )
        {
            return;
        }
        
        Normalizer normalizer;
        
        // We should have a Equality MatchingRule
        MatchingRule equality = attributeType.getEquality();
        
        if ( equality == null )
        {
            // Let's try with the Substring MatchingRule
            MatchingRule subString = attributeType.getSubstring();
            
            if ( subString == null )
            {
                // last chance : ordering matching rule
                MatchingRule ordering = attributeType.getOrdering();
                
                if ( ordering == null )
                {
                    // Ok, no luck. Use a NoOp normalizer
                    normalizer = new NoOpNormalizer();
                }
                else
                {
                    normalizer = ordering.getNormalizer();
                }
            }
            else
            {
                normalizer = subString.getNormalizer();
            }
        }
        else
        {
            normalizer = equality.getNormalizer();
        }
        
        if ( normalizer == null )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_13220_NO_NORMALIZER ) );
        }

        // Now, normalize the upValue
        normValue = normalizer.normalize( upValue );
    }
    
    
    /**
     * @return The normalized value
     */
    public String getNormalized()
    {
        return normValue;
    }
    
    
    /**
     * @return The User Provided value
     */
    public String getUpValue()
    {
        if ( isHR )
        {
            return upValue;
        }
        else
        {
            return getEscaped();
        }
    }


    /**
     * Get the wrapped value as a byte[], if and only if the Value is binary,
     * otherwise returns null.
     *
     * @return the wrapped value as a byte[]
     */
    public byte[] getBytes()
    {
        if ( bytes == null )
        {
            return null;
        }
        
        if ( bytes.length == 0 )
        {
            return Strings.EMPTY_BYTES;
        }
        
        byte[] copy = new byte[bytes.length];
        System.arraycopy( bytes, 0, copy, 0, bytes.length );
        
        return copy;
    }


    /**
     * Tells if the value is schema aware or not.
     *
     * @return <code>true</code> if the value is sxhema aware
     */
    public boolean isSchemaAware()
    {
        return attributeType != null;
    }


    /**
     * Uses the syntaxChecker associated with the attributeType to check if the
     * value is valid.
     * 
     * @param syntaxChecker the SyntaxChecker to use to validate the value
     * @return <code>true</code> if the value is valid
     * @exception LdapInvalidAttributeValueException if the value cannot be validated
     */
    public final boolean isValid( SyntaxChecker syntaxChecker ) throws LdapInvalidAttributeValueException
    {
        if ( syntaxChecker == null )
        {
            String message = I18n.err( I18n.ERR_13219_NULL_SYNTAX_CHECKER, toString() );
            LOG.error( message );
            throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
        }

        // No attributeType, or it's in relaxed mode
        if ( isHR )
        {
            // We need to prepare the String in this case
            return syntaxChecker.isValidSyntax( getString() );
        }
        else
        {
            return syntaxChecker.isValidSyntax( bytes );
        }
    }


    /**
     * Tells if the current value is Human Readable
     * 
     * @return <code>true</code> if the value is a String, <code>false</code> otherwise
     */
    public boolean isHumanReadable()
    {
        return isHR;
    }


    /**
     * @return The length of the interned value
     */
    public int length()
    {
        if ( isHR )
        {
            return upValue != null ? upValue.length() : 0;
        }
        else
        {
            return bytes != null ? bytes.length : 0;
        }
    }
    
    
    /**
     * Gets a comparator using getMatchingRule() to resolve the matching
     * that the comparator is extracted from.
     *
     * @return a comparator associated with the attributeType or null if one cannot be found
     */
    private LdapComparator<?> getLdapComparator()
    {
        if ( attributeType != null )
        {
            MatchingRule mr = attributeType.getEquality();

            if ( mr != null )
            {
                return mr.getLdapComparator();
            }
        }

        return null;
    }


    /**
     * Serialize the Value into a buffer at the given position.
     * 
     * @param buffer The buffer which will contain the serialized StringValue
     * @param pos The position in the buffer for the serialized value
     * @return The new position in the buffer
     */
    public int serialize( byte[] buffer, int pos )
    {
        // Compute the length : the isHR flag first, the value and prepared value presence flags
        int length = 1;
        byte[] preparedBytes = null;

        if ( isHR )
        { 
            if ( upValue != null )
            {
                // The presence flag, the length and the value
                length += 1 + 4 + bytes.length;
            }

            if ( normValue != null )
            {
                // The presence flag, the length and the value
                preparedBytes = Strings.getBytesUtf8( normValue );
                length += 1 + 4 + preparedBytes.length;
            }
        }
        else
        {
            if ( bytes != null )
            {
                length = 1 + 1 + 4 + bytes.length;
            }
            else
            {
                length = 1 + 1;
            }
        }

        // Check that we will be able to store the data in the buffer
        if ( buffer.length - pos < length )
        {
            throw new ArrayIndexOutOfBoundsException();
        }

        if ( isHR )
        {
            buffer[pos++] = Serialize.TRUE;

            // Write the user provided value, if not null
            if ( bytes != null )
            {
                buffer[pos++] = Serialize.TRUE;
                pos = Serialize.serialize( bytes, buffer, pos );
            }
            else
            {
                buffer[pos++] = Serialize.FALSE;
            }
    
            // Write the prepared value, if not null
            if ( normValue != null )
            {
                buffer[pos++] = Serialize.TRUE;
                pos = Serialize.serialize( preparedBytes, buffer, pos );
            }
            else
            {
                buffer[pos++] = Serialize.FALSE;
            }
        }
        else
        {
            buffer[pos++] = Serialize.FALSE;

            if ( bytes != null )
            {
                buffer[pos++] = Serialize.TRUE;
                pos = Serialize.serialize( bytes, buffer, pos );
            }
            else
            {
                buffer[pos++] = Serialize.FALSE;
            }
        }

        return pos;
    }
    
    
    /**
     * Deserialize a Value. It will return a new Value instance.
     * 
     * @param in The input stream
     * @return A new Value instance
     * @throws IOException If the stream can't be read
     * @throws ClassNotFoundException If we can't instanciate a Value
     */
    public static Value deserialize( ObjectInput in ) throws IOException, ClassNotFoundException
    {
        Value value = new Value( ( AttributeType ) null );
        value.readExternal( in );

        return value;
    }

    
    /**
     * Deserialize a Value. It will return a new Value instance.
     * 
     * @param attributeType The AttributeType associated with the Value. Can be null
     * @param in The input stream
     * @return A new Value instance
     * @throws IOException If the stream can't be read
     * @throws ClassNotFoundException If we can't instanciate a Value
     */
    public static Value deserialize( AttributeType attributeType, ObjectInput in ) throws IOException, ClassNotFoundException
    {
        Value value = new Value( attributeType );
        value.readExternal( in );

        return value;
    }


    /**
     * Deserialize a StringValue from a byte[], starting at a given position
     * 
     * @param buffer The buffer containing the StringValue
     * @param pos The position in the buffer
     * @return The new position
     * @throws IOException If the serialized value is not a StringValue
     * @throws LdapInvalidAttributeValueException If the value is invalid
     */
    public int deserialize( byte[] buffer, int pos ) throws IOException, LdapInvalidAttributeValueException
    {
        if ( ( pos < 0 ) || ( pos >= buffer.length ) )
        {
            throw new ArrayIndexOutOfBoundsException();
        }

        // Read the isHR flag
        isHR = Serialize.deserializeBoolean( buffer, pos );
        pos++;

        if ( isHR )
        {
            // Read the user provided value, if it's not null
            boolean hasValue = Serialize.deserializeBoolean( buffer, pos );
            pos++;
    
            if ( hasValue )
            {
                bytes = Serialize.deserializeBytes( buffer, pos );
                pos += 4 + bytes.length;

                upValue = Strings.utf8ToString( bytes );
            }

            // Read the prepared value, if not null
            boolean hasPreparedValue = Serialize.deserializeBoolean( buffer, pos );
            pos++;
    
            if ( hasPreparedValue )
            {
                byte[] preparedBytes = Serialize.deserializeBytes( buffer, pos );
                pos += 4 + preparedBytes.length;
                normValue = Strings.utf8ToString( preparedBytes );
            }
        }
        else
        {
            // Read the user provided value, if it's not null
            boolean hasBytes = Serialize.deserializeBoolean( buffer, pos );
            pos++;
    
            if ( hasBytes )
            {
                bytes = Serialize.deserializeBytes( buffer, pos );
                pos += 4 + bytes.length;
            }

        }
        
        if ( attributeType != null )
        {
            try
            {
                computeNormValue();
            }
            catch ( LdapException le )
            {
                throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, le.getMessage() );
            }
        }
        
        hashCode();

        return pos;
    }
    
    
    /**
     * {@inheritDoc}
     */
    @Override
    public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
    {
        // Read the isHR flag
        isHR = in.readBoolean();

        if ( isHR )
        {
            // Read the value if any
            if ( in.readBoolean() )
            {
                int length = in.readInt();
                bytes = new byte[length];
                
                if ( length != 0 )
                {
                    in.readFully( bytes );
                }
    
                upValue = Strings.utf8ToString( bytes );
            }
    
            // Read the prepared String if any
            if ( in.readBoolean() )
            {
                normValue = in.readUTF();
            }
        }
        else
        {
            if ( in.readBoolean() )
            {
                int length = in.readInt();
                bytes = new byte[length];
                
                if ( length != 0 )
                {
                    in.readFully( bytes );
                }
            }
        }
        
        hashCode();
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public void writeExternal( ObjectOutput out ) throws IOException
    {
        // Write a boolean for the HR flag
        out.writeBoolean( isHR );

        if ( isHR )
        { 
            // Write the value if any
            out.writeBoolean( upValue != null );
    
            if ( upValue != null )
            {
                // Write the value
                out.writeInt( bytes.length );
    
                if ( bytes.length > 0 )
                {
                    out.write( bytes );
                }
            }

            // Write the prepared value if any
            out.writeBoolean( normValue != null );
    
            if ( normValue != null )
            {
                // Write the value
                out.writeUTF( normValue );
            }
        }
        else
        {
            // Just write the bytes if not null
            out.writeBoolean( bytes != null );

            if ( bytes != null )
            {
                out.writeInt( bytes.length );
                
                if ( bytes.length > 0 )
                {
                    out.write( bytes );
                }
            }
        }

        // and flush the data
        out.flush();
    }

    
    /**
     * Compare the current value with a String.
     * 
     * @param other the String we want to compare the current value with
     * @return a positive value if the current value is above the provided String, a negative value
     * if it's below, 0 if they are equal.
     * @throws IllegalStateException on failures to extract the comparator, or the
     * normalizers needed to perform the required comparisons based on the schema
     */
    public int compareTo( String other )
    {
        if ( !isHR )
        {
            String msg = I18n.err( I18n.ERR_13224_FAILED_TO_COMPARE_NORM_VALUES, this, other );
            LOG.error( msg );
            throw new IllegalStateException( msg );
        }
        
        // Check if both value are null
        if ( bytes == null )
        {
            if ( other == null )
            {
                return 0;
            }
            else
            {
                return -1;
            }
        }
        else if ( other == null )
        {
            return 1;
        }
        
        // We have HR values. We may have an attributeType for the base Value
        // It actually does not matter if the second value has an attributeType
        // which is different
        try
        {
            if ( attributeType != null )
            {
                // No normalization. Use the base AttributeType to normalize
                // the other value
                String normalizedOther = attributeType.getEquality().getNormalizer().normalize( other );
                
                return normValue.compareTo( normalizedOther );
            }
            else
            {
                // No AtributeType... Compare the normValue
                return normValue.compareTo( other );
            }
        }
        catch ( LdapException le )
        {
            return -1;
        }
    }

    
    /**
     * Compare two values. We compare the stored bytes
     * 
     * @param other the byte[] we want to compare the current value with
     * @return a positive value if the current value is above the provided byte[], a negative value
     * if it's below, 0 if they are equal.
     * @throws IllegalStateException on failures to extract the comparator, or the
     * normalizers needed to perform the required comparisons based on the schema
     */
    public int compareTo( byte[] other )
    {
        if ( isHR )
        {
            String msg = I18n.err( I18n.ERR_13224_FAILED_TO_COMPARE_NORM_VALUES, this, other );
            LOG.error( msg );
            throw new IllegalStateException( msg );
        }
        
        // Check if both value are null
        if ( bytes == null )
        {
            if ( other == null )
            {
                return 0;
            }
            else
            {
                return -1;
            }
        }
        else if ( other == null )
        {
            return 1;
        }

        // Default : compare the bytes
        return Strings.compare( bytes, other );
    }

    
    /**
     * Compare two values. We either compare the stored bytes, or we use the 
     * AttributeType Comparator, if we have an Ordered MatchingRule. 
     * 
     * @param other The other Value we want to compare the current value with
     * @return a positive value if the current value is above the provided value, a negative value
     * if it's below, 0 if they are equal.
     * @throws IllegalStateException on failures to extract the comparator, or the
     * normalizers needed to perform the required comparisons based on the schema
     */
    @Override
    public int compareTo( Value other )
    {
        // The two values must have the same type
        if ( isHR != other.isHR )
        {
            String msg = I18n.err( I18n.ERR_13224_FAILED_TO_COMPARE_NORM_VALUES, this, other );
            LOG.error( msg );
            throw new IllegalStateException( msg );
        }
        
        // Check if both value are null
        if ( bytes == null )
        {
            if ( other.bytes == null )
            {
                return 0;
            }
            else
            {
                return -1;
            }
        }
        else if ( other.bytes == null )
        {
            return 1;
        }
        
        // Ok, neither this nor the other have null values.
        
        // Shortcut when the value are not HR
        if ( !isHR )
        {
            return Strings.compare( bytes, other.bytes );
        }

        // We have HR values. We may have an attributeType for the base Value
        // It actually does not matter if the second value has an attributeType
        // which is different
        try
        {
            if ( attributeType != null )
            {
                // Check if the other value has been normalized or not
                if ( other.attributeType == null )
                {
                    // No normalization. Use the base AttributeType to normalize
                    // the other value
                    String normalizedOther = attributeType.getEquality().getNormalizer().normalize( other.upValue );
                    
                    return normValue.compareTo( normalizedOther );
                }
                else
                {
                    return normValue.compareTo( other.normValue );
                }
            }
            else
            {
                if ( other.attributeType != null )
                {
                    // Normalize the current value with the other value normalizer
                    String normalizedThis = other.attributeType.getEquality().getNormalizer().normalize( upValue );
                    
                    return normalizedThis.compareTo( other.normValue );
                }
                else
                {
                    // No AtributeType... Compare the normValue
                    return normValue.compareTo( other.normValue );
                }
            }
        }
        catch ( LdapException le )
        {
            return -1;
        }
    }
    
    
    /**
     * We compare two values using their Comparator, if any. 
     * 
     * @see Object#equals(Object)
     */
    @Override
    public boolean equals( Object obj )
    {
        if ( this == obj )
        {
            return true;
        }

        if ( obj instanceof String )
        {
            String other = ( String ) obj;
            
            if ( !isHR )
            {
                return false;
            }
            
            if ( attributeType == null )
            {
                if ( upValue != null )
                {
                    return upValue.equals( other );
                }
                else
                {
                    return obj == null;
                }
            }
            else
            {
                // Use the comparator
                // We have an AttributeType, we use the associated comparator
                try
                {
                    LdapComparator<String> comparator = ( LdapComparator<String> ) getLdapComparator();
                    
                    Normalizer normalizer = null;
                    
                    if ( attributeType.getEquality() != null )
                    {
                        normalizer = attributeType.getEquality().getNormalizer();
                    }

                    if ( normalizer == null )
                    {
                        if ( comparator == null )
                        {
                            return normValue.equals( other );
                        }
                        else
                        {
                            return comparator.compare( normValue, other ) == 0;
                        }
                    }
                    
                    String thisNormValue = normValue;
                    String otherNormValue = normalizer.normalize( other );
                        
                    // Compare normalized values
                    if ( comparator == null )
                    {
                        return thisNormValue.equals( otherNormValue );
                    }
                    else
                    {
                        return comparator.compare( thisNormValue, otherNormValue ) == 0;
                    }
                }
                catch ( LdapException ne )
                {
                    return false;
                }
            }
        }
        
        if ( !( obj instanceof Value ) )
        {
            return false;
        }

        Value other = ( Value ) obj;

        // Check if the values aren't of the same type
        if ( isHR != other.isHR )
        {
            // Both values must be HR or not HR
            return false;
        }
        
        if ( !isHR )
        {
            // Shortcut for binary values
            return Arrays.equals( bytes, other.bytes );
        }
        
        // HR values
        if ( bytes == null )
        {
            return other.bytes == null;
        }
        
        // Special case
        if ( other.bytes == null )
        {
            return false;
        }
        
        // Not null, but empty. We try to avoid a spurious String Preparation
        if ( bytes.length == 0 )
        {
            return other.bytes.length == 0;
        }
        else if ( other.bytes.length == 0 )
        {
            return false;
        }

        // Ok, now, let's see if we have an AttributeType at all. If both have one,
        // and if they aren't equal, then we get out. If one of them has an AttributeType and
        // not the other, we will assume that this is the AttributeType to use.
        MatchingRule equalityMR;
        
        if ( attributeType == null )
        {
            if ( other.attributeType != null )
            {
                // Use the Other value AT
                equalityMR = other.attributeType.getEquality();
 
                // We may not have an Equality MR, and in tjis case, we compare the bytes
                if ( equalityMR == null )
                {
                    return Arrays.equals( bytes, other.bytes );
                }
                
                LdapComparator<Object> ldapComparator = equalityMR.getLdapComparator();
                
                if ( ldapComparator == null )
                {
                    // This is an error !
                    LOG.error( I18n.err( I18n.ERR_13249_NO_COMPARATOR_FOR_AT, other.attributeType ) );
                    
                    return false;
                }
                
                return ldapComparator.compare( normValue, other.normValue ) == 0;
            }
            else
            {
                // Both are null. We will compare the prepared String if we have one, 
                // or the bytes otherwise.
                if ( upValue != null )
                {
                    return upValue.equals( other.upValue );
                }
                else
                {
                    return Arrays.equals( bytes, other.bytes );
                } 
            }
        }
        else 
        {
            if ( other.attributeType != null )
            {
                // Both attributeType must be equal
                if ( !attributeType.equals( other.attributeType ) )
                {
                    return false;
                }
                
                // Use the comparator
                // We have an AttributeType, we use the associated comparator
                LdapComparator<String> comparator = ( LdapComparator<String> ) getLdapComparator();
                
                if ( other.attributeType.getEquality() == null )
                {
                    // No equality ? Default to comparing using a String comparator
                    return stringComparator.compare( normValue, other.normValue ) == 0;
                }
                
                
                // Compare normalized values
                if ( comparator == null )
                {
                    return normValue.equals( other.normValue );
                }
                else
                {
                    return comparator.compare( normValue, other.normValue ) == 0;
                }
            }
            
            // No attributeType
            if ( normValue == null )
            {
                return other.normValue == null;
            }
            else
            {
                return normValue.equals( other.normValue );
            }
        }
    }

    
    /**
     * @see Object#hashCode()
     * @return the instance's hashcode
     */
    @Override
    public int hashCode()
    {
        if ( h == 0 )
        {
            // return zero if the value is null so only one null value can be
            // stored in an attribute - the binary version does the same
            if ( isHR )
            {
                if ( normValue != null )
                {
                    h = normValue.hashCode();
                }
                else
                {
                    h = 0;
                }
            }
            else
            {
                h = Arrays.hashCode( bytes );
            }
        }

        return h;
    }


    /**
     * @see Object#toString()
     */
    @Override
    public String toString()
    {
        if ( isHR )
        {
            return upValue == null ? "null" : upValue;
        }
        else
        {
             // Dumps binary in hex with label.
            if ( bytes == null )
            {
                return "null";
            }
            else if ( bytes.length > 16 )
            {
                // Just dump the first 16 bytes...
                byte[] copy = new byte[16];

                System.arraycopy( bytes, 0, copy, 0, 16 );

                return Strings.dumpBytes( copy ) + "...";
            }
            else
            {
                return Strings.dumpBytes( bytes );
            }
        }
    }
}
