class NestableCondition<ACTUAL, NESTED> extends Join<ACTUAL> {
  private final String descriptionPrefix;

  /**
   * Creates a new <code>{@link NestableCondition}</code>
   * @param descriptionPrefix the prefix to use to build the description
   * @param extractor a function to extract the nested object of type {@literal T} from an object fo type {@literal K}
   * @param conditions conditions to be checked
   * @return the nestable condition
   * @param <ACTUAL> the type of object the resulting condition accepts
   * @param <NESTED> the type of object nested into {@literal K}
   */
  @SafeVarargs
  public static <ACTUAL, NESTED> Condition<ACTUAL> nestable(String descriptionPrefix,
                                                            Function<? super ACTUAL, ? extends NESTED> extractor,
                                                            Condition<? super NESTED>... conditions) {
    return new NestableCondition<>(descriptionPrefix, stream(conditions), extractor);
  }

  /**
   * Creates a new <code>{@link NestableCondition}</code>
   * @param descriptionPrefix the prefix to use to build the description
   * @param conditions conditions to be checked
   * @return the nestable condition
   * @param <ACTUAL> the type of object the resulting condition accepts
   */
  @SafeVarargs
  public static <ACTUAL> Condition<ACTUAL> nestable(String descriptionPrefix, Condition<? super ACTUAL>... conditions) {
    return new NestableCondition<ACTUAL, ACTUAL>(descriptionPrefix, stream(conditions));
  }

  private NestableCondition(String descriptionPrefix, Stream<? extends Condition<? super NESTED>> conditions,
                            Function<? super ACTUAL, ? extends NESTED> extractor) {
    super(compose(conditions, extractor));
    this.descriptionPrefix = descriptionPrefix;
  }

  private NestableCondition(String descriptionPrefix, Stream<? extends Condition<? super ACTUAL>> conditions) {
    super(conditions.collect(toList()));
    this.descriptionPrefix = descriptionPrefix;
  }

  @Override
  public boolean matches(ACTUAL value) {
    return conditions.stream().allMatch(condition -> condition.matches(value));
  }

  @Override
  public String descriptionPrefix() {
    return descriptionPrefix;
  }

  private static <ACTUAL, NESTED> List<Condition<? super ACTUAL>> compose(Stream<? extends Condition<? super NESTED>> conditions,
                                                                          Function<? super ACTUAL, ? extends NESTED> extractor) {
    return conditions.map(condition -> compose(condition, extractor)).collect(toList());
  }

  private static <ACTUAL, NESTED> Condition<ACTUAL> compose(Condition<? super NESTED> condition,
                                                            Function<? super ACTUAL, ? extends NESTED> extractor) {<FILL_FUNCTION_BODY>}
}

    return new Condition<ACTUAL>(condition.description()) {
      @Override
      public boolean matches(ACTUAL value) {
        return condition.matches(extractor.apply(value));
      }

      @Override
      public Description conditionDescriptionWithStatus(ACTUAL actual) {
        return condition.conditionDescriptionWithStatus(extractor.apply(actual));
      }
    };
  
<methods>public org.assertj.core.description.Description conditionDescriptionWithStatus(ACTUAL) ,public final Collection<Condition<? super ACTUAL>> conditions() ,public org.assertj.core.description.Description description() ,public abstract java.lang.String descriptionPrefix() <variables>protected static final java.lang.String PREFIX_DELIMITER,protected static final java.lang.String SUFFIX_DELIMITER,Collection<Condition<? super ACTUAL>> conditions