/*
 * Created on Dec 14, 2010
 *
 * Licensed 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.
 *
 * Copyright @2010-2013 the original author or authors.
 */
package org.fest.assertions.internal;

import static org.fest.assertions.error.ShouldBeSorted.shouldBeSorted;

import org.fest.assertions.data.Index;
import org.fest.assertions.description.Description;
import org.fest.util.VisibleForTesting;

/**
 * Reusable assertions for arrays of {@code int}s.
 *
 * @author Alex Ruiz
 * @author Joel Costigliola
 * @author Mikhail Mazursky
 * @author Nicolas François
 * @author Yvonne Wang
 */
public class IntArrays {

  private static final Arrays arrays = Arrays.instance();
  private static final IntArrays INSTANCE = new IntArrays();

  /**
   * Returns the singleton instance of this class.
   *
   * @return the singleton instance of this class.
   */
  public static IntArrays instance() {
    return INSTANCE;
  }

  @VisibleForTesting
  Failures failures = Failures.instance();

  /**
   * Asserts that the given array is {@code null} or empty.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @throws AssertionError if the given array is not {@code null} *and* contains one or more elements.
   */
  public void assertNullOrEmpty(Description description, int[] actual) {
    arrays.assertNullOrEmpty(description, actual);
  }

  /**
   * Asserts that the given array is empty.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @throws AssertionError if the given array is {@code null}.
   * @throws AssertionError if the given array is not empty.
   */
  public void assertEmpty(Description description, int[] actual) {
    arrays.assertEmpty(description, actual);
  }

  /**
   * Asserts that the given array is not empty.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @throws AssertionError if the given array is {@code null}.
   * @throws AssertionError if the given array is empty.
   */
  public void assertNotEmpty(Description description, int[] actual) {
    arrays.assertNotEmpty(description, actual);
  }

  /**
   * Asserts that the number of elements in the given array is equal to the expected one.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @param expectedSize the expected size of {@code actual}.
   * @throws AssertionError if the given array is {@code null}.
   * @throws AssertionError if the number of elements in the given array is different than the expected one.
   */
  public void assertHasSize(Description description, int[] actual, int expectedSize) {
    arrays.assertHasSize(description, actual, expectedSize);
  }

  /**
   * Asserts that the given array contains the given values, in any order.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @param values the values that are expected to be in the given array.
   * @throws NullPointerException if the array of values is {@code null}.
   * @throws IllegalArgumentException if the array of values is empty.
   * @throws AssertionError if the given array is {@code null}.
   * @throws AssertionError if the given array does not contain the given values.
   */
  public void assertContains(Description description, int[] actual, int[] values) {
    arrays.assertContains(description, actual, values);
  }

  /**
   * Verifies that the given array contains the given value at the given index.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @param value the value to look for.
   * @param index the index where the value should be stored in the given array.
   * @throws AssertionError if the given array is {@code null} or empty.
   * @throws NullPointerException if the given {@code Index} is {@code null}.
   * @throws IndexOutOfBoundsException if the value of the given {@code Index} is equal to or greater than the size of
   *           the given array.
   * @throws AssertionError if the given array does not contain the given value at the given index.
   */
  public void assertContains(Description description, int[] actual, int value, Index index) {
    arrays.assertContains(description, actual, value, index);
  }

  /**
   * Verifies that the given array does not contain the given value at the given index.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @param value the value to look for.
   * @param index the index where the value should be stored in the given array.
   * @throws AssertionError if the given array is {@code null}.
   * @throws NullPointerException if the given {@code Index} is {@code null}.
   * @throws AssertionError if the given array contains the given value at the given index.
   */
  public void assertDoesNotContain(Description description, int[] actual, int value, Index index) {
    arrays.assertDoesNotContain(description, actual, value, index);
  }

  /**
   * Asserts that the given array contains only the given values and nothing else, in any order.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @param values the values that are expected to be in the given array.
   * @throws NullPointerException if the array of values is {@code null}.
   * @throws IllegalArgumentException if the array of values is empty.
   * @throws AssertionError if the given array is {@code null}.
   * @throws AssertionError if the given array does not contain the given values or if the given array contains values
   *           that are not in the given array.
   */
  public void assertContainsOnly(Description description, int[] actual, int[] values) {
    arrays.assertContainsOnly(description, actual, values);
  }

  /**
   * Verifies that the given array contains the given sequence of values, without any other values between them.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @param sequence the sequence of values to look for.
   * @throws AssertionError if the given array is {@code null}.
   * @throws NullPointerException if the given sequence is {@code null}.
   * @throws IllegalArgumentException if the given sequence is empty.
   * @throws AssertionError if the given array does not contain the given sequence of values.
   */
  public void assertContainsSequence(Description description, int[] actual, int[] sequence) {
    arrays.assertContainsSequence(description, actual, sequence);
  }

  /**
   * Asserts that the given array does not contain the given values.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @param values the values that are expected not to be in the given array.
   * @throws NullPointerException if the array of values is {@code null}.
   * @throws IllegalArgumentException if the array of values is empty.
   * @throws AssertionError if the given array is {@code null}.
   * @throws AssertionError if the given array contains any of given values.
   */
  public void assertDoesNotContain(Description description, int[] actual, int[] values) {
    arrays.assertDoesNotContain(description, actual, values);
  }

  /**
   * Asserts that the given array does not have duplicate values.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @throws NullPointerException if the array of values is {@code null}.
   * @throws IllegalArgumentException if the array of values is empty.
   * @throws AssertionError if the given array is {@code null}.
   * @throws AssertionError if the given array contains duplicate values.
   */
  public void assertDoesNotHaveDuplicates(Description description, int[] actual) {
    arrays.assertDoesNotHaveDuplicates(description, actual);
  }

  /**
   * Verifies that the given array starts with the given sequence of values, without any other values between them.
   * Similar to {@link #assertContainsSequence(Description, int[], int[])}, but it also verifies that the
   * first element in the sequence is also the first element of the given array.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @param sequence the sequence of values to look for.
   * @throws NullPointerException if the given argument is {@code null}.
   * @throws IllegalArgumentException if the given argument is an empty array.
   * @throws AssertionError if the given array is {@code null}.
   * @throws AssertionError if the given array does not start with the given sequence of values.
   */
  public void assertStartsWith(Description description, int[] actual, int[] sequence) {
    arrays.assertStartsWith(description, actual, sequence);
  }

  /**
   * Verifies that the given array ends with the given sequence of values, without any other values between them.
   * Similar to {@link #assertContainsSequence(Description, int[], int[])}, but it also verifies that the
   * last element in the sequence is also the last element of the given array.
   *
   * @param description contains information about the assertion.
   * @param actual the given array.
   * @param sequence the sequence of values to look for.
   * @throws NullPointerException if the given argument is {@code null}.
   * @throws IllegalArgumentException if the given argument is an empty array.
   * @throws AssertionError if the given array is {@code null}.
   * @throws AssertionError if the given array does not end with the given sequence of values.
   */
  public void assertEndsWith(Description description, int[] actual, int[] sequence) {
    arrays.assertEndsWith(description, actual, sequence);
  }

  /**
   * Verifies that the actual is sorted into ascending order according to the natural ordering of its elements.
   * Empty arrays are considered sorted.
   *
   * @param description contains the information about the assertion.
   * @param actual the given array.
   * @throws AssertionError if the {@code actual} is {@code null}.
   */
  public void assertIsSorted(Description description, int[] actual) {
    if(actual == null) {
      throw failures.failure("The actual is null");
    }
    if (actual.length == 0) {
      return;
    }
    for (int i = 0; i < actual.length - 1; i++) {
      if (actual[i] > actual[i + 1]) {
        throw failures.failure(description, shouldBeSorted(i, actual));
      }
    }
  }
}


/*
 * Created on Mar 17, 2012
 *
 * Licensed 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.
 *
 * Copyright @2012 the original author or authors.
 */
package org.fest.assertions.error;

import org.fest.assertions.core.Matcher;

/**
 * Creates an error message indicating that an assertion that not verifies elements of a group satisfies at most n times a
 * {@code Condition} A group of elements can be a collection, an array.

 *
 * @author Nicolas François
 * @author Mikhail Mazursky
 * @author Joel Costigliola
 */
public class ElementsShouldNotBeAtMost extends BasicErrorMessageFactory {

  /**
   * Creates a new {@link ElementsShouldNotBeAtMost}.
   * @param actual the actual value in the failed assertion.
   * @param times least time the condition should be verify.
   * @param condition the {@code Condition}.
   * @return the created {@code ErrorMessageFactory}.
   */
  public static <E> ErrorMessageFactory elementsShouldNotBeAtMost(Object actual, int times, Matcher<?> condition) {
    return new ElementsShouldNotBeAtMost(actual, times, condition);
  }

  private ElementsShouldNotBeAtMost(Object actual, int times, Matcher<?> condition) {
    super("expecting elements:\n<%s>\n not to be at most %s times <%s>", actual, times, condition);
  }
}


/*
 * Created on Dec 21, 2010
 *
 * Licensed 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.
 *
 * Copyright @2010-2013 the original author or authors.
 */
package org.fest.assertions.internal;

import static org.fest.assertions.error.ShouldBeEmpty.shouldBeEmpty;
import static org.fest.assertions.error.ShouldBeNullOrEmpty.shouldBeNullOrEmpty;
import static org.fest.assertions.error.ShouldContain.shouldContain;
import static org.fest.assertions.error.ShouldContainKey.shouldContainKey;
import static org.fest.assertions.error.ShouldContainOnly.shouldContainOnly;
import static org.fest.assertions.error.ShouldContainValue.shouldContainValue;
import static org.fest.assertions.error.ShouldHaveSize.shouldHaveSize;
import static org.fest.assertions.error.ShouldNotBeEmpty.shouldNotBeEmpty;
import static org.fest.assertions.error.ShouldNotContain.shouldNotContain;
import static org.fest.assertions.error.ShouldNotContainKey.shouldNotContainKey;
import static org.fest.assertions.error.ShouldNotContainValue.shouldNotContainValue;
import static org.fest.assertions.error.ShouldNotHaveDuplicates.shouldNotHaveDuplicates;
import static org.fest.util.Collections.duplicatesFrom;
import static org.fest.util.Objects.areEqual;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.fest.assertions.data.MapEntry;
import org.fest.assertions.description.Description;
import org.fest.util.VisibleForTesting;

/**
 * Reusable assertions for <code>{@link Map}</code>s.
 *
 * @author Alex Ruiz
 * @author Nicolas François
 * @author Yvonne Wang
 */
public class Maps {

  private static Maps INSTANCE = new Maps();

  /**
   * Returns the singleton instance of this class.
   *
   * @return the singleton instance of this class.
   */
  public static Maps instance() {
    return INSTANCE;
  }

  @VisibleForTesting
  Failures failures = Failures.instance();

  @VisibleForTesting
  Maps() {
  }

  /**
   * Asserts that the given {@code Map} is {@code null} or empty.
   *
   * @param description contains information about the assertion.
   * @param actual the given map.
   * @throws AssertionError if the given {@code Map} is not {@code null} *and* contains one or more entries.
   */
  public void assertNullOrEmpty(Description description, Map<?, ?> actual) {
    if (actual == null || actual.isEmpty()) {
      return;
    }
    throw failures.failure(description, shouldBeNullOrEmpty(actual));
  }

  /**
   * Asserts that the given {@code Map} is empty.
   *
   * @param description contains information about the assertion.
   * @param actual the given {@code Map}.
   * @throws AssertionError if the given {@code Map} is {@code null}.
   * @throws AssertionError if the given {@code Map} is not empty.
   */
  public void assertEmpty(Description description, Map<?, ?> actual) {
    assertNotNull(description, actual);
    if (!actual.isEmpty()) {
      throw failures.failure(description, shouldBeEmpty(actual));
    }
  }

  /**
   * Asserts that the given {@code Map} is not empty.
   *
   * @param description contains information about the assertion.
   * @param actual the given {@code Map}.
   * @throws AssertionError if the given {@code Map} is {@code null}.
   * @throws AssertionError if the given {@code Map} is empty.
   */
  public void assertNotEmpty(Description description, Map<?, ?> actual) {
    assertNotNull(description, actual);
    if (actual.isEmpty()) {
      throw failures.failure(description, shouldNotBeEmpty());
    }
  }

  /**
   * Asserts that the given {@code Map} contains the given entries, in any order.
   *
   * @param description contains information about the assertion.
   * @param actual the given {@code Map}.
   * @param entries the entries that are expected to be in the given {@code Map}.
   * @throws NullPointerException if the array of entries is {@code null}.
   * @throws IllegalArgumentException if the array of entries is empty.
   * @throws NullPointerException if any of the entries in the given array is {@code null}.
   * @throws AssertionError if the given {@code Map} is {@code null}.
   * @throws AssertionError if the given {@code Map} does not contain the given entries.
   */
  public void assertContains(Description description, Map<?, ?> actual, MapEntry[] entries) {
    isNotEmptyOrNull(entries);
    assertNotNull(description, actual);
    Set<MapEntry> notFound = new LinkedHashSet<MapEntry>();
    for (MapEntry entry : entries) {
      if (!containsEntry(actual, entry)) {
        notFound.add(entry);
      }
    }
    if (!notFound.isEmpty()) {
      throw failures.failure(description, shouldContain(actual, entries, notFound));
    }
  }

  /**
   * Asserts that the given {@code Map} contains only the given entries, nothing else.
   *
   * @param description contains information about the assertion.
   * @param actual the given {@code Map}.
   * @param entries the entries that are expected to be in the given {@code Map}.
   * @throws NullPointerException if the array of entries is {@code null}.
   * @throws IllegalArgumentException if the array of entries is empty.
   * @throws NullPointerException if any of the entries in the given array is {@code null}.
   * @throws AssertionError if the given {@code Map} is {@code null}.
   * @throws AssertionError if the given {@code Map} does not contain the given entries.
   */
  public <K, V> void assertContainsOnly(Description description, Map<K, V> actual, MapEntry[] entries) {
    isNotEmptyOrNull(entries);
    assertNotNull(description, actual);
    Map<K, V> notExpected = new LinkedHashMap<K, V>(actual);
    Set<MapEntry> notFound = containsOnly(actual, entries, notExpected);
    if (!notFound.isEmpty() || !notExpected.isEmpty()) {
      throw failures.failure(description, shouldContainOnly(actual, entries, notFound, notExpected));
    }
  }

  private <K, V> Set<MapEntry> containsOnly(Map<K, V> actual, MapEntry[] entries, Map<K, V> notExpected) {
    Set<MapEntry> notFound = new LinkedHashSet<MapEntry>();
    Set<?> notExpectedKeys = notExpected.keySet();
    Collection<?> notExpectedValues = notExpected.values();
    for (MapEntry entry : entries) {
      if (!containsEntry(actual, entry)) {
        notFound.add(entry);
      } else {
        notExpectedKeys.remove(entry.key);
        notExpectedValues.remove(entry.value);
      }
    }
    return notFound;
  }

  /**
   * Asserts that the given {@code Map} does not contain the given entries.
   *
   * @param description contains information about the assertion.
   * @param actual the given {@code Map}.
   * @param entries the entries that are expected to be in the given {@code Map}.
   * @throws NullPointerException if the array of entries is {@code null}.
   * @throws IllegalArgumentException if the array of entries is empty.
   * @throws NullPointerException if any of the entries in the given array is {@code null}.
   * @throws AssertionError if the given {@code Map} is {@code null}.
   * @throws AssertionError if the given {@code Map} contains any of the given entries.
   */
  public void assertDoesNotContain(Description description, Map<?, ?> actual, MapEntry[] entries) {
    isNotEmptyOrNull(entries);
    assertNotNull(description, actual);
    Set<MapEntry> found = new LinkedHashSet<MapEntry>();
    for (MapEntry entry : entries) {
      if (containsEntry(actual, entry)) {
        found.add(entry);
      }
    }
    if (!found.isEmpty()) {
      throw failures.failure(description, shouldNotContain(actual, entries, found));
    }
  }

  /**
   * Asserts that the actual map contain the given key.
   *
   * @param description contains information about the assertion.
   * @param actual the given {@code Map}.
   * @param key the given key
   * @throws AssertionError if the actual map is {@code null}.
   * @throws AssertionError if the actual map not contains the given key.
   */
  public <K> void assertContainsKey(Description description, Map<?, ?> actual, K key) {
    assertNotNull(description, actual);
    if (!actual.containsKey(key)) {
      throw failures.failure(description, shouldContainKey(actual, key));
    }
  }

  /**
   * Asserts that the actual map not contains the given key.
   *
   * @param description contains information about the assertion.
   * @param actual the given {@code Map}.
   * @param key the given key
   * @throws AssertionError if the actual map is {@code null}.
   * @throws AssertionError if the actual map contains the given key.
   */
  public <K> void assertDoesNotContainKey(Description description, Map<?, ?> actual, K key) {
    assertNotNull(description, actual);
    if (actual.containsKey(key)) {
      throw failures.failure(description, shouldNotContainKey(actual, key));
    }
  }

  /**
   * Asserts that the actual map contain the given value.
   *
   * @param description contains information about the assertion.
   * @param actual the given {@code Map}.
   * @param value the given value
   * @throws AssertionError if the actual map is {@code null}.
   * @throws AssertionError if the actual map not contains the given value.
   */
  public <V> void assertContainsValue(Description description, Map<?, ?> actual, V value) {
    assertNotNull(description, actual);
    if (!actual.containsValue(value)) {
      throw failures.failure(description, shouldContainValue(actual, value));
    }
  }

  /**
   * Asserts that the actual map does not contain the given value.
   *
   * @param description contains information about the assertion.
   * @param actual the given {@code Map}.
   * @param value the given value
   * @throws AssertionError if the actual map is {@code null}.
   * @throws AssertionError if the actual map contains the given value.
   */
  public <V> void assertDoesNotContainValue(Description description, Map<?, ?> actual, V value) {
    assertNotNull(description, actual);
    if (actual.containsValue(value)) {
      throw failures.failure(description, shouldNotContainValue(actual, value));
    }
  }

  /**
   * Asserts that the actual map does not contain the duplicate values.
   *
   * @param description contains information about the assertion.
   * @param actual the given {@code Map}.
   * @throws AssertionError if the actual map is {@code null}.
   * @throws AssertionError if the actual map contains the given value.
   */
  public <K, V> void assertDoesNotContainDuplicateValues(Description description, Map<K, V> actual) {
    assertNotNull(description, actual);
    Collection<?> duplicates = duplicatesFrom(actual.values());
    if (!duplicates.isEmpty()) {
      throw failures.failure(description, shouldNotHaveDuplicates(actual, duplicates));
    }
  }

  /**
   * Asserts that the number of entries in the given {@code Map} is equal to the expected one.
   *
   * @param description contains information about the assertion.
   * @param actual the given {@code Map}.
   * @param expectedSize the expected size of {@code actual}.
   * @throws AssertionError if the given {@code Map} is {@code null}.
   * @throws AssertionError if the number of entries in the given {@code Map} is different than the expected one.
   */
  public <K, V> void assertHasSize(Description description, Map<K, V> actual, int expectedSize) {
    assertNotNull(description, actual);
    int sizeOfActual = actual.size();
    if (sizeOfActual != expectedSize) {
      throw failures.failure(description, shouldHaveSize(actual, sizeOfActual, expectedSize));
    }
  }

  private void isNotEmptyOrNull(MapEntry[] entries) {
    if (entries == null) {
      throw new NullPointerException("The array of entries to look for should not be null");
    }
    if (entries.length == 0) {
      throw new IllegalArgumentException("The array of entries to look for should not be empty");
    }
  }

  private boolean containsEntry(Map<?, ?> actual, MapEntry entry) {
    if (entry == null) {
      throw new NullPointerException("Entries to look for should not be null");
    }
    if (!actual.containsKey(entry.key)) {
      return false;
    }
    return areEqual(actual.get(entry.key), entry.value);
  }

  private <K, V> void assertNotNull(Description description, Map<K, V> actual) {
    Objects.instance().assertNotNull(description, actual);
  }
}


/*
 * Created on Feb 8, 2011
 *
 * Licensed 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.
 *
 * Copyright @2011 the original author or authors.
 */
package org.fest.assertions.internal;

import static org.fest.assertions.internal.CommonValidations.checkNumberIsNotNull;
import static org.fest.assertions.internal.Comparables.assertNotNull;

import java.math.BigDecimal;

import org.fest.assertions.description.Description;
import org.fest.util.VisibleForTesting;

/**
 * Reusable assertions for {@link BigDecimal}s.
 *
 * @author Yvonne Wang
 */
public class BigDecimals {

  private static final BigDecimal ZERO = BigDecimal.ZERO;
  private static final BigDecimals INSTANCE = new BigDecimals();

  /**
   * Returns the singleton instance of this class.
   *
   * @return the singleton instance of this class.
   */
  public static BigDecimals instance() {
    return INSTANCE;
  }

  @VisibleForTesting
  Comparables comparables = Comparables.instance();

  @VisibleForTesting
  Failures failures = Failures.instance();

  @VisibleForTesting
  BigDecimals() {
  }

  /**
   * Verifies that two BigDecimals are equal.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   * @param expected the expected value.
   */
  public void assertEqual(Description description, BigDecimal actual, BigDecimal expected) {
    checkNumberIsNotNull(expected);
    assertNotNull(description, actual);
    comparables.assertEqual(description, actual, expected);
  }

  /**
   * Verifies that two BigDecimals are not equal.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   * @param expected the expected value.
   */
  public void assertNotEqual(Description description, BigDecimal actual, BigDecimal expected) {
    checkNumberIsNotNull(expected);
    assertNotNull(description, actual);
    comparables.assertNotEqual(description, actual, expected);
  }

  /**
   * Verifies that the actual value is greater than the expected.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   * @param expected the expected value.
   */
  public void assertGreaterThan(Description description, BigDecimal actual, BigDecimal expected) {
    checkNumberIsNotNull(expected);
    assertNotNull(description, actual);
    comparables.assertGreaterThan(description, actual, expected);
  }

  /**
   * Verifies that the actual value is not greater than the expected.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   * @param expected the expected value.
   */
  public void assertNotGreaterThan(Description description, BigDecimal actual, BigDecimal expected) {
    checkNumberIsNotNull(expected);
    assertNotNull(description, actual);
    comparables.assertNotGreaterThan(description, actual, expected);
  }

  /**
   * Verifies that the actual value is less than the expected.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   * @param expected the expected value.
   */
  public void assertLessThan(Description description, BigDecimal actual, BigDecimal expected) {
    checkNumberIsNotNull(expected);
    assertNotNull(description, actual);
    comparables.assertLessThan(description, actual, expected);
  }

  /**
   * Verifies that the actual value is not less than the expected.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   * @param expected the expected value.
   */
  public void assertNotLessThan(Description description, BigDecimal actual, BigDecimal expected) {
    checkNumberIsNotNull(expected);
    assertNotNull(description, actual);
    comparables.assertNotLessThan(description, actual, expected);
  }

  /**
   * Verifies that the actual value is zero.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   */
  public void assertIsZero(Description description, BigDecimal actual) {
    comparables.assertEqual(description, actual, ZERO);
  }

  /**
   * Verifies that the actual value is not zero.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   */
  public void assertIsNotZero(Description description, BigDecimal actual) {
    comparables.assertNotEqual(description, actual, ZERO);
  }

  /**
   * Verifies that the actual value is positive.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   */
  public void assertIsPositive(Description description, BigDecimal actual) {
    comparables.assertGreaterThan(description, actual, ZERO);
  }

  /**
   * Verifies that the actual value is negative.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   */
  public void assertIsNegative(Description description, BigDecimal actual) {
    comparables.assertLessThan(description, actual, ZERO);
  }
}


/*
 * Created on Mar 22, 2012
 *
 * Licensed 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.
 *
 * Copyright @2012 the original author or authors.
 */
package org.fest.assertions.condition;

import org.fest.assertions.core.Matcher;

/**
 * Returns {@code true} if the condition is not satisfied.
 *
 * @author Nicolas François
 * @author Mikhail Mazursky
 */
public class Not<T> extends Negative<T> {

  /**
   * Creates a new </code>{@link Not}</code>.
   *
   * @param condition the condition to inverse.
   * @return The Not condition created.
   */
  public static <T> Not<T> not(Matcher<? super T> condition) {
    return new Not<T>(condition);
  }

  private Not(Matcher<? super T> condition) {
    super(condition);
  }

  @Override
  public String toString() {
    return String.format("not :<%s>", condition);
  }

}


/*
 * Created on Mar 17, 2012
 *
 * Licensed 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.
 *
 * Copyright @2012 the original author or authors.
 */
package org.fest.assertions.error;

import org.fest.assertions.core.Matcher;

/**
 * Creates an error message indicating that an assertion that not verifies elements of a group satisfies at least n times a
 * {@code Condition} A group of elements can be a collection, an array.

 *
 * @author Nicolas François
 * @author Mikhail Mazursky
 * @author Joel Costigliola
 */
public class ElementsShouldNotBeAtLeast extends BasicErrorMessageFactory {

  /**
   * Creates a new {@link ElementsShouldNotBeAtLeast}.
   * @param actual the actual value in the failed assertion.
   * @param times least time the condition should be verify.
   * @param condition the {@code Condition}.
   * @return the created {@code ErrorMessageFactory}.
   */
  public static ErrorMessageFactory elementsShouldNotBeAtLeast(Object actual, int times, Matcher<?> condition) {
    return new ElementsShouldNotBeAtLeast(actual, times, condition);
  }

  private ElementsShouldNotBeAtLeast(Object actual, int times, Matcher<?> condition) {
    super("expecting elements:\n<%s>\n not to be at least %s times <%s>", actual, times, condition);
  }
}


/*
 * Created on Mar 5, 2012
 *
 * Licensed 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.
 *
 * Copyright @2012 the original author or authors.
 */
package org.fest.assertions.error;

import org.fest.assertions.core.Matcher;

/**
 * Creates an error message indicating that an assertion that not verifies that each element of a group satisfies a
 * {@code Condition} A group of elements can be a collection, an array.

 *
 * @author Nicolas François
 * @author Mikhail Mazursky
 * @author Joel Costigliola
 */
public class ElementsShouldNotBe extends BasicErrorMessageFactory {

  /**
   * Creates a new {@link ElementsShouldNotBe}.
   * @param actual the actual value in the failed assertion.
   * @param satisfies elements that satisfies the condition
   * @param condition the {@code Condition}.
   * @return the created {@code ErrorMessageFactory}.
   */
  public static ErrorMessageFactory elementsShouldNotBe(Object actual, Object satisfies, Matcher<?> condition) {
    return new ElementsShouldNotBe(actual, satisfies, condition);
  }

  private ElementsShouldNotBe(Object actual, Object satisfies, Matcher<?> condition) {
    super("expecting elements:\n<%s>\n of \n<%s>\n not to be <%s>", satisfies, actual, condition);
  }
}


/*
 * Created on Oct 24, 2010
 *
 * Licensed 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.
 *
 * Copyright @2010-2013 the original author or authors.
 */
package org.fest.assertions.api;

import org.fest.assertions.core.FloatingPointNumberAssert;
import org.fest.assertions.data.Offset;
import org.fest.assertions.description.Description;
import org.fest.assertions.internal.Floats;
import org.fest.util.VisibleForTesting;

/**
 * Assertion methods for floats.
 * <p>
 * To create an instance of this class, invoke {@link Assertions#assertThat(Float)} or
 * {@link Assertions#assertThat(float)}.
 * </p>
 *
 * @author Yvonne Wang
 * @author Alex Ruiz
 * @author Ansgar Konermann
 */
public class FloatAssert extends AbstractComparableAssert<FloatAssert, Float> implements
  FloatingPointNumberAssert<FloatAssert, Float> {

  @VisibleForTesting
  Floats floats = Floats.instance();

  protected FloatAssert(Float actual) {
    super(actual, FloatAssert.class);
  }

  protected FloatAssert(Float actual, Description description) {
    super(actual, FloatAssert.class, description);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public FloatAssert isNaN() {
    floats.assertIsNaN(description, actual);
    return this;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public FloatAssert isNotNaN() {
    floats.assertIsNotNaN(description, actual);
    return this;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public FloatAssert isEqualTo(Float expected, Offset<Float> offset) {
    floats.assertEqual(description, actual, expected, offset);
    return this;
  }

  /**
   * Verifies that the actual value is equal to the given one.
   *
   * @param expected the given value to compare the actual value to.
   * @return {@code this} assertion object.
   * @throws AssertionError if the actual value is {@code null}.
   * @throws AssertionError if the actual value is not equal to the given one.
   */
  public FloatAssert isEqualTo(float expected) {
    floats.assertEqual(description, actual, expected);
    return this;
  }

  /**
   * Verifies that the actual value is equal to the given one, within a positive offset.
   *
   * @param expected the given value to compare the actual value to.
   * @param offset   the given positive offset.
   * @return {@code this} assertion object.
   * @throws NullPointerException if the given offset is {@code null}.
   * @throws AssertionError       if the actual value is {@code null}.
   * @throws AssertionError       if the actual value is not equal to the given one.
   */
  public FloatAssert isEqualTo(float expected, Offset<Float> offset) {
    floats.assertEqual(description, actual, expected, offset);
    return this;
  }

  /**
   * Verifies that the actual value is not equal to the given one.
   *
   * @param expected the given value to compare the actual value to.
   * @return {@code this} assertion object.
   * @throws AssertionError if the actual value is {@code null}.
   * @throws AssertionError if the actual value is equal to the given one.
   */
  public FloatAssert isNotEqualTo(float expected) {
    floats.assertNotEqual(description, actual, expected);
    return this;
  }

  /**
   * Verifies that the actual value is less than the given one.
   *
   * @param expected the given value to compare the actual value to.
   * @return {@code this} assertion object.
   * @throws AssertionError if the actual value is {@code null}.
   * @throws AssertionError if the actual value is equal to or greater than the given one.
   */
  public FloatAssert isLessThan(float expected) {
    floats.assertLessThan(description, actual, expected);
    return this;
  }

  /**
   * Verifies that the actual value is less than or equal to the given one.
   *
   * @param expected the given value to compare the actual value to.
   * @return {@code this} assertion object.
   * @throws AssertionError if the actual value is {@code null}.
   * @throws AssertionError if the actual value is greater than the given one.
   */
  public FloatAssert isNotGreaterThan(float expected) {
    floats.assertNotGreaterThan(description, actual, expected);
    return this;
  }

  /**
   * Verifies that the actual value is greater than the given one.
   *
   * @param expected the given value to compare the actual value to.
   * @return {@code this} assertion object.
   * @throws AssertionError if the actual value is {@code null}.
   * @throws AssertionError if the actual value is equal to or less than the given one.
   */
  public FloatAssert isGreaterThan(float expected) {
    floats.assertGreaterThan(description, actual, expected);
    return this;
  }

  /**
   * Verifies that the actual value is greater than or equal to the given one.
   *
   * @param expected the given value to compare the actual value to.
   * @return {@code this} assertion object.
   * @throws AssertionError if the actual value is {@code null}.
   * @throws AssertionError if the actual value is less than the given one.
   */
  public FloatAssert isNotLessThan(float expected) {
    floats.assertNotLessThan(description, actual, expected);
    return this;
  }
}


/*
 * Created on Mar 19, 2012
 *
 * Licensed 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.
 *
 * Copyright @2012 the original author or authors.
 */
package org.fest.assertions.error;

import java.util.List;

/**
 * Creates an {@link AssertionError} indicating that an assertion that verifies that two objects are lenient equal by
 * ignoring fields failed.
 *
 * @author Nicolas François
 * @author Joel Costigliola
 */
public class ShouldBeLenientEqualByIgnoring extends BasicErrorMessageFactory {

  /**
   * Creates a new {@link ShouldBeLenientEqualByIgnoring}.
   * @param actual the actual value in the failed assertion.
   * @param rejectedFields fields name not matching
   * @param expectedValues fields value not matching
   * @param ignoredFields fields which are not base the lenient equality
   * @return the created {@code ErrorMessageFactory}.
   */
  public static <E> ErrorMessageFactory shouldBeLenientEqualByIgnoring(Object actual, List<String> rejectedFields,
      List<Object> expectedValues, List<String> ignoredFields) {
    if (rejectedFields.size() == 1) {
      if (ignoredFields.isEmpty()) {
        return new ShouldBeLenientEqualByIgnoring(actual, rejectedFields.get(0), expectedValues.get(0));
      } else {
        return new ShouldBeLenientEqualByIgnoring(actual, rejectedFields.get(0), expectedValues.get(0), ignoredFields);
      }
    } else {
      if (ignoredFields.isEmpty()) {
        return new ShouldBeLenientEqualByIgnoring(actual, rejectedFields, expectedValues);
      } else {
        return new ShouldBeLenientEqualByIgnoring(actual, rejectedFields, expectedValues, ignoredFields);
      }
    }
  }

  private ShouldBeLenientEqualByIgnoring(Object actual, List<String> rejectedFields, List<Object> expectedValues,
      List<String> ignoredFields) {
    super("expecting:\n<%s>\n in fields:\n<%s>\n of <%s>.\nComparison was performed on all fields but <%s>",
        expectedValues, rejectedFields, actual, ignoredFields);
  }

  private ShouldBeLenientEqualByIgnoring(Object actual, String rejectedField, Object expectedValue, List<String> ignoredFields) {
    super("expecting:\n<%s> in field <%s> of <%s>.\nComparison was performed on all fields but <%s>", expectedValue,
        rejectedField, actual, ignoredFields);
  }

  private ShouldBeLenientEqualByIgnoring(Object actual, List<String> rejectedFields, List<Object> expectedValue) {
    super("expecting:\n<%s>\n in fields:\n<%s>\n of <%s>.\nComparison was performed on all fields", expectedValue,
        rejectedFields, actual);
  }

  private ShouldBeLenientEqualByIgnoring(Object actual, String rejectedField, Object expectedValue) {
    super("expecting:\n<%s> in field <%s> of <%s>.\nComparison was performed on all fields", expectedValue, rejectedField,
        actual);
  }

}


/*
 * Created on Dec 14, 2010
 *
 * Licensed 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.
 *
 * Copyright @2013 the original author or authors.
 */
package org.fest.assertions.error;

/**
 * Creates an error message indicating that an assertion that verifies that a {@code String} contains another
 * {@code String} only once failed.
 *
 * @author Pauline Iogna
 * @author Joel Costigliola
 * @author Yvonne Wang
 */
public class ShouldContainStringOnlyOnce extends BasicErrorMessageFactory {

  /**
   * Creates a new <code>{@link ShouldContainStringOnlyOnce}</code>.
   *
   * @param actual the actual value in the failed assertion.
   * @param sequence the String expected to be in {@code actual} only once.
   * @param occurences the number of occurrences of sequence in actual.
   * @return the created {@code ErrorMessageFactory}.
   */
  public static ErrorMessageFactory shouldContainOnlyOnce(String actual, String sequence, int occurences) {
    return new ShouldContainStringOnlyOnce(actual, sequence, occurences);
  }

  private ShouldContainStringOnlyOnce(String actual, String expected, int occurences) {
    super("expecting:\n<%s>\n to appear only once in:\n<%s>\n but it appeared %s time.", expected, actual, occurences);
  }
}


/*
 * Created on Mar 5, 2012
 *
 * Licensed 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.
 *
 * Copyright @2012 the original author or authors.
 */
package org.fest.assertions.error;

import org.fest.assertions.core.Matcher;

/**
 * Creates an error message indicating that an assertion that verifies that each element of a group satisfies a {@code Condition}
 * A group of elements can be a collection, an array.

 *
 * @author Nicolas François
 * @author Mikhail Mazursky
 * @author Joel Costigliola
 */
public class ElementsShouldNotHave extends BasicErrorMessageFactory {

  /**
   * Creates a new {@link ElementsShouldNotHave}.
   * @param actual the actual value in the failed assertion.
   * @param notSatisfies elements that not satisfies the condition
   * @param condition the {@code Condition}.
   * @return the created {@code ErrorMessageFactory}.
   */
  public static ErrorMessageFactory elementsShouldNotHave(Object actual, Object notSatisfies, Matcher<?> condition) {
    return new ElementsShouldNotHave(actual, notSatisfies, condition);
  }

  private ElementsShouldNotHave(Object actual, Object notSatisfies, Matcher<?> condition) {
    super("expecting elements:\n<%s>\n of \n<%s>\n not to have <%s>", notSatisfies, actual, condition);
  }
}


/*
 * Created on Oct 24, 2010
 *
 * Licensed 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.
 *
 * Copyright @2010-2011 the original author or authors.
 */
package org.fest.assertions.error;

import org.fest.assertions.data.Offset;

/**
 * Creates an error message indicating that an assertion that verifies that two numbers are equal within a positive offset failed.
 *
 * @author Alex Ruiz
 * @author Joel Costigliola
 */
public class ShouldBeEqualWithinOffset extends BasicErrorMessageFactory {

  /**
   * Creates a new <code>{@link ShouldBeEqualWithinOffset}</code>.
   * @param <T> guarantees that the values used in this factory have the same type.
   * @param actual the actual value in the failed assertion.
   * @param expected the expected value in the failed assertion.
   * @param offset the given positive offset.
   * @param difference the effective difference between actual and expected.
   * @return the created {@code ErrorMessageFactory}.
   */
  public static <T extends Number> ErrorMessageFactory shouldBeEqual(T actual, T expected, Offset<T> offset, T difference) {
    return new ShouldBeEqualWithinOffset(actual, expected, offset, difference);
  }

  private ShouldBeEqualWithinOffset(Number actual, Number expected, Offset<?> offset, Number difference) {
    super("expecting:\n <%s> to be close to <%s> within offset <%s> but offset was <%s>", actual, expected, offset.value, difference);
  }
}


/*
 * Created on Sep 30, 2010
 *
 * Licensed 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.
 *
 * Copyright @2010-2013 the original author or authors.
 */
package org.fest.assertions.api;

import java.io.File;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Entry point for assertion methods for different data types. Each method in this class is a static factory for the
 * type-specific assertion objects. The purpose of this class is to make test code more readable.
 *

 * For example:
 *

 * List<Employee> newEmployees = employees.hired(TODAY); {@link Assertions#assertThat(Collection) assertThat}
 * (newEmployees).{@link CollectionAssert#hasSize(int) hasSize}(6);
 *
 * @author Alex Ruiz
 * @author Yvonne Wang
 * @author David DIDIER
 * @author Ted Young
 */
public class Assertions {

  /**
   * Creates a new instance of {@link BigDecimalAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static BigDecimalAssert assertThat(BigDecimal actual) {
    return new BigDecimalAssert(actual);
  }

  /**
   * Creates a new instance of {@link BooleanAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static BooleanAssert assertThat(boolean actual) {
    return new BooleanAssert(actual);
  }

  /**
   * Creates a new instance of {@link BooleanAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static BooleanAssert assertThat(Boolean actual) {
    return new BooleanAssert(actual);
  }

  /**
   * Creates a new instance of {@link BooleanArrayAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static BooleanArrayAssert assertThat(boolean[] actual) {
    return new BooleanArrayAssert(actual);
  }

  /**
   * Creates a new instance of {@link ByteAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static ByteAssert assertThat(byte actual) {
    return new ByteAssert(actual);
  }

  /**
   * Creates a new instance of {@link ByteAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static ByteAssert assertThat(Byte actual) {
    return new ByteAssert(actual);
  }

  /**
   * Creates a new instance of {@link ByteArrayAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static ByteArrayAssert assertThat(byte[] actual) {
    return new ByteArrayAssert(actual);
  }

  /**
   * Creates a new instance of {@link CharacterAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static CharacterAssert assertThat(char actual) {
    return new CharacterAssert(actual);
  }

  /**
   * Creates a new instance of {@link CharArrayAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static CharArrayAssert assertThat(char[] actual) {
    return new CharArrayAssert(actual);
  }

  /**
   * Creates a new instance of {@link CharacterAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static CharacterAssert assertThat(Character actual) {
    return new CharacterAssert(actual);
  }

  /**
   * Creates a new instance of {@link CollectionAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static CollectionAssert assertThat(Collection<?> actual) {
    return new CollectionAssert(actual);
  }

  /**
   * Creates a new instance of {@link DoubleAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static DoubleAssert assertThat(double actual) {
    return new DoubleAssert(actual);
  }

  /**
   * Creates a new instance of {@link DoubleAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static DoubleAssert assertThat(Double actual) {
    return new DoubleAssert(actual);
  }

  /**
   * Creates a new instance of {@link DoubleArrayAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static DoubleArrayAssert assertThat(double[] actual) {
    return new DoubleArrayAssert(actual);
  }

  /**
   * Creates a new instance of {@link FileAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static FileAssert assertThat(File actual) {
    return new FileAssert(actual);
  }

  /**
   * Creates a new instance of {@link FloatAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static FloatAssert assertThat(float actual) {
    return new FloatAssert(actual);
  }

  /**
   * Creates a new instance of {@link FloatAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static FloatAssert assertThat(Float actual) {
    return new FloatAssert(actual);
  }

  /**
   * Creates a new instance of {@link FloatArrayAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static FloatArrayAssert assertThat(float[] actual) {
    return new FloatArrayAssert(actual);
  }

  /**
   * Creates a new instance of {@link IntegerAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static IntegerAssert assertThat(int actual) {
    return new IntegerAssert(actual);
  }

  /**
   * Creates a new instance of {@link IntArrayAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static IntArrayAssert assertThat(int[] actual) {
    return new IntArrayAssert(actual);
  }

  /**
   * Creates a new instance of {@link IntegerAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static IntegerAssert assertThat(Integer actual) {
    return new IntegerAssert(actual);
  }

  /**
   * Creates a new instance of {@link ListAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static <T> ListAssert assertThat(List<T> actual) {
    return new ListAssert(actual);
  }

  /**
   * Creates a new instance of {@link LongAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static LongAssert assertThat(long actual) {
    return new LongAssert(actual);
  }

  /**
   * Creates a new instance of {@link LongAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static LongAssert assertThat(Long actual) {
    return new LongAssert(actual);
  }

  /**
   * Creates a new instance of {@link LongArrayAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static LongArrayAssert assertThat(long[] actual) {
    return new LongArrayAssert(actual);
  }

  /**
   * Creates a new instance of {@link ObjectAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static ObjectAssert assertThat(Object actual) {
    return new ObjectAssert(actual);
  }

  /**
   * Creates a new instance of {@link ObjectArrayAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static ObjectArrayAssert assertThat(Object[] actual) {
    return new ObjectArrayAssert(actual);
  }

  /**
   * Creates a new instance of {@link SetAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static <T> SetAssert assertThat(Set<T> actual) {
    return new SetAssert(actual);
  }

  /**
   * Creates a new instance of {@link MapAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static <K, V> MapAssert assertThat(Map<K, V> actual) {
    return new MapAssert(actual);
  }

  /**
   * Creates a new instance of {@link ShortAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static ShortAssert assertThat(short actual) {
    return new ShortAssert(actual);
  }

  /**
   * Creates a new instance of {@link ShortAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static ShortAssert assertThat(Short actual) {
    return new ShortAssert(actual);
  }

  /**
   * Creates a new instance of {@link ShortArrayAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static ShortArrayAssert assertThat(short[] actual) {
    return new ShortArrayAssert(actual);
  }

  /**
   * Creates a new instance of {@link StringAssert}.
   *
   * @param actual the actual value.
   * @return the created assertion object.
   */
  public static StringAssert assertThat(String actual) {
    return new StringAssert(actual);
  }

  /** Creates a new {@link Assertions}. */
  protected Assertions() {
  }
}


/*
 * Created on Sep 24, 2012
 *
 * Licensed 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.
 *
 * Copyright @2012-2013 the original author or authors.
 */
package org.fest.assertions.api;

import org.fest.assertions.description.Description;

/**
 * Base class for assertions for {@code Object}s.
 *
 * @param <S> the "self" type of this assertion class. Please read "Emulating 'self types' using Java Generics to simplify fluent API implementation"
 *          for more details.
 * @param  the type of the actual value.
 *
 * @author Alex Ruiz
 * @author Joel Costigliola
 * @author Yvonne Wang
 */
public abstract class AbstractObjectAssert<S, A> extends AbstractAssert<S, A> {
  protected AbstractObjectAssert(A actual, Class<S> selfType) {
    super(actual, selfType);
  }

  protected AbstractObjectAssert(A actual, Class<S> selfType, Description description) {
    super(actual, selfType, description);
  }

  /**
   * Verifies that the actual value is the same as the given one.
   *
   * @param expected the given value to compare the actual value to.
   * @return {@code this} assertion object.
   * @throws AssertionError if the actual value is not the same as the given one.
   */
  public S isSameAs(A expected) {
    objects.assertSame(description, actual, expected);
    return myself;
  }

  /**
   * Verifies that the actual value is not the same as the given one.
   *
   * @param other the given value to compare the actual value to.
   * @return {@code this} assertion object.
   * @throws AssertionError if the actual value is the same as the given one.
   */
  public S isNotSameAs(A other) {
    objects.assertNotSame(description, actual, other);
    return myself;
  }

  /**
   * Verifies that the actual value is an instance of the given type.
   *
   * @param type the type to check the actual value against.
   * @return this assertion object.
   * @throws NullPointerException if the given type is {@code null}.
   * @throws AssertionError if the actual value is {@code null}.
   * @throws AssertionError if the actual value is not an instance of the given type.
   */
  public S isInstanceOf(Class<?> type) {
    objects.assertIsInstanceOf(description, actual, type);
    return myself;
  }

  /**
   * Verifies that the actual value is not an instance of the given type.
   *
   * @param type the type to check the actual value against.
   * @return this assertion object.
   * @throws NullPointerException if the given type is {@code null}.
   * @throws AssertionError if the actual value is an instance of the given type.
   */
  public S isNotInstanceOf(Class<?> type) {
    objects.assertIsNotInstanceOf(description, actual, type);
    return myself;
  }

  /**
   * Verifies that the actual value is an instance of any of the given types.
   *
   * @param types the types to check the actual value against.
   * @return this assertion object.
   * @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 actual actual value is {@code null}.
   * @throws AssertionError if the actual actual value is not an instance of any of the given types.
   */
  public S isInstanceOfAny(Class<?>... types) {
    objects.assertIsInstanceOfAny(description, actual, types);
    return myself;
  }

  /**
   * Verifies that the actual value is not an instance of any of the given types.
   *
   * @param types the types to check the actual value against.
   * @return this assertion object.
   * @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 actual actual value is an instance of any of the given types.
   */
  public S isNotInstanceOfAny(Class<?>... types) {
    objects.assertIsNotInstanceOfAny(description, actual, types);
    return myself;
  }
}


/*
 * Created on Apr 23, 2012
 *
 * Licensed 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.
 *
 * Copyright @2012 the original author or authors.
 */
package org.fest.assertions.error;

import java.util.List;

/**
 * Creates an {@link AssertionError} indicating that an assertion that verifies that two objects are lenient equal by
 * accepting fields failed.
 *
 * @author Nicolas François
 * @author Joel Costigliola
 */
public class ShouldBeLenientEqualByAccepting extends BasicErrorMessageFactory {

  /**
   * Creates a new {@link ShouldBeLenientEqualByAccepting}.
   * @param actual the actual value in the failed assertion.
   * @param rejectedFields fields name not matching
   * @param expectedValues fields value not matching
   * @param acceptedFields fields on which is based the lenient equality
   * @return the created {@code ErrorMessageFactory}.
   */
  public static <E> ErrorMessageFactory shouldBeLenientEqualByAccepting(Object actual, List<String> rejectedFields,
      List<Object> expectedValues, List<String> acceptedFields) {
    if (rejectedFields.size() == 1) {
      return new ShouldBeLenientEqualByAccepting(actual, rejectedFields.get(0), expectedValues.get(0), acceptedFields);
    } else {
      return new ShouldBeLenientEqualByAccepting(actual, rejectedFields, expectedValues, acceptedFields);
    }
  }

  private ShouldBeLenientEqualByAccepting(Object actual, List<String> rejectedFields, List<Object> expectedValue,
      List<String> acceptedFields) {
    super("expecting:\n<%s>\n in fields:\n<%s>\n of <%s>.\nComparison was performed on fields <%s>", expectedValue,
        rejectedFields, actual, acceptedFields);
  }

  private ShouldBeLenientEqualByAccepting(Object actual, String rejectedField, Object rejectedValue, List<String> acceptedFields) {
    super("expecting:\n<%s> in field <%s> of <%s>.\nComparison was performed on fields <%s>", rejectedValue, rejectedField,
        actual, acceptedFields);
  }

}


/*
 * Created on Dec 17, 2010
 *
 * Licensed 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.
 *
 * Copyright @2010-2013 the original author or authors.
 */
package org.fest.assertions.api;

import org.fest.assertions.core.ArraySortedAssert;
import org.fest.assertions.core.EnumerableAssert;
import org.fest.assertions.data.Index;
import org.fest.assertions.description.Description;
import org.fest.assertions.internal.ByteArrays;
import org.fest.util.VisibleForTesting;

/**
 * Assertion methods for arrays of {@code byte}s.
 *

 * To create an instance of this class, invoke {@link Assertions#assertThat(byte[])}.
 *

 *
 * @author Yvonne Wang
 * @author Alex Ruiz
 * @author Joel Costigliola
 */
public class ByteArrayAssert extends AbstractAssert<ByteArrayAssert, byte[]> implements
    EnumerableAssert<ByteArrayAssert>, ArraySortedAssert<ByteArrayAssert> {

  @VisibleForTesting
  ByteArrays arrays = ByteArrays.instance();

  protected ByteArrayAssert(byte[] actual) {
    super(actual, ByteArrayAssert.class);
  }

  protected ByteArrayAssert(byte[] actual, Description description) {
    super(actual, ByteArrayAssert.class, description);
  }

  /** {@inheritDoc} */
  @Override
  public ByteArrayAssert isNullOrEmpty() {
    arrays.assertNullOrEmpty(description, actual);
    return this;
  }

  /** {@inheritDoc} */
  @Override
  public ByteArrayAssert isEmpty() {
    arrays.assertEmpty(description, actual);
    return this;
  }

  /** {@inheritDoc} */
  @Override
  public ByteArrayAssert isNotEmpty() {
    arrays.assertNotEmpty(description, actual);
    return this;
  }

  /** {@inheritDoc} */
  @Override
  public ByteArrayAssert hasSize(int expected) {
    arrays.assertHasSize(description, actual, expected);
    return this;
  }

  @Override
  public ByteArrayAssert isSorted() {
    arrays.assertIsSorted(description, actual);
    return this;
  }

  /**
   * Verifies that the actual array contains the given values, in any order.
   *
   * @param values the given values.
   * @return {@code this} assertion object.
   * @throws NullPointerException if the given argument is {@code null}.
   * @throws IllegalArgumentException if the given argument is an empty array.
   * @throws AssertionError if the actual array is {@code null}.
   * @throws AssertionError if the actual array does not contain the given values.
   */
  public ByteArrayAssert contains(byte... values) {
    arrays.assertContains(description, actual, values);
    return this;
  }

  /**
   * Verifies that the given array contains the given value at the given index.
   *
   * @param value the value to look for.
   * @param index the index where the value should be stored in the given array.
   * @return {@code this} assertion object.
   * @throws AssertionError if the given array is {@code null} or empty.
   * @throws NullPointerException if the given {@code Index} is {@code null}.
   * @throws IndexOutOfBoundsException if the value of the given {@code Index} is equal to or greater than the size of
   *           the given array.
   * @throws AssertionError if the given array does not contain the given value at the given index.
   */
  public ByteArrayAssert contains(byte value, Index index) {
    arrays.assertContains(description, actual, value, index);
    return this;
  }

  /**
   * Verifies that the actual array contains only the given values and nothing else, in any order.
   *
   * @param values the given values.
   * @return {@code this} assertion object.
   * @throws NullPointerException if the given argument is {@code null}.
   * @throws IllegalArgumentException if the given argument is an empty array.
   * @throws AssertionError if the actual array is {@code null}.
   * @throws AssertionError if the actual array does not contain the given values, i.e. the actual array contains some
   *           or none of the given values, or the actual array contains more values than the given ones.
   */
  public ByteArrayAssert containsOnly(byte... values) {
    arrays.assertContainsOnly(description, actual, values);
    return this;
  }

  /**
   * Verifies that the actual array contains the given sequence, without any other values between them.
   *
   * @param sequence the sequence of values to look for.
   * @return this assertion object.
   * @throws AssertionError if the actual array is {@code null}.
   * @throws AssertionError if the given array is {@code null}.
   * @throws AssertionError if the actual array does not contain the given sequence.
   */
  public ByteArrayAssert containsSequence(byte... sequence) {
    arrays.assertContainsSequence(description, actual, sequence);
    return this;
  }

  /**
   * Verifies that the actual array does not contain the given values.
   *
   * @param values the given values.
   * @return {@code this} assertion object.
   * @throws NullPointerException if the given argument is {@code null}.
   * @throws IllegalArgumentException if the given argument is an empty array.
   * @throws AssertionError if the actual array is {@code null}.
   * @throws AssertionError if the actual array contains any of the given values.
   */
  public ByteArrayAssert doesNotContain(byte... values) {
    arrays.assertDoesNotContain(description, actual, values);
    return this;
  }

  /**
   * Verifies that the given array does not contain the given value at the given index.
   *
   * @param value the value to look for.
   * @param index the index where the value should be stored in the given array.
   * @return {@code this} assertion object.
   * @throws AssertionError if the given array is {@code null}.
   * @throws NullPointerException if the given {@code Index} is {@code null}.
   * @throws AssertionError if the given array contains the given value at the given index.
   */
  public ByteArrayAssert doesNotContain(byte value, Index index) {
    arrays.assertDoesNotContain(description, actual, value, index);
    return this;
  }

  /**
   * Verifies that the actual array does not contain duplicates.
   *
   * @return {@code this} assertion object.
   * @throws AssertionError if the actual array is {@code null}.
   * @throws AssertionError if the actual array contains duplicates.
   */
  public ByteArrayAssert doesNotHaveDuplicates() {
    arrays.assertDoesNotHaveDuplicates(description, actual);
    return this;
  }

  /**
   * Verifies that the actual array starts with the given sequence of values, without any other values between them.
   * Similar to {@link #containsSequence(byte...)}, but it also verifies that the first element in the
   * sequence is also first element of the actual array.
   *
   * @param sequence the sequence of values to look for.
   * @return this assertion object.
   * @throws NullPointerException if the given argument is {@code null}.
   * @throws IllegalArgumentException if the given argument is an empty array.
   * @throws AssertionError if the actual array is {@code null}.
   * @throws AssertionError if the actual array does not start with the given sequence.
   */
  public ByteArrayAssert startsWith(byte... sequence) {
    arrays.assertStartsWith(description, actual, sequence);
    return this;
  }

  /**
   * Verifies that the actual array ends with the given sequence of values, without any other values between them.
   * Similar to {@link #containsSequence(byte...)}, but it also verifies that the last element in the
   * sequence is also last element of the actual array.
   *
   * @param sequence the sequence of values to look for.
   * @return this assertion object.
   * @throws NullPointerException if the given argument is {@code null}.
   * @throws IllegalArgumentException if the given argument is an empty array.
   * @throws AssertionError if the actual array is {@code null}.
   * @throws AssertionError if the actual array does not end with the given sequence.
   */
  public ByteArrayAssert endsWith(byte... sequence) {
    arrays.assertEndsWith(description, actual, sequence);
    return this;
  }
}


/*
 * Created on Oct 18, 2010
 *
 * Licensed 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.
 *
 * Copyright @2010-2012 the original author or authors.
 */
package org.fest.assertions.error;

import static java.lang.String.format;
import static org.fest.util.Arrays.format;
import static org.fest.util.Objects.HASH_CODE_PRIME;
import static org.fest.util.Objects.areEqual;
import static org.fest.util.Objects.hashCodeFor;
import static org.fest.util.Strings.quote;

import java.util.Arrays;

import org.fest.assertions.description.Description;
import org.fest.util.VisibleForTesting;

/**
 * A factory of error messages typically shown when an assertion fails.
 *
 * @author Alex Ruiz
 * @author Joel Costigliola
 * @author Yvonne Wang
 */
public class BasicErrorMessageFactory implements ErrorMessageFactory {
  protected final String format;
  protected final Object[] arguments;

  @VisibleForTesting
  MessageFormatter formatter = MessageFormatter.instance();

  /**
   * Creates a new </code>{@link BasicErrorMessageFactory}</code>.
   *
   * @param format the format string.
   * @param arguments arguments referenced by the format specifiers in the format string.
   */
  public BasicErrorMessageFactory(String format, Object... arguments) {
    this.format = format;
    this.arguments = arguments;
  }

  /** {@inheritDoc} */
  @Override
  public String create(Description d) {
    return formatter.format(d, format, arguments);
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    BasicErrorMessageFactory other = (BasicErrorMessageFactory) obj;
    return areEqual(format, other.format) && areEqual(arguments, other.arguments);
  }

  @Override
  public int hashCode() {
    int result = 1;
    result = HASH_CODE_PRIME * result + hashCodeFor(format);
    result = HASH_CODE_PRIME * result + Arrays.hashCode(arguments);
    return result;
  }

  @Override
  public String toString() {
    return format("%s[format=%s, arguments=%s]", getClass().getSimpleName(), quote(format), format(arguments));
  }
}


/*
 * Created on Mar 17, 2012
 *
 * Licensed 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.
 *
 * Copyright @2012 the original author or authors.
 */
package org.fest.assertions.error;

import org.fest.assertions.core.Matcher;

/**
 * Creates an error message indicating that an assertion that not verifies elements of a group satisfies at most n times a
 * {@code Condition} A group of elements can be a collection, an array.

 *
 * @author Nicolas François
 * @author Mikhail Mazursky
 * @author Joel Costigliola
 */
public class ElementsShouldNotHaveAtMost extends BasicErrorMessageFactory {

  /**
   * Creates a new {@link ElementsShouldNotHaveAtMost}.
   * @param actual the actual value in the failed assertion.
   * @param times least time the condition should be verify.
   * @param condition the {@code Condition}.
   * @return the created {@code ErrorMessageFactory}.
   */
  public static <E> ErrorMessageFactory elementsShouldNotHaveAtMost(Object actual, int times, Matcher<?> condition) {
    return new ElementsShouldNotHaveAtMost(actual, times, condition);
  }

  private ElementsShouldNotHaveAtMost(Object actual, int times, Matcher<?> condition) {
    super("expecting elements:\n<%s>\n not to have at most %s times <%s>", actual, times, condition);
  }
}


/*
 * Created on Oct 25, 2010
 *
 * Licensed 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.
 *
 * Copyright @2010-2013 the original author or authors.
 */
package org.fest.assertions.internal;

import static java.lang.Double.NaN;
import static java.lang.Math.abs;

import static org.fest.assertions.error.ShouldBeEqualWithinOffset.shouldBeEqual;
import static org.fest.assertions.error.ShouldBeGreaterThan.shouldBeGreaterThan;
import static org.fest.assertions.error.ShouldBeLessThan.shouldBeLessThan;
import static org.fest.assertions.error.ShouldNotBeEqual.shouldNotBeEqual;
import static org.fest.assertions.error.ShouldNotBeGreaterThan.shouldNotBeGreaterThan;
import static org.fest.assertions.error.ShouldNotBeLessThan.shouldNotBeLessThan;
import static org.fest.assertions.internal.CommonValidations.checkNumberIsNotNull;
import static org.fest.assertions.internal.CommonValidations.checkOffsetIsNotNull;
import static org.fest.assertions.internal.Comparables.assertNotNull;

import org.fest.assertions.data.Offset;
import org.fest.assertions.description.Description;
import org.fest.assertions.error.ShouldBeEqual;
import org.fest.util.VisibleForTesting;

/**
 * Reusable assertions for {@link Double}s.
 *
 * @author Alex Ruiz
 * @author Yvonne Wang
 */
public class Doubles {

  private static final Doubles INSTANCE = new Doubles();

  /**
   * Returns the singleton instance of this class.
   *
   * @return the singleton instance of this class.
   */
  public static Doubles instance() {
    return INSTANCE;
  }

  @VisibleForTesting
  Comparables comparables = Comparables.instance();
  @VisibleForTesting
  Failures failures = Failures.instance();

  @VisibleForTesting
  Doubles() {
  }

  /**
   * Verifies that the actual value is equal to {@code NaN}.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   */
  public void assertIsNaN(Description description, Double actual) {
    comparables.assertEqual(description, actual, NaN);
  }

  /**
   * Verifies that the actual value is not equal to {@code NaN}.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   */
  public void assertIsNotNaN(Description description, Double actual) {
    comparables.assertNotEqual(description, actual, NaN);
  }

  /**
   * Verifies that two doubles are equal within a positive offset.

   * It does not rely on the custom comparisonStrategy (if one is set) because using an offset is already a specific
   * comparison strategy.
   *
   * @param description describes the information about the assertion.
   * @param actual the actual value.
   * @param expected the expected value.
   * @param offset the given positive offset.
   * @throws NullPointerException if the given offset is {@code null}.
   * @throws AssertionError if the actual value is {@code null}.
   * @throws AssertionError if the actual value is not equal to the expected one.
   */
  public void assertEqual(Description description, Double actual, Double expected, Offset<Double> offset) {
    checkOffsetIsNotNull(offset);
    checkNumberIsNotNull(expected);
    assertNotNull(description, actual);
    if (!isEqualTo(actual, expected, offset)) {
      throw failures.failure(description,
          shouldBeEqual(actual, expected, offset, abs(expected.doubleValue() - actual.doubleValue())));
    }
  }

  public void assertEqual(Description description, Double actual, double expected) {
    assertNotNull(description, actual);
    if (!(actual.doubleValue() == expected)) {
      throw failures.failure(description, ShouldBeEqual.shouldBeEqual(actual, expected));
    }
  }

  /**
   * Verifies that two doubles are not equal.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   * @param expected the expected value.
   * @param offset the given positive offset.
   */
  public void assertNotEqual(Description description, Double actual, Double expected, Offset<Double> offset) {
    checkOffsetIsNotNull(offset);
    checkNumberIsNotNull(expected);
    assertNotNull(description, actual);
    if (isEqualTo(actual, expected, offset)) {
      throw failures.failure(description, shouldNotBeEqual(actual, expected));
    }
  }

  public void assertNotEqual(Description description, Double actual, double expected) {
    assertNotNull(description, actual);
    if (actual.doubleValue() == expected) {
      throw failures.failure(description, shouldNotBeEqual(actual, expected));
    }
  }

  /**
   * Verifies that the actual value is greater than the expected.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   * @param expected the expected value.
   */
  public void assertGreaterThan(Description description, Double actual, double expected) {
    assertNotNull(description, actual);
    if (!isGreaterThan(actual, expected)) {
      throw failures.failure(description, shouldBeGreaterThan(actual, expected));
    }
  }

  /**
   * Verifies that the actual value is not greater than the expected.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   * @param expected the expected value.
   */
  public void assertNotGreaterThan(Description description, Double actual, double expected) {
    assertNotNull(description, actual);
    if (isGreaterThan(actual, expected)) {
      throw failures.failure(description, shouldNotBeGreaterThan(actual, expected));
    }
  }

  /**
   * Verifies that the actual value is less than the expected.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   * @param expected the expected value.
   */
  public void assertLessThan(Description description, Double actual, double expected) {
    assertNotNull(description, actual);
    if (!isLessThan(actual, expected)) {
      throw failures.failure(description, shouldBeLessThan(actual, expected));
    }
  }

  /**
   * Verifies that the actual value is not less than the expected.
   *
   * @param description the description of the actual value.
   * @param actual the actual value.
   * @param expected the expected value.
   */
  public void assertNotLessThan(Description description, Double actual, double expected) {
    assertNotNull(description, actual);
    if (isLessThan(actual, expected)) {
      throw failures.failure(description, shouldNotBeLessThan(actual, expected));
    }
  }

  private boolean isEqualTo(Double actual, Double expected, Offset<?> offset) {
    return abs(expected.doubleValue() - actual.doubleValue()) <= offset.value.doubleValue();
  }

  private boolean isGreaterThan(Double actual, double expected) {
    return actual.doubleValue() > expected;
  }

  private boolean isLessThan(Double actual, double expected) {
    return actual.doubleValue() < expected;
  }
}


/*
 * Created on Aug 5, 2010
 *
 * Licensed 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.
 *
 * Copyright @2010-2013 the original author or authors.
 */
package org.fest.assertions.internal;

import org.fest.assertions.description.Description;
import org.fest.assertions.error.ErrorMessageFactory;
import org.fest.assertions.error.NotEqualErrorFactory;
import org.fest.util.Throwables;
import org.fest.util.VisibleForTesting;

/**
 * Failure actions.
 *
 * @author Yvonne Wang
 * @author Alex Ruiz
 */
public class Failures {

  private static final Failures INSTANCE = new Failures();

  /**
   * Returns the singleton instance of this class.
   *
   * @return the singleton instance of this class.
   */
  public static Failures instance() {
    return INSTANCE;
  }

  /**
   * flag indicating whether or not we remove elements related to FEST from assertion error stack trace.
   */
  private boolean removeFestRelatedElementsFromStackTrace = true;

  /**
   * Sets whether we remove elements related to FEST from assertion error stack trace.
   *
   * @param removeFestRelatedElementsFromStackTrace flag
   */
  public void setRemoveFestRelatedElementsFromStackTrace(boolean removeFestRelatedElementsFromStackTrace) {
    this.removeFestRelatedElementsFromStackTrace = removeFestRelatedElementsFromStackTrace;
  }

  @VisibleForTesting
  Failures() {
  }

  /**
   * Creates a {@link AssertionError} using {@link ErrorMessageFactory} to create the detail message of the
   * {@link AssertionError}, prepending the value of {@link Description} to the
   * error message
   *
   * @param description contains information about the failed assertion.
   * @param message knows how to create detail messages for {@code AssertionError}s.
   * @return the created {@link AssertionError}.
   */
  public AssertionError failure(Description description, ErrorMessageFactory message) {
    AssertionError assertionError = new AssertionError(message.create(description));
    removeFestRelatedElementsFromStackTraceIfNeeded(assertionError);
    return assertionError;
  }

  /**
   * Creates a {@link AssertionError} using the given {@code String} as message.
   *

   * It filters the AssertionError stack trace be default, to have full stack trace use
   * {@link #setRemoveFestRelatedElementsFromStackTrace(boolean)}.
   *
   * @param message the message of the {@code AssertionError} to create.
   * @return the created {@link AssertionError}.
   */
  public AssertionError failure(String message) {
    AssertionError assertionError = new AssertionError(message);
    removeFestRelatedElementsFromStackTraceIfNeeded(assertionError);
    return assertionError;
  }

/**
   * If the {@link #removeFestRelatedElementsFromStackTrace} is true, it filters the stack trace of the given {@link AssertionError}
   * by removing stack trace elements related to Fest in order to get a more readable stack trace.
   *

   * See example below :
   *

--------------- stack trace not filtered -----------------
org.junit.ComparisonFailure: expected:<'[Ronaldo]'> but was:<'[Messi]'>
  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
  at java.lang.reflect.Constructor.newInstance(Constructor.java:501)
  at org.fest.assertions.error.ConstructorInvoker.newInstance(ConstructorInvoker.java:34)
  at org.fest.assertions.error.ShouldBeEqual.newComparisonFailure(ShouldBeEqual.java:111)
  at org.fest.assertions.error.ShouldBeEqual.comparisonFailure(ShouldBeEqual.java:103)
  at org.fest.assertions.error.ShouldBeEqual.newAssertionError(ShouldBeEqual.java:81)
  at org.fest.assertions.internal.Failures.failure(Failures.java:76)
  at org.fest.assertions.internal.Objects.assertEqualTo(Objects.java:116)
  at org.fest.assertions.api.AbstractAssert.isEqualTo(AbstractAssert.java:74)
  at examples.StackTraceFilterExample.main(StackTraceFilterExample.java:13)

--------------- stack trace filtered -----------------
org.junit.ComparisonFailure: expected:<'[Ronaldo]'> but was:<'[Messi]'>
  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
  at examples.StackTraceFilterExample.main(StackTraceFilterExample.java:20)
   *

   *
   * Method is public because we need to call it from {@link NotEqualErrorFactory#newAssertionError(org.fest.assertions.description.Description)} that is building a junit ComparisonFailure by reflection.
   *
   * @param assertionError the {@code AssertionError} to filter stack trace if option is set.
   */
  public void removeFestRelatedElementsFromStackTraceIfNeeded(AssertionError assertionError) {
    if (removeFestRelatedElementsFromStackTrace) {
      Throwables.removeFestFromStackTrace(assertionError);
    }
  }

}


package org.fest.assertions.error;

import java.util.List;

import org.fest.assertions.core.Matcher;
import org.fest.assertions.data.Index;

/**
 * Creates an error message indicating that an assertion that verifies a group of elements contains a value at a given
 * index that satisfies a {@link Matcher} failed.
 *
 * @author Bo Gotthardt
 */
public class ShouldHaveAtIndex extends BasicErrorMessageFactory {

  /**
   * Creates a new {@link ShouldHaveAtIndex}.
   * @param <T> guarantees that the type of the actual value and the generic type of the {@code Condition} are the same.
   * @param actual the actual value in the failed assertion.
   * @param condition the {@code Condition}.
   * @param index the index of the expected value.
   * @param found the value in {@code actual} stored under {@code index}.
   * @return the created {@code ErrorMessageFactory}.
   */
  public static <T> ErrorMessageFactory shouldHaveAtIndex(List<T> actual, Matcher<? super T> condition, Index index, T found) {
    return new ShouldHaveAtIndex(actual, condition, index, found);
  }

  private <T> ShouldHaveAtIndex(List<T> actual, Matcher<? super T> condition, Index index, T found) {
    super("expecting:\n<%s> at index <%s> to have:<%s> in:\n <%s>\n", found, index.value, condition, actual);
  }
}


/*
 * Created on Oct 26, 2010
 *
 * Licensed 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.
 *
 * Copyright @2010-2013 the original author or authors.
 */
package org.fest.assertions.api;

import java.util.List;

import org.fest.assertions.core.IndexedObjectEnumerableAssert;
import org.fest.assertions.data.Index;
import org.fest.assertions.description.Description;
import org.fest.assertions.internal.Lists;
import org.fest.util.VisibleForTesting;

/**
 * Assertion methods for {@link List}s.
 * <p>
 * To create an instance of this class, invoke {@link Assertions#assertThat(List)}.
 *
 * @author Yvonne Wang
 * @author Alex Ruiz
 */
public class ListAssert extends AbstractCollectionAssert<ListAssert, List<?>> implements
    IndexedObjectEnumerableAssert<ListAssert> {

  @VisibleForTesting
  Lists lists = Lists.instance();

  protected ListAssert(List<?> actual) {
    super(actual, ListAssert.class);
  }

  protected ListAssert(List<?> actual, Description description) {
    super(actual, ListAssert.class, description);
  }

  /** {@inheritDoc} */
  @Override
  public ListAssert contains(Object value, Index index) {
    lists.assertContains(description, actual, value, index);
    return this;
  }

  /** {@inheritDoc} */
  @Override
  public ListAssert doesNotContain(Object value, Index index) {
    lists.assertDoesNotContain(description, actual, value, index);
    return this;
  }
}


/*
 * Created on Mar 17, 2012
 *
 * Licensed 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.
 *
 * Copyright @2012 the original author or authors.
 */
package org.fest.assertions.error;

import org.fest.assertions.core.Matcher;

/**
 * Creates an error message indicating that an assertion that verifies elements of a group satisfies at most n times a
 * {@code Condition} A group of elements can be a collection, an array.

 *
 * @author Nicolas François
 * @author Mikhail Mazursky
 * @author Joel Costigliola
 */
public class ElementsShouldHaveAtMost extends BasicErrorMessageFactory {

  /**
   * Creates a new {@link ElementsShouldHaveAtMost}.
   * @param actual the actual value in the failed assertion.
   * @param times least time the condition should be verify.
   * @param condition the {@code Condition}.
   * @return the created {@code ErrorMessageFactory}.
   */
  public static ErrorMessageFactory elementsShouldHaveAtMost(Object actual, int times, Matcher<?> condition) {
    return new ElementsShouldHaveAtMost(actual, times, condition);
  }

  private ElementsShouldHaveAtMost(Object actual, int times, Matcher<?> condition) {
    super("expecting elements:\n<%s>\n to have at most %s times <%s>", actual, times, condition);
  }
}


/*
 * Created on Mar 5, 2012
 *
 * Licensed 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.
 *
 * Copyright @2012 the original author or authors.
 */
package org.fest.assertions.error;

import org.fest.assertions.core.Matcher;

/**
 * Creates an error message indicating that an assertion that verifies that each element of a group satisfies a {@code Condition}
 * A group of elements can be a collection, an array.

 *
 * @author Nicolas François
 * @author Mikhail Mazursky
 * @author Joel Costigliola
 */
public class ElementsShouldHave extends BasicErrorMessageFactory {

  /**
   * Creates a new {@link ElementsShouldHave}.
   * @param actual the actual value in the failed assertion.
   * @param notSatisfies elements that not satisfies the condition
   * @param condition the {@code Condition}.
   * @return the created {@code ErrorMessageFactory}.
   */
  public static ErrorMessageFactory elementsShouldHave(Object actual, Object notSatisfies, Matcher<?> condition) {
    return new ElementsShouldHave(actual, notSatisfies, condition);
  }

  private ElementsShouldHave(Object actual, Object notSatisfies, Matcher<?> condition) {
    super("expecting elements:\n<%s>\n of \n<%s>\n to have <%s>", notSatisfies, actual, condition);
  }
}