/*
 * 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     https://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 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package org.apache.jdo.tck.util;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This is a utility class to support equality checking. An EqualityHelper object defines the
 * context of a deepEquals call, because it keeps track of objects that have already been processed.
 * This avoids endless recursion when comparing cyclic data structures for deep equality.
 *
 * <p>Furthermore, EqualityHelper provides convenience methods for checking deep equality, equality
 * and close enough (for floating point values).
 *
 * @author Michael Bouschen
 * @since 1.1
 */
public class EqualityHelper {

  /** Logger */
  protected final Log logger = LogFactory.getFactory().getInstance("org.apache.jdo.tck");

  /** true if debug logging in enabled. */
  protected boolean debug = logger.isDebugEnabled();

  /** Used when comparing float values close enough. */
  public static final float FLOAT_EPSILON = (float) Math.pow(2.0, -20.0);

  /** Used when comparing double values close enough. */
  public static final double DOUBLE_EPSILON = Math.pow(2.0, -52.0);

  /** Message for null vs. not null */
  static final String MSG_ME_NULL = "\nExpected null, actual not null";

  /** Message for not null vs. null */
  static final String MSG_OTHER_NULL = "\nExpected not null, actual null";

  /** Message for incompatible types */
  static final String MSG_INCOMPATIBLE_TYPES = "\nIncompatible types for comparison";

  /** Message for wrong class for counting via iterator */
  static final String MSG_PARAMETER_MUST_BE_COLLECTION_OR_MAP =
      "Parameter must be a Collection or Map.";

  /**
   * Comparator used in method deepEquals comparing maps. This comparator is used to order Maps
   * whose keys are Comparable so the entries can be compared using deepCompareFields.
   */
  @SuppressWarnings("unchecked")
  private static final Comparator<Map.Entry<?, ?>> entryKeyComparator =
      (o1, o2) -> {
        Object key1 = o1.getKey();
        Object key2 = o2.getKey();
        return ((Comparable<Object>) key1).compareTo(key2);
      };

  /** Utility counter for maps and collections */
  static int countIterator(Object o) {
    int result = 0;
    Iterator<?> it;
    if (o instanceof Collection) {
      it = ((Collection<?>) o).iterator();
    } else if (o instanceof Map) {
      it = ((Map<?, ?>) o).entrySet().iterator();
    } else {
      throw new ClassCastException(MSG_PARAMETER_MUST_BE_COLLECTION_OR_MAP);
    }
    while (it.hasNext()) {
      it.next();
      result++;
    }
    return result;
  }
  /** Comparator used in method deepEquals comparing maps of DeepEquality. */
  private static class DeepEqualityEntryKeyComparator<K, V> implements Comparator<Map.Entry<K, V>> {
    final Comparator<K> comparator;

    DeepEqualityEntryKeyComparator(Comparator<K> comp) {
      this.comparator = comp;
    }

    public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
      K key1 = o1.getKey();
      K key2 = o2.getKey();
      return comparator.compare(key1, key2);
    }
  }

  /**
   * Collection of instances that have been processed already in the context of this EqualityHelper
   * instance
   */
  private final Collection<Object> processed = new HashSet<>();

  /** StringBuffer of logged differences. */
  final StringBuffer unequalBuffer = new StringBuffer();

  /** Context is a stack of navigational paths. */
  final Stack<String> contextStack = new Stack<>();

  // Methods to support keeping track of instances that have been
  // processed already.

  /**
   * Returns <code>true</code> if the specified instance has been processed already in the context
   * of this <code>EqualityHelper</code>.
   *
   * @param obj the instance to be checked.
   * @return <code>true</code> if the instance has been processed already; <code>false</code>
   *     otherwise.
   */
  public boolean isProcessed(Object obj) {
    return processed.contains(obj);
  }

  /**
   * Marks the specified instance as processed in the context of this <code>EqualityHelper</code>.
   * This means the instance is added to the collection of processed instances.
   *
   * @param obj instance marked as processed
   */
  public void markProcessed(Object obj) {
    processed.add(obj);
  }

  /**
   * Clears the collection of processed instances of this <code>EqualityHelper</code>. No instance
   * is marked as processed in the context of this <code>EqualityHelper</code> after calling this
   * method.
   */
  public void clearProcessed() {
    processed.clear();
  }

  // Deep equality support methods

  /**
   * Returns <code>true</code> if the specified instances are "deep equal".
   *
   * @param me one object to be tested for deep equality
   * @param other the other object to be tested for deep equality
   * @return <code>true</code> if the objects are deep equal.
   */
  public boolean deepEquals(DeepEquality me, DeepEquality other) {
    if (me == other) return true;
    if ((me == null) || (other == null)) return false;
    if (isProcessed(me)) return true;
    markProcessed(me);
    return me.deepCompareFields(other, this);
  }

  /**
   * Returns <code>true</code> if the specified instances are "deep equal". The method compares the
   * two instances via the deepEquals method if they implement DeepEquals; compares the two
   * instances via deepEquals if they implement Collection or Map, and otherwise compares the
   * instances using equals.
   *
   * @param me one object to be tested for deep equality
   * @param other the other object to be tested for deep equality
   * @return <code>true</code> if the objects are deep equal.
   */
  @SuppressWarnings({"unchecked", "rawtypes"})
  public boolean deepEquals(Object me, Object other) {
    if (me == other) return true;
    if ((me == null) || (other == null)) return false;
    if ((me instanceof DeepEquality) && (other instanceof DeepEquality))
      return deepEquals((DeepEquality) me, (DeepEquality) other);
    if ((me instanceof Collection<?>) && (other instanceof Collection<?>))
      return deepEquals((Collection) me, (Collection) other);
    if ((me instanceof Map<?, ?>) && (other instanceof Map<?, ?>))
      return deepEquals((Map) me, (Map) other);
    return me.equals(other);
  }

  /**
   * Returns <code>true</code> if the specified collections are "deep equal". Two collections are
   * deep equal, if they have the same size and their corresponding elements are deep equal after
   * sorting using the natural ordering of the elements. The method throws a <code>
   * ClassCastException</code> if the elements are not Comparable or if they are not mutually
   * comparable.
   *
   * @param mine one collection to be tested for deep equality
   * @param other the other collection to be tested for deep equality
   * @return <code>true</code> if the collections are deep equal.
   * @throws ClassCastException if the collections contain elements that are not mutually
   *     comparable.
   */
  @SuppressWarnings("unchecked")
  public <T extends Comparable<T>> boolean deepEquals(Collection<T> mine, Collection<T> other) {
    if (mine == other) return true;
    if ((mine == null) || (other == null)) return false;

    // Return false, if the size differs
    if (mine.size() != other.size()) return false;

    if (mine.size() == 0) return true;

    // Now check the elements
    List<T> myList = new ArrayList<>(mine);
    Collections.sort(myList);
    List<T> otherList = new ArrayList<>(other);
    /* Any collection of elements to be compared must implement Comparator
     * to avoid the other side having to implement Comparable. */
    Comparator<T> comparator = (Comparator<T>) myList.get(0);
    Collections.sort(otherList, comparator);
    for (int i = 0; i < myList.size(); i++) {
      if (!deepEquals(myList.get(i), otherList.get(i))) return false;
    }
    return true;
  }

  /**
   * Returns <code>true</code> if the specified maps are "deep equal". Two maps are deep equal, if
   * they have the same size and the values of the corresponding keys compare deep equal. The method
   * throws a <code>ClassCastException</code> if keys or values are not Comparable or if they are
   * not mutually comparable.
   *
   * @param mine one map to be tested for deep equality
   * @param other the other map to be tested for deep equality
   * @return <code>true</code> if the maps are deep equal.
   * @throws ClassCastException if the maps contain keys or values that are not mutually comparable.
   */
  @SuppressWarnings("unchecked")
  public <K, V> boolean deepEquals(Map<K, V> mine, Map<K, V> other) {
    if (mine == other) return true;
    if ((mine == null) || (other == null)) return false;

    // Return false, if the size differs
    if (mine.size() != other.size()) return false;

    if (mine.size() == 0) return true;

    // Now check the elements
    List<Map.Entry<K, V>> myList = new ArrayList<>(mine.entrySet());
    Collections.sort(myList, entryKeyComparator);
    List<Map.Entry<K, V>> otherList = new ArrayList<>(other.entrySet());
    /* Any collection of elements to be compared must implement Comparator
     * to avoid the other side having to implement Comparable. */
    Comparator<K> comparator = (Comparator<K>) ((Map.Entry<V, K>) myList.get(0)).getKey();
    Collections.sort(otherList, new DeepEqualityEntryKeyComparator<>(comparator));

    for (int i = 0; i < myList.size(); i++) {
      Map.Entry<K, V> entry1 = myList.get(i);
      Map.Entry<K, V> entry2 = otherList.get(i);
      // compare the keys
      if (!deepEquals(entry1.getKey(), entry2.getKey())) return false;
      // compare the values
      if (!deepEquals(entry1.getValue(), entry2.getValue())) return false;
    }
    return true;
  }

  // Shallow equality support methods

  /**
   * Returns <code>true</code> if the specified collections are "shallow equal". Two collections are
   * shallow equal, if they have the same size and their corresponding elements are equal after
   * sorting using the natural ordering.
   *
   * @param mine one collection to be tested for shallow equality
   * @param other the other collection to be tested for shallow equality
   * @return <code>true</code> if the collections are deep equal.
   */
  @SuppressWarnings("unchecked")
  public <T extends Comparable<T>> boolean shallowEquals(Collection<T> mine, Collection<T> other) {
    if (mine == other) return true;
    if ((mine == null) || (other == null)) return false;

    // Return false, if the size differs
    if (mine.size() != other.size()) return false;

    if (mine.size() == 0) return true;

    // Now check the elements
    List<T> myList = new ArrayList<>(mine);
    Collections.sort(myList);
    List<T> otherList = new ArrayList<>(other);
    /* Any collection of elements to be compared must implement Comparator
     * to avoid the other side having to implement Comparable. */
    Comparator<T> comparator = (Comparator<T>) myList.get(0);
    Collections.sort(otherList, comparator);
    return myList.equals(otherList);
  }

  // Deep equality support methods with logging

  public String getUnequalBuffer() {
    return unequalBuffer.toString();
  }

  /** Context is nested via navigation through relationships. */
  void pushContext(String ctx) {
    contextStack.push(ctx);
  }

  String popContext() {
    return contextStack.pop();
  }

  /**
   * Log differences between objects that don't compare equal.
   *
   * @param o1 the first object
   * @param o2 the second object
   * @param where the field where the objects are found
   */
  void logUnequal(Object o1, Object o2, String where) {
    unequalBuffer.append("Context: ");
    Iterator<String> it = contextStack.iterator();
    StringBuilder offset = new StringBuilder("\n");
    while (it.hasNext()) {
      unequalBuffer.append(it.next());
      unequalBuffer.append("-> ");
      offset.append("    ");
    }
    unequalBuffer.append(where);
    unequalBuffer.append(offset);
    unequalBuffer.append("expected '");
    unequalBuffer.append(o1);
    unequalBuffer.append("'");
    unequalBuffer.append(offset);
    unequalBuffer.append("  actual '");
    unequalBuffer.append(o2);
    unequalBuffer.append("'\n");
  }

  /**
   * Returns <code>true</code> if the specified instances are "deep equal". If unequal, log the
   * location of the inequality.
   *
   * @param me one object to be tested for deep equality
   * @param other the other object to be tested for deep equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the objects are deep equal.
   */
  public boolean deepEquals(DeepEquality me, Object other, String where) {
    if (me == other) return true;
    if (me == null) {
      logUnequal(me, other, where + MSG_ME_NULL);
      return false;
    }
    if (other == null) {
      logUnequal(me, other, where + MSG_OTHER_NULL);
      return false;
    }
    if (isProcessed(me)) return true;
    markProcessed(me);
    pushContext(where);
    boolean result = true;
    if (!me.deepCompareFields(other, this)) {
      // logUnequal(me, other, where);
      result = false;
    }
    popContext();
    return result;
  }

  /**
   * Returns <code>true</code> if the specified instances are "deep equal". The method compares the
   * two instances via the deepEquals method if they implement DeepEquals; compares the two
   * instances via deepEquals if they implement Collection or Map, and otherwise compares the
   * instances using equals.
   *
   * @param me one object to be tested for deep equality
   * @param other the other object to be tested for deep equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the objects are deep equal.
   */
  @SuppressWarnings({"unchecked", "rawtypes"})
  public boolean deepEquals(Object me, Object other, String where) {
    if (me == other) return true;
    if (me == null) {
      logUnequal(me, other, where + MSG_ME_NULL);
      return false;
    }
    if (other == null) {
      logUnequal(me, other, where + MSG_OTHER_NULL);
      return false;
    }
    if (me instanceof DeepEquality) {
      return deepEquals((DeepEquality) me, other, where);
    } else if ((me instanceof Collection<?>) && (other instanceof Collection<?>)) {
      return deepEqualsCollection((Collection) me, (Collection) other, where);
    } else if ((me instanceof Map<?, ?>) && (other instanceof Map<?, ?>)) {
      return deepEqualsMap((Map) me, (Map) other, where);
    } else {
      return equals(me, other, where);
    }
  }

  /**
   * Returns <code>true</code> if the specified collections are "deep equal". Two collections are
   * deep equal, if they have the same size and their corresponding elements are deep equal after
   * sorting using the natural ordering of the elements. The method throws a <code>
   * ClassCastException</code> if the elements are not Comparable or if they are not mutually
   * comparable.
   *
   * @param me one collection to be tested for deep equality
   * @param other the other collection to be tested for deep equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the collections are deep equal.
   * @throws ClassCastException if the collections contain elements that are not mutually
   *     comparable.
   */
  @SuppressWarnings("unchecked")
  public <S extends Comparable<S>, T> boolean deepEqualsCollection(
      Collection<S> me, Collection<T> other, String where) {
    if (me == other) return true;
    if (me == null) {
      logUnequal(me, other, where + MSG_ME_NULL);
      return false;
    }
    if (other == null) {
      logUnequal(me, other, where + MSG_OTHER_NULL);
      return false;
    }
    int mysize = me.size();
    int othersize = other.size();
    // Return false, if the size differs
    if (mysize != othersize) {
      int count = countIterator(other);
      logUnequal(
          me,
          other,
          where
              + "\nSize mismatch: expected size= "
              + me.size()
              + ", original size= "
              + othersize
              + ", current size= "
              + other.size()
              + ", counted size= "
              + count);
      return false;
    }

    if (mysize == 0) return true;

    // Now check each element for equality or deep equality
    List<S> myList = new ArrayList<>(me);
    // Use the natural ordering of me; must implement Comparable
    Collections.sort(myList);
    List<T> otherList = new ArrayList<>(other);
    /* Any collection of elements to be compared must implement Comparator
     * to avoid the other side having to implement Comparable. */
    Comparator<T> comparator = (Comparator<T>) myList.get(0);
    otherList.sort(comparator);
    boolean result = true;
    for (int i = 0; i < myList.size(); i++) {
      DeepEquality o1 = (DeepEquality) myList.get(i);
      Object o2 = otherList.get(i);
      /* Compare corresponding elements of the ordered list. */
      if (!deepEquals(o1, o2, where + "[" + i + "]")) {
        result = false;
      }
    }
    return result;
  }

  /**
   * Returns <code>true</code> if the specified maps are "deep equal". Two maps are deep equal, if
   * they have the same size and the values of the corresponding keys compare deep equal. The method
   * throws a <code>ClassCastException</code> if keys or values are not Comparable or if they are
   * not mutually comparable.
   *
   * @param me one map to be tested for deep equality
   * @param other the other map to be tested for deep equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the maps are deep equal.
   * @throws ClassCastException if the maps contain keys or values that are not mutually comparable.
   */
  @SuppressWarnings({"unchecked", "rawtypes"})
  public <K, V> boolean deepEqualsMap(Map<K, V> me, Map<K, V> other, String where) {
    if (me == other) return true;
    if (me == null) {
      logUnequal(me, other, where + MSG_ME_NULL);
      return false;
    }
    if (other == null) {
      logUnequal(me, other, where + MSG_OTHER_NULL);
      return false;
    }

    // Return false, if the size differs
    int mysize = me.size();
    int othersize = other.size();
    if (mysize != othersize) {
      int count = countIterator(other);
      logUnequal(
          me,
          other,
          where
              + "\nSize mismatch: expected size= "
              + me.size()
              + ", original size= "
              + othersize
              + ", current size= "
              + other.size()
              + ", counted size= "
              + count);
      return false;
    }

    if (mysize == 0) return true;

    // Now check the elements
    List<Map.Entry<K, V>> myList = new ArrayList<>(me.entrySet());
    // Use the natural ordering of me; must implement Comparable
    Collections.sort(myList, entryKeyComparator);
    List<Map.Entry<K, V>> otherList = new ArrayList<>(other.entrySet());
    Comparator<Map.Entry<?, ?>> comparator = entryKeyComparator;
    // Use the Comparator to avoid the other side implementing Comparable
    Object key = myList.get(0).getKey();
    if (key instanceof Comparator) {
      comparator = new DeepEqualityEntryKeyComparator((Comparator) key);
    }
    Collections.sort(otherList, comparator);

    boolean result = true;
    for (int i = 0; i < myList.size(); i++) {
      Map.Entry<K, V> entry1 = myList.get(i);
      Object key1 = entry1.getKey();
      Object value1 = entry1.getValue();
      Map.Entry<K, V> entry2 = otherList.get(i);
      K key2 = entry2.getKey();
      V value2 = entry2.getValue();
      // compare the keys
      if (!deepEquals(key1, key2, where + "[" + i + "].key")) {
        result = false;
      }
      // compare the values
      if (!deepEquals(value1, value2, where + "[" + i + "].value")) {
        result = false;
      }
    }
    return result;
  }

  // Shallow equality support methods

  /**
   * Returns <code>true</code> if the specified collections are "shallow equal". Two collections are
   * shallow equal, if they have the same size and their corresponding elements are equal after
   * sorting using the natural ordering.
   *
   * @param me one collection to be tested for shallow equality
   * @param other the other collection to be tested for shallow equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the collections are deep equal.
   */
  @SuppressWarnings("unchecked")
  public <T extends Comparable<T>> boolean shallowEquals(
      Collection<T> me, Collection<T> other, String where) {
    if (me == other) return true;
    if (me == null) {
      logUnequal(me, other, where + MSG_ME_NULL);
      return false;
    }
    if (other == null) {
      logUnequal(me, other, where + MSG_OTHER_NULL);
      return false;
    }

    // Return false, if the size differs
    int mysize = me.size();
    int othersize = other.size();
    if (mysize != othersize) {
      // debug size...
      Iterator<T> it = other.iterator();
      int count = 0;
      while (it.hasNext()) {
        it.next();
        ++count;
      }
      logUnequal(
          me,
          other,
          where
              + "\nSize mismatch: expected size= "
              + me.size()
              + ", original size= "
              + othersize
              + ", current size= "
              + other.size()
              + ", counted size= "
              + count);
      return false;
    }

    if (me.size() == 0) return true;

    // Now check the elements
    List<T> myList = new ArrayList<>(me);
    Collections.sort(myList);
    List<T> otherList = new ArrayList<>(other);
    /* Any collection of elements to be compared must implement Comparator
     * to avoid the other side having to implement Comparable. */
    Comparator<T> comparator = (Comparator<T>) myList.get(0);
    Collections.sort(otherList, comparator);
    boolean result = myList.equals(otherList);
    if (!result) logUnequal(me, other, where + "\nCollections do not compare equal");
    return result;
  }

  // Equality support methods

  /**
   * Returns <code>true</code> if the specified objects are equal. This is a helper method checking
   * for identical and <code>null</code> objects before delegating to the regular equals method.
   *
   * @param o1 one object to be tested for equality
   * @param o2 the other object to be tested for equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the specified objects are equal.
   */
  public boolean equals(Object o1, Object o2, String where) {
    if (o1 == o2) return true;
    if (o1 == null) {
      logUnequal(o1, o2, where + MSG_ME_NULL);
      return false;
    }
    if (o2 == null) {
      logUnequal(o1, o2, where + MSG_OTHER_NULL);
      return false;
    }
    if (!o1.equals(o2)) {
      logUnequal(o1, o2, where);
      return false;
    }
    return true;
  }

  /**
   * Returns <code>true</code>, if compare called for the specified BigDecimal objects returns
   * <code>0</code>. Please note, two BigDecimal instances are not equal (using equals) if their
   * scale differs, and this method compares the values, ignoring scale.
   *
   * @param o1 one object to be tested for equality
   * @param o2 the other object to be tested for equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the specified BigDecimal objects are equal.
   */
  public boolean equals(BigDecimal o1, BigDecimal o2, String where) {
    if (o1 == o2) return true;
    if ((o1 == null) || (o2 == null)) {
      logUnequal(o1, o2, where);
      return false;
    }
    boolean result = o1.equals(o2);
    if (!result) logUnequal(o1, o2, where);
    return result;
  }

  /**
   * Returns <code>true</code>, if two parameters are equal.
   *
   * @param p1 one to be tested for equality
   * @param p2 the other to be tested for equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the parameters are equal.
   */
  public boolean equals(boolean p1, boolean p2, String where) {
    if (p1 != p2) {
      logUnequal(Boolean.toString(p1), Boolean.toString(p2), where);
      return false;
    }
    return true;
  }

  /**
   * Returns <code>true</code>, if two parameters are equal.
   *
   * @param p1 one to be tested for equality
   * @param p2 the other to be tested for equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the parameters are equal.
   */
  public boolean equals(char p1, char p2, String where) {
    if (p1 != p2) {
      logUnequal(Character.toString(p1), Character.toString(p2), where);
      return false;
    }
    return true;
  }

  /**
   * Returns <code>true</code>, if two parameters are equal.
   *
   * @param p1 one to be tested for equality
   * @param p2 the other to be tested for equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the parameters are equal.
   */
  public boolean equals(byte p1, byte p2, String where) {
    if (p1 != p2) {
      logUnequal(Byte.toString(p1), Byte.toString(p2), where);
      return false;
    }
    return true;
  }

  /**
   * Returns <code>true</code>, if two parameters are equal.
   *
   * @param p1 one to be tested for equality
   * @param p2 the other to be tested for equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the parameters are equal.
   */
  public boolean equals(short p1, short p2, String where) {
    if (p1 != p2) {
      logUnequal(Short.toString(p1), Short.toString(p2), where);
      return false;
    }
    return true;
  }

  /**
   * Returns <code>true</code>, if two parameters are equal.
   *
   * @param p1 one to be tested for equality
   * @param p2 the other to be tested for equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the parameters are equal.
   */
  public boolean equals(int p1, int p2, String where) {
    if (p1 != p2) {
      logUnequal(Integer.toString(p1), Integer.toString(p2), where);
      return false;
    }
    return true;
  }

  /**
   * Returns <code>true</code>, if two parameters are equal.
   *
   * @param p1 one to be tested for equality
   * @param p2 the other to be tested for equality
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the parameters are equal.
   */
  public boolean equals(long p1, long p2, String where) {
    if (p1 != p2) {
      logUnequal(Long.toString(p1), Long.toString(p2), where);
      return false;
    }
    return true;
  }

  /**
   * Returns <code>true</code> if the specified objects are equal. This is a helper method checking
   * for identical and <code>null</code> objects before delegating to the regular equals method.
   *
   * @param o1 one object to be tested for equality
   * @param o2 the other object to be tested for equality
   * @return <code>true</code> if the specified objects are equal.
   */
  public static boolean equals(Object o1, Object o2) {
    if (o1 == o2) {
      return true;
    }
    if (o1 == null || o2 == null) {
      return false;
    }
    return o1.equals(o2);
  }

  // Methods to support "close enough" comparison

  /**
   * Returns <code>true</code> if the specified objects are close enough to be considered to be
   * equal for a deep equals comparison. The method delegates to the method taking double or float
   * values if the specified objects are Float or Double wrappers. Otherwise it delegates to equals.
   *
   * @param o1 one object to be tested for close enough
   * @param o2 the other object to be tested for close enough
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the specified values are close enough.
   */
  public boolean closeEnough(Object o1, Object o2, String where) {
    if (o1 == o2) return true;
    if ((o1 == null) || (o2 == null)) {
      logUnequal(o1, o2, where);
      return false;
    }
    boolean result = true;
    if ((o1 instanceof Double) && (o2 instanceof Double)) {
      return closeEnough(((Double) o1).doubleValue(), ((Double) o2).doubleValue(), where);
    } else if ((o1 instanceof Float) && (o2 instanceof Float)) {
      return closeEnough(((Float) o1).floatValue(), ((Float) o2).floatValue(), where);
    } else if ((o1 instanceof BigDecimal) && (o2 instanceof BigDecimal)) {
      return ((BigDecimal) o1).compareTo((BigDecimal) o2) == 0;
    } else {
      result = o1.equals(o2);
    }
    if (!result) logUnequal(o1, o2, where);
    return result;
  }

  /**
   * Returns <code>true</code> if the specified float values are close enough to be considered to be
   * equal for a deep equals comparison. Floating point values are not exact, so comparing them
   * using <code>==</code> might not return useful results. This method checks that both double
   * values are within some percent of each other.
   *
   * @param d1 one double to be tested for close enough
   * @param d2 the other double to be tested for close enough
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the specified values are close enough.
   */
  public boolean closeEnough(double d1, double d2, String where) {
    if (d1 == d2) return true;

    double diff = Math.abs(d1 - d2);
    boolean result = diff < Math.abs((d1 + d2) * DOUBLE_EPSILON);
    if (!result) logUnequal(Double.toString(d1), Double.toString(d2), where);
    return result;
  }

  /**
   * Returns <code>true</code> if the specified float values are close enough to be considered to be
   * equal for a deep equals comparison. Floating point values are not exact, so comparing them
   * using <code>==</code> might not return useful results. This method checks that both float
   * values are within some percent of each other.
   *
   * @param f1 one float to be tested for close enough
   * @param f2 the other float to be tested for close enough
   * @param where the location of the inequality (provided by the caller)
   * @return <code>true</code> if the specified values are close enough.
   */
  public boolean closeEnough(float f1, float f2, String where) {
    if (f1 == f2) return true;

    float diff = Math.abs(f1 - f2);
    boolean result = diff < Math.abs((f1 + f2) * FLOAT_EPSILON);
    if (!result) logUnequal(Float.toString(f1), Float.toString(f2), where);
    return result;
  }

  // Methods to support compare methods as specified in Comparator

  /**
   * Compares its two arguments for order. Returns a negative integer, zero, or a positive integer
   * as the first argument is less than, equal to, or greater than the second.
   *
   * @param l1 the first long to be compared
   * @param l2 the second long to be compared
   * @return a negative integer, zero, or a positive integer as the first argument is less than,
   *     equal to, or greater than the second.
   */
  public static int compare(long l1, long l2) {
    return (Long.compare(l1, l2));
  }
}
