/**
 * 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-2015 the original author or authors.
 */
package org.assertj.core.api;

import org.assertj.core.description.Description;
import org.assertj.core.description.EmptyTextDescription;

/**
 * An object that has a description.
 * 
 * @param <S> the "self" type of this assertion class. Please read &quot;<a href="http://bit.ly/1IZIRcY"
 *          target="_blank">Emulating 'self types' using Java Generics to simplify fluent API implementation</a>&quot;
 *          for more details.
 * 
 * @author Alex Ruiz
 * @author Yvonne Wang
 * @author Mikhail Mazursky
 */
public interface Descriptable<S extends Descriptable<S>> {

  /**
   * Sets the description of this object supporting {@link String#format(String, Object...)} syntax.
   * <p>
   * Example :
   * <pre><code class='java'> try {
   *   // set a bad age to Mr Frodo which is really 33 years old.
   *   frodo.setAge(50);
   *   // you can specify a test description with as() method or describedAs(), it supports String format args
   *   assertThat(frodo.getAge()).as(&quot;check %s's age&quot;, frodo.getName()).isEqualTo(33);
   * } catch (AssertionError e) {
   *   assertThat(e).hasMessage(&quot;[check Frodo's age] expected:&lt;[33]&gt; but was:&lt;[50]&gt;&quot;);
   * }</code></pre>
   * 
   * @param description the new description to set.
   * @param args optional parameter if description is a format String.
   * @return {@code this} object.
   * @throws NullPointerException if the description is {@code null}.
   * @see #describedAs(String, Object...)
   */
  S as(String description, Object... args);

  /**
   * Sets the description of this object. To remove or clear the description, pass a
   * <code>{@link EmptyTextDescription}</code> as argument.
   * <p>
   * This overloaded version of "describedAs" offers more flexibility than the one taking a {@code String} by allowing
   * users to pass their own implementation of a description. For example, a description that creates its value lazily,
   * only when an assertion failure occurs.
   * </p>
   * 
   * @param description the new description to set.
   * @return {@code this} object.
   * @throws NullPointerException if the description is {@code null}.
   * @see #describedAs(Description)
   */
  S as(Description description);

  /**
   * Alias for <code>{@link #as(String, Object...)}</code> since "as" is a keyword in <a
   * href="http://groovy-lang.org/" target="_blank">Groovy</a>.
   * 
   * @param description the new description to set.
   * @return {@code this} object.
   * @throws NullPointerException if the description is {@code null}.
   */
  S describedAs(String description, Object... args);

  /**
   * Alias for <code>{@link #as(String, Object...)}</code> since "as" is a keyword in <a
   * href="http://groovy-lang.org/" target="_blank">Groovy</a>. To remove or clear the description, pass a
   * <code>{@link EmptyTextDescription}</code> as argument.
   * <p>
   * This overloaded version of "describedAs" offers more flexibility than the one taking a {@code String} by allowing
   * users to pass their own implementation of a description. For example, a description that creates its value lazily,
   * only when an assertion failure occurs.
   * </p>
   * 
   * @param description the new description to set.
   * @return {@code this} object.
   * @throws NullPointerException if the description is {@code null}.
   */
  S describedAs(Description description);
}

@@ -684,66 +684,8 @@
 ion;
-%0Aimport org.assertj.core.description.EmptyTextDescription;
 %0A%0A/*
@@ -1162,28 +1162,268 @@
 f th
-is object supporting
+e assertion that is going to be called after. %0A   * %3Cp%3E%0A   * You must set it %3Cb%3Ebefore%3C/b%3E calling the assertion otherwise it is ignored as the failing assertion breaks %0A   * the chained call by throwing an AssertionError.%0A   * %3Cp%3E%0A   * The description follows
  %7B@l
@@ -1632,16 +1632,8 @@
   //
- you can
  spe
@@ -1660,40 +1660,41 @@
 ion 
-with
+(call
  as() 
-method or describedAs(
+before the assertion !
 ), i
@@ -1718,20 +1718,23 @@
  format 
-args
+syntax.
 %0A   *   
@@ -2353,120 +2353,229 @@
 f th
-is object. To remove or clear the description, pas
+e assertion that is going to be called after. %0A   * %3Cp%3E%0A   * You must set it %3Cb%3Ebefore%3C/b%3E calling the assertion otherwise it is ignored as the failing assertion break
 s 
-a
 %0A   * 
-%3Ccode%3E%7B@link EmptyTextDescription%7D%3C/code%3E as argument
+the chained call by throwing an AssertionError
 .%0A  
@@ -3110,32 +3110,295 @@
 iption);%0A%0A  /**%0A
+   * Sets the description of the assertion that is going to be called after. %0A   * %3Cp%3E%0A   * You must set it %3Cb%3Ebefore%3C/b%3E calling the assertion otherwise it is ignored as the failing assertion breaks %0A   * the chained call by throwing an AssertionError.%0A   * %3Cp%3E%0A
    * Alias for %3C
@@ -3771,257 +3771,255 @@
   * 
-Alias for %3Ccode%3E%7B@link #as(String, Object...)%7D%3C/code%3E since %22as%22 is a keyword in %3Ca%0A   * href=%22http://groovy-lang.org/%22 target=%22_blank%22%3EGroovy%3C/a%3E. To remove or clear the description, pas
+Sets the description of the assertion that is going to be called after. %0A   * %3Cp%3E%0A   * You must set it %3Cb%3Ebefore%3C/b%3E calling the assertion otherwise it is ignored as the failing assertion break
 s 
-a
 %0A   * 
-%3Ccode%3E%7B@link EmptyTextDescription%7D%3C/code%3E as argument
+the chained call by throwing an AssertionError
 .%0A  

Clarify as() usage