class Join<T> extends Condition<T> {

  protected static final String SUFFIX_DELIMITER = "]";
  protected static final String PREFIX_DELIMITER = ":[";

  @VisibleForTesting
  Collection<Condition<? super T>> conditions;

  /**
   * Creates a new <code>{@link Join}</code>.
   * @param conditions the conditions to join.
   * @throws NullPointerException if the given array is {@code null}.
   * @throws NullPointerException if any of the elements in the given array is {@code null}.
   */
  @SafeVarargs
  protected Join(Condition<? super T>... conditions) {
    this(Arrays.stream(checkNotNullConditions(conditions)));
  }

  /**
   * Creates a new <code>{@link Join}</code>.
   * @param conditions the conditions to join.
   * @throws NullPointerException if the given iterable is {@code null}.
   * @throws NullPointerException if any of the elements in the given iterable is {@code null}.
   */
  protected Join(Iterable<? extends Condition<? super T>> conditions) {
    this(Streams.stream(checkNotNullConditions(conditions)));
  }

  private Join(Stream<? extends Condition<? super T>> stream) {
    conditions = stream.map(Join::notNull).collect(toList());
    calculateDescription();
  }

  private static <T> T checkNotNullConditions(T conditions) {<FILL_FUNCTION_BODY>}

  /**
   * method used to prefix the subclass join description, ex: "all of"
   * @return the prefix to use to build the description.
   */
  public abstract String descriptionPrefix();

  /**
   * method used to calculate the subclass join description
   */
  private void calculateDescription() {
    List<Description> conditionsDescriptions = conditions.stream()
                                                         .map(Condition::description)
                                                         .collect(toList());
    String prefix = descriptionPrefix() + PREFIX_DELIMITER;
    describedAs(new JoinDescription(prefix, SUFFIX_DELIMITER, conditionsDescriptions));
  }

  @Override
  public Description description() {
    calculateDescription();
    return super.description();
  }

  @Override
  public Description conditionDescriptionWithStatus(T actual) {
    List<Description> descriptionsWithStatus = conditions.stream()
                                                         .map(condition -> condition.conditionDescriptionWithStatus(actual))
                                                         .collect(toList());
    String prefix = status(actual).label + " " + descriptionPrefix() + PREFIX_DELIMITER;
    return new JoinDescription(prefix, SUFFIX_DELIMITER, descriptionsWithStatus);
  }

  private static <T> T notNull(T condition) {
    return requireNonNull(condition, "The given conditions should not have null entries");
  }

  /**
   * Returns the conditions to join.
   * @return the conditions to join.
   */
  public final Collection<Condition<? super T>> conditions() {
    return unmodifiableCollection(conditions);
  }
}

    return requireNonNull(conditions, "The given conditions should not be null");
  
<methods>public void <init>() ,public void <init>(java.lang.String) ,public transient void <init>(Predicate<T>, java.lang.String, java.lang.Object[]) ,public void <init>(org.assertj.core.description.Description) ,public org.assertj.core.description.Description conditionDescriptionWithStatus(T) ,public Condition<T> describedAs(org.assertj.core.description.Description) ,public org.assertj.core.description.Description description() ,public boolean matches(T) ,public java.lang.String toString() <variables>org.assertj.core.description.Description description,private Predicate<T> predicate