package java.lang;

import java.io.IOException;
import ej.annotation.Nullable;

/**
 * An object to which <code>char</code> sequences and values can be appended.
 *
 * <p>
 * The characters to be appended should be valid Unicode characters. Note that supplementary
 * characters may be composed of multiple 16-bit <code>char</code> values.
 *
 * <p>
 * Appendables are not necessarily safe for multithreaded access. Thread safety is the
 * responsibility of classes that extend and implement this interface.
 *
 * <p>
 * Since this interface may be implemented by existing classes with different styles of error
 * handling there is no guarantee that errors will be propagated to the invoker.
 */
public interface Appendable {

    /**
     * Appends the specified character to this <code>Appendable</code>.
     *
     * @param c
     *        The character to append
     *
     * @return A reference to this <code>Appendable</code>
     *
     * @throws IOException
     *         If an I/O error occurs
     */
    Appendable append(char c) throws IOException;

    /**
     * Appends the specified character sequence to this <code>Appendable</code>.
     *
     * <p>
     * Depending on which class implements the character sequence <code>csq</code>, the entire sequence may
     * not be appended.
     *
     * @param csq
     *        The character sequence to append. If <code>csq</code> is <code>null</code>, then the four
     *        characters <code>"null"</code> are appended to this Appendable.
     *
     * @return A reference to this <code>Appendable</code>
     *
     * @throws IOException
     *         If an I/O error occurs
     */
    Appendable append(@Nullable CharSequence csq) throws IOException;

    /**
     * Appends a subsequence of the specified character sequence to this <code>Appendable</code>.
     *
     * <p>
     * An invocation of this method of the form <code>out.append(csq, start,
     * end)</code> when <code>csq</code> is not <code>null</code>, behaves in exactly the same way as the
     * invocation
     *
     * <pre>
     * out.append(csq.subSequence(start, end))
     * </pre>
     *
     * @param csq
     *        The character sequence from which a subsequence will be appended. If <code>csq</code> is
     *        <code>null</code>, then characters will be appended as if <code>csq</code> contained the four
     *        characters <code>"null"</code>.
     *
     * @param start
     *        The index of the first character in the subsequence
     *
     * @param end
     *        The index of the character following the last character in the subsequence
     *
     * @return A reference to this <code>Appendable</code>
     *
     * @throws IndexOutOfBoundsException
     *         If <code>start</code> or <code>end</code> are negative, <code>start</code> is greater than
     *         <code>end</code>, or <code>end</code> is greater than <code>csq.length()</code>
     *
     * @throws IOException
     *         If an I/O error occurs
     */
    Appendable append(@Nullable CharSequence csq, int start, int end) throws IOException;
}
