class CommonValidations {

  private static final Failures FAILURES = Failures.instance();

  private CommonValidations() {}

  static void checkIndexValueIsValid(Index index, int maximum) {
    requireNonNull(index, "Index should not be null");
    if (index.value <= maximum) return;
    String errorMessage = "Index should be between <0> and <%d> (inclusive) but was:%n <%d>";
    throw new IndexOutOfBoundsException(format(errorMessage, maximum, index.value));
  }

  static void checkOffsetIsNotNull(Offset<?> offset) {
    requireNonNull(offset, "The given offset should not be null");
  }

  static void checkPercentageIsNotNull(Percentage percentage) {
    requireNonNull(percentage, "The given percentage should not be null");
  }

  static void checkNumberIsNotNull(Number number) {
    requireNonNull(number, "The given number should not be null");
  }

  static void checkIsNotEmpty(Object[] values) {
    if (values.length == 0) throw arrayOfValuesToLookForIsEmpty();
  }

  static void checkIsNotEmpty(Iterable<?> iterable) {
    if (!iterable.iterator().hasNext()) throw iterableOfValuesToLookForIsEmpty();
  }

  public static void checkIsNotNull(Object[] values) {
    if (values == null) throw arrayOfValuesToLookForIsNull();
  }

  static void checkIsNotNull(Iterable<?> iterable) {
    if (iterable == null) throw iterableOfValuesToLookForIsNull();
  }

  static void checkIsNotNullAndNotEmpty(Object[] values) {
    checkIsNotNull(values);
    checkIsNotEmpty(values);
  }

  static void checkIsNotNullAndNotEmpty(Iterable<?> iterable) {
    checkIsNotNull(iterable);
    checkIsNotEmpty(iterable);
  }

  public static void failIfEmptySinceActualIsNotEmpty(AssertionInfo info, Failures failures, Object actual,
                                                      Object values) {
    if (isArrayEmpty(values)) throw failures.failure(info, actualIsNotEmpty(actual));
  }

  public static void hasSameSizeAsCheck(AssertionInfo info, Object actual, Object other, int sizeOfActual) {
    checkOtherIsNotNull(other, "Array");
    checkSameSizes(info, actual, other, sizeOfActual, Array.getLength(other));
  }

  public static void hasSameSizeAsCheck(AssertionInfo info, Object actual, Iterable<?> other, int sizeOfActual) {
    checkOtherIsNotNull(other, "Iterable");
    checkSameSizes(info, actual, other, sizeOfActual, sizeOf(other));
  }

  public static void hasSameSizeAsCheck(AssertionInfo info, Object actual, Map<?, ?> other, int sizeOfActual) {
    checkOtherIsNotNull(other, "Map");
    checkSameSizes(info, actual, other, sizeOfActual, other.size());
  }

  static void checkOtherIsNotNull(Object other, String otherType) {
    requireNonNull(other, "The " + otherType + " to compare actual size with should not be null");
  }

  static void checkSameSizes(AssertionInfo info, Object actual, Object other, int sizeOfActual, int sizeOfOther) {
    if (sizeOfActual != sizeOfOther)
      throw FAILURES.failure(info, shouldHaveSameSizeAs(actual, other, sizeOfActual, sizeOfOther));
  }

  public static void checkSizes(Object actual, int sizeOfActual, int sizeOfOther, AssertionInfo info) {
    if (sizeOfActual != sizeOfOther) throw FAILURES.failure(info, shouldHaveSize(actual, sizeOfActual, sizeOfOther));
  }

  public static void checkSizeGreaterThan(Object actual, int boundary, int sizeOfActual,
                                          AssertionInfo info) {
    if (!(sizeOfActual > boundary))
      throw FAILURES.failure(info, shouldHaveSizeGreaterThan(actual, sizeOfActual, boundary));
  }

  public static void checkSizeGreaterThanOrEqualTo(Object actual, int boundary, int sizeOfActual,
                                                   AssertionInfo info) {
    if (!(sizeOfActual >= boundary))
      throw FAILURES.failure(info, shouldHaveSizeGreaterThanOrEqualTo(actual, sizeOfActual, boundary));
  }

  public static void checkSizeLessThan(Object actual, int boundary, int sizeOfActual,
                                       AssertionInfo info) {
    if (!(sizeOfActual < boundary))
      throw FAILURES.failure(info, shouldHaveSizeLessThan(actual, sizeOfActual, boundary));
  }

  public static void checkSizeLessThanOrEqualTo(Object actual, int boundary, int sizeOfActual,
                                                AssertionInfo info) {
    if (!(sizeOfActual <= boundary))
      throw FAILURES.failure(info, shouldHaveSizeLessThanOrEqualTo(actual, sizeOfActual, boundary));
  }

  public static void checkSizeBetween(Object actual, int lowerBoundary, int higherBoundary,
                                      int sizeOfActual, AssertionInfo info) {
    if (!(higherBoundary >= lowerBoundary))
      throw new IllegalArgumentException(format("The higher boundary <%s> must be greater than the lower boundary <%s>.",
                                                higherBoundary, lowerBoundary));

    if (!(lowerBoundary <= sizeOfActual && sizeOfActual <= higherBoundary))
      throw FAILURES.failure(info, shouldHaveSizeBetween(actual, sizeOfActual, lowerBoundary, higherBoundary));
  }

  public static void checkLineCounts(Object actual, int lineCountOfActual, int lineCountOfOther, AssertionInfo info) {<FILL_FUNCTION_BODY>}

  public static void checkTypeIsNotNull(Class<?> expectedType) {
    requireNonNull(expectedType, "The given type should not be null");
  }

  public static void checkIterableIsNotNull(Iterable<?> set) {
    requireNonNull(set, "The iterable to look for should not be null");
  }

  public static void checkSequenceIsNotNull(Object sequence) {
    requireNonNull(sequence, nullSequence());
  }

  public static void checkSubsequenceIsNotNull(Object subsequence) {
    requireNonNull(subsequence, nullSubsequence());
  }
}

    if (lineCountOfActual != lineCountOfOther)
      throw FAILURES.failure(info, shouldHaveLinesCount(actual, lineCountOfActual, lineCountOfOther));
  
<no_super_class>