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


import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import org.apache.directory.shared.i18n.I18n;


/**
 * <p>
 * Assists in implementing {@link Object#equals(Object)} methods.
 * </p>
 * <p>
 * This class provides methods to build a good equals method for any class. It
 * follows rules laid out in <a
 * href="http://java.sun.com/docs/books/effective/index.html">Effective Java</a> ,
 * by Joshua Bloch. In particular the rule for comparing <code>doubles</code>,
 * <code>floats</code>, and arrays can be tricky. Also, making sure that
 * <code>equals()</code> and <code>hashCode()</code> are consistent can be
 * difficult.
 * </p>
 * <p>
 * Two Objects that compare as equals must generate the same hash code, but two
 * Objects with the same hash code do not have to be equal.
 * </p>
 * <p>
 * All relevant fields should be included in the calculation of equals. Derived
 * fields may be ignored. In particular, any field used in generating a hash
 * code must be used in the equals method, and vice versa.
 * </p>
 * <p>
 * Typical use for the code is as follows:
 * </p>
 * 
 * <pre>
 * public boolean equals( Object o )
 * {
 *     if ( !( o instanceof MyClass ) )
 *     {
 *         return false;
 *     }
 *     MyClass rhs = ( MyClass ) o;
 *     return new EqualsBuilder().appendSuper( super.equals( o ) ).append( field1, rhs.field1 )
 *         .append( field2, rhs.field2 ).append( field3, rhs.field3 ).isEquals();
 * }
 * </pre>
 * 
 * <p>
 * Alternatively, there is a method that uses reflection to determine the fields
 * to test. Because these fields are usually private, the method,
 * <code>reflectionEquals</code>, uses
 * <code>AccessibleObject.setAccessible</code> to change the visibility of the
 * fields. This will fail under a security manager, unless the appropriate
 * permissions are set up correctly. It is also slower than testing explicitly.
 * </p>
 * <p>
 * A typical invocation for this method would look like:
 * </p>
 * 
 * <pre>
 * public boolean equals( Object o )
 * {
 *     return EqualsBuilder.reflectionEquals( this, o );
 * }
 * </pre>
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class EqualsBuilder
{

    /**
     * If the fields tested are equals. The default value is <code>true</code>.
     */
    private boolean isEquals = true;


    /**
     * <p>
     * Constructor for EqualsBuilder.
     * </p>
     * <p>
     * Starts off assuming that equals is <code>true</code>.
     * </p>
     * 
     * @see Object#equals(Object)
     */
    public EqualsBuilder()
    {
        // do nothing for now.
    }


    // -------------------------------------------------------------------------

    /**
     * <p>
     * This method uses reflection to determine if the two <code>Object</code>s
     * are equal.
     * </p>
     * <p>
     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
     * private fields. This means that it will throw a security exception if run
     * under a security manager, if the permissions are not set up correctly. It
     * is also not as efficient as testing explicitly.
     * </p>
     * <p>
     * Transient members will be not be tested, as they are likely derived
     * fields, and not part of the value of the Object.
     * </p>
     * <p>
     * Static fields will not be tested. Superclass fields will be included.
     * </p>
     * 
     * @param lhs
     *            <code>this</code> object
     * @param rhs
     *            the other object
     * @return <code>true</code> if the two Objects have tested equals.
     */
    public static boolean reflectionEquals( Object lhs, Object rhs )
    {
        return reflectionEquals( lhs, rhs, false, null );
    }


    /**
     * <p>
     * This method uses reflection to determine if the two <code>Object</code>s
     * are equal.
     * </p>
     * <p>
     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
     * private fields. This means that it will throw a security exception if run
     * under a security manager, if the permissions are not set up correctly. It
     * is also not as efficient as testing explicitly.
     * </p>
     * <p>
     * If the TestTransients parameter is set to <code>true</code>, transient
     * members will be tested, otherwise they are ignored, as they are likely
     * derived fields, and not part of the value of the <code>Object</code>.
     * </p>
     * <p>
     * Static fields will not be tested. Superclass fields will be included.
     * </p>
     * 
     * @param lhs
     *            <code>this</code> object
     * @param rhs
     *            the other object
     * @param testTransients
     *            whether to include transient fields
     * @return <code>true</code> if the two Objects have tested equals.
     */
    public static boolean reflectionEquals( Object lhs, Object rhs, boolean testTransients )
    {
        return reflectionEquals( lhs, rhs, testTransients, null );
    }


    /**
     * <p>
     * This method uses reflection to determine if the two <code>Object</code>s
     * are equal.
     * </p>
     * <p>
     * It uses <code>AccessibleObject.setAccessible</code> to gain access to
     * private fields. This means that it will throw a security exception if run
     * under a security manager, if the permissions are not set up correctly. It
     * is also not as efficient as testing explicitly.
     * </p>
     * <p>
     * If the testTransients parameter is set to <code>true</code>, transient
     * members will be tested, otherwise they are ignored, as they are likely
     * derived fields, and not part of the value of the <code>Object</code>.
     * </p>
     * <p>
     * Static fields will not be included. Superclass fields will be appended up
     * to and including the specified superclass. A null superclass is treated
     * as java.lang.Object.
     * </p>
     * 
     * @param lhs
     *            <code>this</code> object
     * @param rhs
     *            the other object
     * @param testTransients
     *            whether to include transient fields
     * @param reflectUpToClass
     *            the superclass to reflect up to (inclusive), may be
     *            <code>null</code>
     * @return <code>true</code> if the two Objects have tested equals.
     * @since 2.0
     */
    public static boolean reflectionEquals( Object lhs, Object rhs, boolean testTransients, Class reflectUpToClass )
    {
        if ( lhs == rhs )
        {
            return true;
        }
        if ( lhs == null || rhs == null )
        {
            return false;
        }
        // Find the leaf class since there may be transients in the leaf
        // class or in classes between the leaf and root.
        // If we are not testing transients or a subclass has no ivars,
        // then a subclass can test equals to a superclass.
        Class lhsClass = lhs.getClass();
        Class rhsClass = rhs.getClass();
        Class testClass;
        if ( lhsClass.isInstance( rhs ) )
        {
            testClass = lhsClass;
            if ( !rhsClass.isInstance( lhs ) )
            {
                // rhsClass is a subclass of lhsClass
                testClass = rhsClass;
            }
        }
        else if ( rhsClass.isInstance( lhs ) )
        {
            testClass = rhsClass;
            if ( !lhsClass.isInstance( rhs ) )
            {
                // lhsClass is a subclass of rhsClass
                testClass = lhsClass;
            }
        }
        else
        {
            // The two classes are not related.
            return false;
        }
        EqualsBuilder equalsBuilder = new EqualsBuilder();
        try
        {
            reflectionAppend( lhs, rhs, testClass, equalsBuilder, testTransients );
            while ( testClass.getSuperclass() != null && testClass != reflectUpToClass )
            {
                testClass = testClass.getSuperclass();
                reflectionAppend( lhs, rhs, testClass, equalsBuilder, testTransients );
            }
        }
        catch ( IllegalArgumentException e )
        {
            // In this case, we tried to test a subclass vs. a superclass and
            // the subclass has ivars or the ivars are transient and
            // we are testing transients.
            // If a subclass has ivars that we are trying to test them, we get
            // an
            // exception and we know that the objects are not equal.
            return false;
        }
        return equalsBuilder.isEquals();
    }


    /**
     * <p>
     * Appends the fields and values defined by the given object of the given
     * Class.
     * </p>
     * 
     * @param lhs
     *            the left hand object
     * @param rhs
     *            the right hand object
     * @param clazz
     *            the class to append details of
     * @param builder
     *            the builder to append to
     * @param useTransients
     *            whether to test transient fields
     */
    private static void reflectionAppend( Object lhs, Object rhs, Class clazz, EqualsBuilder builder,
        boolean useTransients )
    {
        Field[] fields = clazz.getDeclaredFields();
        AccessibleObject.setAccessible( fields, true );
        for ( int i = 0; i < fields.length && builder.isEquals; i++ )
        {
            Field f = fields[i];
            if ( ( f.getName().indexOf( '$' ) == -1 ) && ( useTransients || !Modifier.isTransient( f.getModifiers() ) )
                && ( !Modifier.isStatic( f.getModifiers() ) ) )
            {
                try
                {
                    builder.append( f.get( lhs ), f.get( rhs ) );
                }
                catch ( IllegalAccessException e )
                {
                    // this can't happen. Would get a Security exception instead
                    // throw a runtime exception in case the impossible happens.
                    throw new InternalError( I18n.err( I18n.ERR_04355 ) );
                }
            }
        }
    }


    // -------------------------------------------------------------------------

    /**
     * <p>
     * Adds the result of <code>super.equals()</code> to this builder.
     * </p>
     * 
     * @param superEquals
     *            the result of calling <code>super.equals()</code>
     * @return EqualsBuilder - used to chain calls.
     * @since 2.0
     */
    public EqualsBuilder appendSuper( boolean superEquals )
    {
        if ( isEquals == false )
        {
            return this;
        }
        isEquals = superEquals;
        return this;
    }


    // -------------------------------------------------------------------------

    /**
     * <p>
     * Test if two <code>Object</code>s are equal using their
     * <code>equals</code> method.
     * </p>
     * 
     * @param lhs
     *            the left hand object
     * @param rhs
     *            the right hand object
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( Object lhs, Object rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        if ( lhs == rhs )
        {
            return this;
        }
        if ( lhs == null || rhs == null )
        {
            this.setEquals( false );
            return this;
        }
        Class lhsClass = lhs.getClass();
        if ( !lhsClass.isArray() )
        {
            // The simple case, not an array, just test the element
            isEquals = lhs.equals( rhs );
        }
        else if ( lhs.getClass() != rhs.getClass() )
        {
            // Here when we compare different dimensions, for example: a
            // boolean[][] to a boolean[]
            this.setEquals( false );
        }
        // 'Switch' on type of array, to dispatch to the correct handler
        // This handles multi dimensional arrays of the same depth
        else if ( lhs instanceof long[] )
        {
            append( ( long[] ) lhs, ( long[] ) rhs );
        }
        else if ( lhs instanceof int[] )
        {
            append( ( int[] ) lhs, ( int[] ) rhs );
        }
        else if ( lhs instanceof short[] )
        {
            append( ( short[] ) lhs, ( short[] ) rhs );
        }
        else if ( lhs instanceof char[] )
        {
            append( ( char[] ) lhs, ( char[] ) rhs );
        }
        else if ( lhs instanceof byte[] )
        {
            append( ( byte[] ) lhs, ( byte[] ) rhs );
        }
        else if ( lhs instanceof double[] )
        {
            append( ( double[] ) lhs, ( double[] ) rhs );
        }
        else if ( lhs instanceof float[] )
        {
            append( ( float[] ) lhs, ( float[] ) rhs );
        }
        else if ( lhs instanceof boolean[] )
        {
            append( ( boolean[] ) lhs, ( boolean[] ) rhs );
        }
        else
        {
            // Not an array of primitives
            append( ( Object[] ) lhs, ( Object[] ) rhs );
        }
        return this;
    }


    /**
     * <p>
     * Test if two <code>long</code> s are equal.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>long</code>
     * @param rhs
     *            the right hand <code>long</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( long lhs, long rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        isEquals = ( lhs == rhs );
        return this;
    }


    /**
     * <p>
     * Test if two <code>int</code>s are equal.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>int</code>
     * @param rhs
     *            the right hand <code>int</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( int lhs, int rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        isEquals = ( lhs == rhs );
        return this;
    }


    /**
     * <p>
     * Test if two <code>short</code>s are equal.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>short</code>
     * @param rhs
     *            the right hand <code>short</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( short lhs, short rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        isEquals = ( lhs == rhs );
        return this;
    }


    /**
     * <p>
     * Test if two <code>char</code>s are equal.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>char</code>
     * @param rhs
     *            the right hand <code>char</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( char lhs, char rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        isEquals = ( lhs == rhs );
        return this;
    }


    /**
     * <p>
     * Test if two <code>byte</code>s are equal.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>byte</code>
     * @param rhs
     *            the right hand <code>byte</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( byte lhs, byte rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        isEquals = ( lhs == rhs );
        return this;
    }


    /**
     * <p>
     * Test if two <code>double</code>s are equal by testing that the pattern
     * of bits returned by <code>doubleToLong</code> are equal.
     * </p>
     * <p>
     * This handles NaNs, Infinities, and <code>-0.0</code>.
     * </p>
     * <p>
     * It is compatible with the hash code generated by
     * <code>HashCodeBuilder</code>.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>double</code>
     * @param rhs
     *            the right hand <code>double</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( double lhs, double rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        return append( Double.doubleToLongBits( lhs ), Double.doubleToLongBits( rhs ) );
    }


    /**
     * <p>
     * Test if two <code>float</code>s are equal byt testing that the pattern
     * of bits returned by doubleToLong are equal.
     * </p>
     * <p>
     * This handles NaNs, Infinities, and <code>-0.0</code>.
     * </p>
     * <p>
     * It is compatible with the hash code generated by
     * <code>HashCodeBuilder</code>.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>float</code>
     * @param rhs
     *            the right hand <code>float</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( float lhs, float rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        return append( Float.floatToIntBits( lhs ), Float.floatToIntBits( rhs ) );
    }


    /**
     * <p>
     * Test if two <code>booleans</code>s are equal.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>boolean</code>
     * @param rhs
     *            the right hand <code>boolean</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( boolean lhs, boolean rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        isEquals = ( lhs == rhs );
        return this;
    }


    /**
     * <p>
     * Performs a deep comparison of two <code>Object</code> arrays.
     * </p>
     * <p>
     * This also will be called for the top level of multi-dimensional, ragged,
     * and multi-typed arrays.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>Object[]</code>
     * @param rhs
     *            the right hand <code>Object[]</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( Object[] lhs, Object[] rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        if ( lhs == rhs )
        {
            return this;
        }
        if ( lhs == null || rhs == null )
        {
            this.setEquals( false );
            return this;
        }
        if ( lhs.length != rhs.length )
        {
            this.setEquals( false );
            return this;
        }
        for ( int i = 0; i < lhs.length && isEquals; ++i )
        {
            append( lhs[i], rhs[i] );
        }
        return this;
    }


    /**
     * <p>
     * Deep comparison of array of <code>long</code>. Length and all values
     * are compared.
     * </p>
     * <p>
     * The method {@link #append(long, long)} is used.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>long[]</code>
     * @param rhs
     *            the right hand <code>long[]</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( long[] lhs, long[] rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        if ( lhs == rhs )
        {
            return this;
        }
        if ( lhs == null || rhs == null )
        {
            this.setEquals( false );
            return this;
        }
        if ( lhs.length != rhs.length )
        {
            this.setEquals( false );
            return this;
        }
        for ( int i = 0; i < lhs.length && isEquals; ++i )
        {
            append( lhs[i], rhs[i] );
        }
        return this;
    }


    /**
     * <p>
     * Deep comparison of array of <code>int</code>. Length and all values
     * are compared.
     * </p>
     * <p>
     * The method {@link #append(int, int)} is used.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>int[]</code>
     * @param rhs
     *            the right hand <code>int[]</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( int[] lhs, int[] rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        if ( lhs == rhs )
        {
            return this;
        }
        if ( lhs == null || rhs == null )
        {
            this.setEquals( false );
            return this;
        }
        if ( lhs.length != rhs.length )
        {
            this.setEquals( false );
            return this;
        }
        for ( int i = 0; i < lhs.length && isEquals; ++i )
        {
            append( lhs[i], rhs[i] );
        }
        return this;
    }


    /**
     * <p>
     * Deep comparison of array of <code>short</code>. Length and all values
     * are compared.
     * </p>
     * <p>
     * The method {@link #append(short, short)} is used.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>short[]</code>
     * @param rhs
     *            the right hand <code>short[]</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( short[] lhs, short[] rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        if ( lhs == rhs )
        {
            return this;
        }
        if ( lhs == null || rhs == null )
        {
            this.setEquals( false );
            return this;
        }
        if ( lhs.length != rhs.length )
        {
            this.setEquals( false );
            return this;
        }
        for ( int i = 0; i < lhs.length && isEquals; ++i )
        {
            append( lhs[i], rhs[i] );
        }
        return this;
    }


    /**
     * <p>
     * Deep comparison of array of <code>char</code>. Length and all values
     * are compared.
     * </p>
     * <p>
     * The method {@link #append(char, char)} is used.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>char[]</code>
     * @param rhs
     *            the right hand <code>char[]</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( char[] lhs, char[] rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        if ( lhs == rhs )
        {
            return this;
        }
        if ( lhs == null || rhs == null )
        {
            this.setEquals( false );
            return this;
        }
        if ( lhs.length != rhs.length )
        {
            this.setEquals( false );
            return this;
        }
        for ( int i = 0; i < lhs.length && isEquals; ++i )
        {
            append( lhs[i], rhs[i] );
        }
        return this;
    }


    /**
     * <p>
     * Deep comparison of array of <code>byte</code>. Length and all values
     * are compared.
     * </p>
     * <p>
     * The method {@link #append(byte, byte)} is used.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>byte[]</code>
     * @param rhs
     *            the right hand <code>byte[]</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( byte[] lhs, byte[] rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        if ( lhs == rhs )
        {
            return this;
        }
        if ( lhs == null || rhs == null )
        {
            this.setEquals( false );
            return this;
        }
        if ( lhs.length != rhs.length )
        {
            this.setEquals( false );
            return this;
        }
        for ( int i = 0; i < lhs.length && isEquals; ++i )
        {
            append( lhs[i], rhs[i] );
        }
        return this;
    }


    /**
     * <p>
     * Deep comparison of array of <code>double</code>. Length and all values
     * are compared.
     * </p>
     * <p>
     * The method {@link #append(double, double)} is used.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>double[]</code>
     * @param rhs
     *            the right hand <code>double[]</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( double[] lhs, double[] rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        if ( lhs == rhs )
        {
            return this;
        }
        if ( lhs == null || rhs == null )
        {
            this.setEquals( false );
            return this;
        }
        if ( lhs.length != rhs.length )
        {
            this.setEquals( false );
            return this;
        }
        for ( int i = 0; i < lhs.length && isEquals; ++i )
        {
            append( lhs[i], rhs[i] );
        }
        return this;
    }


    /**
     * <p>
     * Deep comparison of array of <code>float</code>. Length and all values
     * are compared.
     * </p>
     * <p>
     * The method {@link #append(float, float)} is used.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>float[]</code>
     * @param rhs
     *            the right hand <code>float[]</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( float[] lhs, float[] rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        if ( lhs == rhs )
        {
            return this;
        }
        if ( lhs == null || rhs == null )
        {
            this.setEquals( false );
            return this;
        }
        if ( lhs.length != rhs.length )
        {
            this.setEquals( false );
            return this;
        }
        for ( int i = 0; i < lhs.length && isEquals; ++i )
        {
            append( lhs[i], rhs[i] );
        }
        return this;
    }


    /**
     * <p>
     * Deep comparison of array of <code>boolean</code>. Length and all
     * values are compared.
     * </p>
     * <p>
     * The method {@link #append(boolean, boolean)} is used.
     * </p>
     * 
     * @param lhs
     *            the left hand <code>boolean[]</code>
     * @param rhs
     *            the right hand <code>boolean[]</code>
     * @return EqualsBuilder - used to chain calls.
     */
    public EqualsBuilder append( boolean[] lhs, boolean[] rhs )
    {
        if ( isEquals == false )
        {
            return this;
        }
        if ( lhs == rhs )
        {
            return this;
        }
        if ( lhs == null || rhs == null )
        {
            this.setEquals( false );
            return this;
        }
        if ( lhs.length != rhs.length )
        {
            this.setEquals( false );
            return this;
        }
        for ( int i = 0; i < lhs.length && isEquals; ++i )
        {
            append( lhs[i], rhs[i] );
        }
        return this;
    }


    /**
     * <p>
     * Returns <code>true</code> if the fields that have been checked are all
     * equal.
     * </p>
     * 
     * @return boolean
     */
    public boolean isEquals()
    {
        return this.isEquals;
    }


    /**
     * Sets the <code>isEquals</code> value.
     * 
     * @param isEquals
     *            The value to set.
     */
    protected void setEquals( boolean isEquals )
    {
        this.isEquals = isEquals;
    }
}
