/**
  * Implements logical AND between the comparators results. Iterates through the comparators chain
  * until one of them returns false. If none returns false, this method returns true.
  *
  * @see EquivalenceComparator#equivalenceCompare(Object, Object, Object, Object)
  */
 public boolean equivalenceCompare(E arg1, E arg2, C context1, C context2) {
   for (EquivalenceComparator<? super E, ? super C> currentComparator : this.chain) {
     if (!currentComparator.equivalenceCompare(arg1, arg2, context1, context2)) {
       return false;
     }
   }
   return true;
 }
  /**
   * Rehashes the concatenation of the results of all single hashcodes.
   *
   * @see EquivalenceComparator#equivalenceHashcode(Object, Object)
   */
  public int equivalenceHashcode(E arg1, C context) {
    StringBuffer hashStringBuffer = new StringBuffer();
    for (ListIterator<EquivalenceComparator<? super E, ? super C>> iter = this.chain.listIterator();
        iter.hasNext(); ) {
      EquivalenceComparator<? super E, ? super C> currentComparator = iter.next();
      int currentHashCode = currentComparator.equivalenceHashcode(arg1, context);
      hashStringBuffer.append(currentHashCode);

      // add a delimeter only if needed for next
      if (iter.hasNext()) {
        hashStringBuffer.append('+');
      }
    }
    return hashStringBuffer.toString().hashCode();
  }