/**
  * Assert that the given object is lenient equals by ignoring fields.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param other the object to compare {@code actual} to.
  * @param fields the fields to ignore in comparison
  * @throws NullPointerException if the actual type is {@code null}.
  * @throws NullPointerException if the other type is {@code null}.
  * @throws AssertionError if the actual and the given object are not lenient equals.
  * @throws AssertionError if the other object is not an instance of the actual type.
  */
 public <A> void assertIsLenientEqualsToByIgnoringFields(
     AssertionInfo info, A actual, A other, String... fields) {
   assertIsInstanceOf(info, other, actual.getClass());
   List<String> fieldsNames = new LinkedList<String>();
   List<Object> expectedValues = new LinkedList<Object>();
   Set<String> ignoredFields = set(fields);
   for (Field field : actual.getClass().getDeclaredFields()) {
     try {
       if (!ignoredFields.contains(field.getName())) {
         String fieldName = field.getName();
         Object actualFieldValue = propertySupport.propertyValue(fieldName, Object.class, actual);
         Object otherFieldValue = propertySupport.propertyValue(fieldName, Object.class, other);
         if (!org.fest.util.Objects.areEqual(actualFieldValue, otherFieldValue)) {
           fieldsNames.add(fieldName);
           expectedValues.add(otherFieldValue);
         }
       }
     } catch (IntrospectionError e) {
       // Not readeable field, skip.
     }
   }
   if (fieldsNames.isEmpty()) return;
   throw failures.failure(
       info, shouldBeLenientEqualByIgnoring(actual, fieldsNames, expectedValues, list(fields)));
 }
 /**
  * Assert that the given object is lenient equals by ignoring null fields value on other object.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param other the object to compare {@code actual} to.
  * @throws NullPointerException if the actual type is {@code null}.
  * @throws NullPointerException if the other type is {@code null}.
  * @throws AssertionError if the actual and the given object are not lenient equals.
  * @throws AssertionError if the other object is not an instance of the actual type.
  */
 public <A> void assertIsLenientEqualsToByIgnoringNullFields(
     AssertionInfo info, A actual, A other) {
   assertIsInstanceOf(info, other, actual.getClass());
   List<String> fieldsNames = new LinkedList<String>();
   List<Object> values = new LinkedList<Object>();
   List<String> nullFields = new LinkedList<String>();
   for (Field field : actual.getClass().getDeclaredFields()) {
     try {
       Object otherFieldValue =
           propertySupport.propertyValue(field.getName(), field.getType(), other);
       if (otherFieldValue != null) {
         Object actualFieldValue =
             propertySupport.propertyValue(field.getName(), field.getType(), actual);
         if (!otherFieldValue.equals(actualFieldValue)) {
           fieldsNames.add(field.getName());
           values.add(otherFieldValue);
         }
       } else {
         nullFields.add(field.getName());
       }
     } catch (IntrospectionError e) {
       // Not readeable field, skip.
     }
   }
   if (fieldsNames.isEmpty()) return;
   throw failures.failure(
       info, shouldBeLenientEqualByIgnoring(actual, fieldsNames, values, nullFields));
 }
 /**
  * Verifies that the actual value is not exactly a instance of given type.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param type the type to check the actual value against.
  * @throws AssertionError if the actual is exactly a instance of given type.
  * @throws NullPointerException if the actual value is null.
  * @throws NullPointerException if the given object is null.
  */
 public void assertIsNotExactlyInstanceOf(AssertionInfo info, Object actual, Class<?> type) {
   assertNotNull(info, actual);
   if (type == null) throw new NullPointerException("The given type should not be null");
   Class<?> current = actual.getClass();
   if (!type.equals(current)) return;
   throw failures.failure(info, shouldNotBeExactlyInstance(actual, type));
 }
 /**
  * Verifies that the actual value does not have the same class as the given object.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param other the object to check type against.
  * @throws AssertionError if the actual has the same type has the given object.
  * @throws NullPointerException if the actual value is null.
  * @throws NullPointerException if the given object is null.
  */
 public void assertDoesNotHaveSameClassAs(AssertionInfo info, Object actual, Object other) {
   assertNotNull(info, actual);
   if (other == null) throw new NullPointerException("The given object should not be null");
   Class<?> actualClass = actual.getClass();
   Class<?> otherClass = other.getClass();
   if (!actualClass.equals(otherClass)) return;
   throw failures.failure(info, shouldNotHaveSameClass(actual, other));
 }
 /**
  * Verifies that the given object is not an instance of any of the given types.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param types the types to check the given object against.
  * @throws NullPointerException if the given array is {@code null}.
  * @throws IllegalArgumentException if the given array is empty.
  * @throws NullPointerException if the given array has {@code null} elements.
  * @throws AssertionError if the given object is {@code null}.
  * @throws AssertionError if the given object is an instance of any of the given types.
  */
 public void assertIsNotInstanceOfAny(AssertionInfo info, Object actual, Class<?>[] types) {
   checkIsNotNullAndIsNotEmpty(types);
   assertNotNull(info, actual);
   boolean found = false;
   for (Class<?> type : types) {
     if (type == null) {
       String format = "The given array of types:<%s> should not have null elements";
       throw new NullPointerException(String.format(format, toStringOf(types)));
     }
     if (type.isInstance(actual)) {
       found = true;
       break;
     }
   }
   if (!found) return;
   throw failures.failure(info, shouldNotBeInstanceOfAny(actual, types));
 }
 /**
  * Assert that the given object is lenient equals to other object by comparing given fields value
  * only.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param other the object to compare {@code actual} to.
  * @param fields accepted fields
  * @throws NullPointerException if the actual type is {@code null}.
  * @throws NullPointerException if the other type is {@code null}.
  * @throws AssertionError if the actual and the given object are not lenient equals.
  * @throws AssertionError if the other object is not an instance of the actual type.
  * @throws IntrospectionError if a field does not exist in actual.
  */
 public <A> void assertIsLenientEqualsToByAcceptingFields(
     AssertionInfo info, A actual, A other, String... fields) {
   assertIsInstanceOf(info, other, actual.getClass());
   List<String> rejectedFieldsNames = new LinkedList<String>();
   List<Object> expectedValues = new LinkedList<Object>();
   for (String fieldName : fields) {
     Object actualFieldValue = propertySupport.propertyValue(fieldName, Object.class, actual);
     Object otherFieldValue = propertySupport.propertyValue(fieldName, Object.class, other);
     if (!(actualFieldValue == otherFieldValue
         || (actualFieldValue != null && actualFieldValue.equals(otherFieldValue)))) {
       rejectedFieldsNames.add(fieldName);
       expectedValues.add(otherFieldValue);
     }
   }
   if (rejectedFieldsNames.isEmpty()) return;
   throw failures.failure(
       info,
       shouldBeLenientEqualByAccepting(actual, rejectedFieldsNames, expectedValues, list(fields)));
 }
 /**
  * Asserts that the given object is not present in the given collection.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param values the given collection.
  * @throws NullPointerException if the given iterable is {@code null}.
  * @throws IllegalArgumentException if the given collection is empty.
  * @throws AssertionError if the given object is present in the given collection.
  */
 public <A> void assertIsNotIn(AssertionInfo info, A actual, Iterable<? extends A> values) {
   checkIsNotNullAndNotEmpty(values);
   assertNotNull(info, actual);
   if (!isActualIn(actual, values)) return;
   throw failures.failure(info, shouldNotBeIn(actual, values, comparisonStrategy));
 }
 /**
  * Asserts that the given object is not present in the given array.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param values the given array.
  * @throws NullPointerException if the given array is {@code null}.
  * @throws IllegalArgumentException if the given array is empty.
  * @throws AssertionError if the given object is present in the given array.
  */
 public void assertIsNotIn(AssertionInfo info, Object actual, Object[] values) {
   checkIsNotNullAndNotEmpty(values);
   assertNotNull(info, actual);
   if (!isItemInArray(actual, values)) return;
   throw failures.failure(info, shouldNotBeIn(actual, values, comparisonStrategy));
 }
 /**
  * Asserts that two objects do not refer to the same object.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param other the object to compare {@code actual} to.
  * @throws AssertionError if the given objects refer to the same object.
  */
 public void assertNotSame(AssertionInfo info, Object actual, Object other) {
   if (actual != other) return;
   throw failures.failure(info, shouldNotBeSame(actual));
 }
 /**
  * Asserts that two objects refer to the same object.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param expected the expected object.
  * @throws AssertionError if the given objects do not refer to the same object.
  */
 public void assertSame(AssertionInfo info, Object actual, Object expected) {
   if (actual == expected) return;
   throw failures.failure(info, shouldBeSame(actual, expected));
 }
 /**
  * Asserts that the given object is not {@code null}.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @throws AssertionError if the given object is {@code null}.
  */
 public void assertNotNull(AssertionInfo info, Object actual) {
   if (actual != null) return;
   throw failures.failure(info, shouldNotBeNull());
 }
 /**
  * Asserts that the given object is {@code null}.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @throws AssertionError if the given object is not {@code null}.
  */
 public void assertNull(AssertionInfo info, Object actual) {
   if (actual == null) return;
   throw failures.failure(info, shouldBeEqual(actual, null, comparisonStrategy));
 }
 /**
  * Asserts that two objects are not equal.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param other the object to compare {@code actual} to.
  * @throws AssertionError if {@code actual} is equal to {@code other}.
  */
 public void assertNotEqual(AssertionInfo info, Object actual, Object other) {
   if (!areEqual(actual, other)) return;
   throw failures.failure(info, shouldNotBeEqual(actual, other, comparisonStrategy));
 }
 /**
  * Asserts that two objects are equal.
  *
  * @param info contains information about the assertion.
  * @param actual the "actual" object.
  * @param expected the "expected" object.
  * @throws AssertionError if {@code actual} is not equal to {@code expected}. This method will
  *     throw a {@code org.junit.ComparisonFailure} instead if JUnit is in the classpath and the
  *     given objects are not equal.
  */
 public void assertEqual(AssertionInfo info, Object actual, Object expected) {
   if (areEqual(actual, expected)) return;
   throw failures.failure(info, shouldBeEqual(actual, expected, comparisonStrategy));
 }
 /**
  * Verifies that the actual value type is not in given types.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param types the types to check the actual value against.
  * @throws AssertionError if the actual value type is in given type.
  * @throws NullPointerException if the actual value is null.
  * @throws NullPointerException if the given types is null.
  */
 public void assertIsNotOfAnyClassIn(AssertionInfo info, Object actual, Class<?>[] types) {
   assertNotNull(info, actual);
   if (types == null) throw new NullPointerException("The given types should not be null");
   if (!isItemInArray(actual.getClass(), types)) return;
   throw failures.failure(info, shouldNotBeOfClassIn(actual, types));
 }
 /**
  * Verifies that the given object is not an instance of the given type.
  *
  * @param info contains information about the assertion.
  * @param actual the given object.
  * @param type the type to check the given object against.
  * @throws NullPointerException if the given type is {@code null}.
  * @throws AssertionError if the given object is {@code null}.
  * @throws AssertionError if the given object is an instance of the given type.
  */
 public void assertIsNotInstanceOf(AssertionInfo info, Object actual, Class<?> type) {
   if (type == null) throw new NullPointerException("The given type should not be null");
   assertNotNull(info, actual);
   if (!type.isInstance(actual)) return;
   throw failures.failure(info, shouldNotBeInstance(actual, type));
 }