class AbstractSoftAssertions extends DefaultAssertionErrorCollector
    implements SoftAssertionsProvider, InstanceOfAssertFactories {

  final SoftProxies proxies;

  protected AbstractSoftAssertions() {
    // pass itself as an AssertionErrorCollector instance
    proxies = new SoftProxies(this);
  }

  private static final AssertionErrorCreator ASSERTION_ERROR_CREATOR = new AssertionErrorCreator();

  public static void assertAll(AssertionErrorCollector collector) {
    List<AssertionError> errors = collector.assertionErrorsCollected();
    if (!errors.isEmpty()) throw ASSERTION_ERROR_CREATOR.multipleSoftAssertionsError(errors);
  }

  @Override
  public void assertAll() {
    assertAll(this);
  }

  @Override
  public <SELF extends Assert<? extends SELF, ? extends ACTUAL>, ACTUAL> SELF proxy(Class<SELF> assertClass,
                                                                                    Class<ACTUAL> actualClass, ACTUAL actual) {
    return proxies.createSoftAssertionProxy(assertClass, actualClass, actual);
  }

  /**
   * Fails with the given message.
   *
   * @param <T> dummy return value type
   * @param failureMessage error message.
   * @return nothing, it's just to be used in {@code doSomething(optional.orElseGet(() -> softly.fail("boom")));}.
   * @since 2.6.0 / 3.6.0
   */
  @CanIgnoreReturnValue
  public <T> T fail(String failureMessage) {
    AssertionError error = Failures.instance().failure(failureMessage);
    collectAssertionError(error);
    return null;
  }

  /**
   * Fails with an empty message to be used in code like:
   * <pre><code class='java'> doSomething(optional.orElseGet(() -> softly.fail()));</code></pre>
   *
   * @param <T> dummy return value type
   * @return nothing, it's just to be used in {@code doSomething(optional.orElseGet(() -> softly.fail()));}.
   * @since 3.26.0
   */
  @CanIgnoreReturnValue
  public <T> T fail() {<FILL_FUNCTION_BODY>}

  /**
   * Fails with the given message built like {@link String#format(String, Object...)}.
   *
   * @param <T> dummy return value type
   * @param failureMessage error message.
   * @param args Arguments referenced by the format specifiers in the format string.
   * @return nothing, it's just to be used in {@code doSomething(optional.orElseGet(() -> softly.fail("boom")));}.
   * @since 2.6.0 / 3.6.0
   */
  @CanIgnoreReturnValue
  public <T> T fail(String failureMessage, Object... args) {
    return fail(format(failureMessage, args));
  }

  /**
   * Fails with the given message and with the {@link Throwable} that caused the failure.
   *
   * @param <T> dummy return value type
   * @param failureMessage error message.
   * @param realCause cause of the error.
   * @return nothing, it's just to be used in {@code doSomething(optional.orElseGet(() -> softly.fail("boom")));}.
   * @since 2.6.0 / 3.6.0
   */
  @CanIgnoreReturnValue
  public <T> T fail(String failureMessage, Throwable realCause) {
    AssertionError error = Failures.instance().failure(failureMessage);
    error.initCause(realCause);
    collectAssertionError(error);
    return null;
  }

  /**
   * Fails with the {@link Throwable} that caused the failure and an empty message.
   * <p>
   * Example:
   * <pre><code class='java'> doSomething(optional.orElseGet(() -> softly.fail(cause)));</code></pre>
   *
   * @param <T> dummy return value type
   * @param realCause cause of the error.
   * @return nothing, it's just to be used in {@code doSomething(optional.orElseGet(() -> softly.fail(cause)));}.
   * @since 3.26.0
   */
  @CanIgnoreReturnValue
  public <T> T fail(Throwable realCause) {
    return fail("", realCause);
  }

  /**
   * Fails with a message explaining that a {@link Throwable} of given class was expected to be thrown
   * but had not been.
   *
   * @param throwableClass the Throwable class that was expected to be thrown.
   * @throws AssertionError with a message explaining that a {@link Throwable} of given class was expected to be thrown but had
   *           not been.
   * @since 2.6.0 / 3.6.0
   *
   * {@link Fail#shouldHaveThrown(Class)} can be used as a replacement.
   */
  public void failBecauseExceptionWasNotThrown(Class<? extends Throwable> throwableClass) {
    shouldHaveThrown(throwableClass);
  }

  /**
   * Fails with a message explaining that a {@link Throwable} of given class was expected to be thrown
   * but had not been.
   *
   * @param throwableClass the Throwable class that was expected to be thrown.
   * @throws AssertionError with a message explaining that a {@link Throwable} of given class was expected to be thrown but had
   *           not been.
   * @since 2.6.0 / 3.6.0
   */
  public void shouldHaveThrown(Class<? extends Throwable> throwableClass) {
    AssertionError error = Failures.instance().expectedThrowableNotThrown(throwableClass);
    collectAssertionError(error);
  }

  /**
   * Returns a copy of list of soft assertions collected errors.
   * @return a copy of list of soft assertions collected errors.
   */
  public List<Throwable> errorsCollected() {
    return decorateErrorsCollected(super.assertionErrorsCollected());
  }

}

    // pass an empty string because passing null results in a "null" error message.
    return fail("");
  
<methods>public void <init>() ,public void addAfterAssertionErrorCollected(org.assertj.core.api.AfterAssertionErrorCollected) ,public List<java.lang.AssertionError> assertionErrorsCollected() ,public void collectAssertionError(java.lang.AssertionError) ,public Optional<org.assertj.core.api.AssertionErrorCollector> getDelegate() ,public void setAfterAssertionErrorCollected(org.assertj.core.api.AfterAssertionErrorCollected) ,public void setDelegate(org.assertj.core.api.AssertionErrorCollector) ,public void succeeded() ,public boolean wasSuccess() <variables>private final List<org.assertj.core.api.AfterAssertionErrorCollected> callbacks,private final List<java.lang.AssertionError> collectedAssertionErrors,private org.assertj.core.api.AssertionErrorCollector delegate,private volatile boolean wasSuccess