/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
package org.apache.commons.text;

import java.io.IOException;
import java.io.Reader;
import java.io.Serializable;
import java.io.Writer;
import java.nio.CharBuffer;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

import org.apache.commons.text.matcher.StringMatcher;

/**
 * Builds a string from constituent parts providing a more flexible and powerful API than StringBuffer.
 * <p>
 * The main differences from StringBuffer/StringBuilder are:
 * </p>
 * <ul>
 * <li>Not synchronized</li>
 * <li>Not final</li>
 * <li>Subclasses have direct access to character array</li>
 * <li>Additional methods
 * <ul>
 * <li>appendWithSeparators - adds an array of values, with a separator</li>
 * <li>appendPadding - adds a length padding characters</li>
 * <li>appendFixedLength - adds a fixed width field to the builder</li>
 * <li>toCharArray/getChars - simpler ways to get a range of the character array</li>
 * <li>delete - delete char or string</li>
 * <li>replace - search and replace for a char or string</li>
 * <li>leftString/rightString/midString - substring without exceptions</li>
 * <li>contains - whether the builder contains a char or string</li>
 * <li>size/clear/isEmpty - collections style API methods</li>
 * </ul>
 * </li>
 * <li>Views
 * <ul>
 * <li>asTokenizer - uses the internal buffer as the source of a StrTokenizer</li>
 * <li>asReader - uses the internal buffer as the source of a Reader</li>
 * <li>asWriter - allows a Writer to write directly to the internal buffer</li>
 * </ul>
 * </li>
 * </ul>
 * <p>
 * The aim has been to provide an API that mimics very closely what StringBuffer provides, but with additional methods.
 * It should be noted that some edge cases, with invalid indices or null input, have been altered - see individual
 * methods. The biggest of these changes is that by default, null will not output the text 'null'. This can be
 * controlled by a property, {@link #setNullText(String)}.
 * </p>
 * <p>
 * This class is called {@code TextStringBuilder} instead of {@code StringBuilder} to avoid clashing with
 * {@link java.lang.StringBuilder}.
 * </p>
 *
 * @since 1.3
 */
public class TextStringBuilder implements CharSequence, Appendable, Serializable, Builder<String> {

    /**
     * The size of the string {@code "false"}.
     */
    private static final int FALSE_STRING_SIZE = "false".length();

    /**
     * The size of the string {@code "true"}.
     */
    private static final int TRUE_STRING_SIZE = "true".length();

    /**
     * The extra capacity for new builders.
     */
    static final int CAPACITY = 32;

    /**
     * Required for serialization support.
     *
     * @see java.io.Serializable
     */
    private static final long serialVersionUID = 1L;

    /** Internal data storage. */
    char[] buffer; // package-protected for test code use only
    /** Current size of the buffer. */
    private int size;
    /** The new line. */
    private String newLine;
    /** The null text. */
    private String nullText;

    // -----------------------------------------------------------------------
    /**
     * Constructor that creates an empty builder initial capacity 32 characters.
     */
    public TextStringBuilder() {
        this(CAPACITY);
    }

    /**
     * Constructor that creates an empty builder the specified initial capacity.
     *
     * @param initialCapacity
     *            the initial capacity, zero or less will be converted to 32
     */
    public TextStringBuilder(int initialCapacity) {
        super();
        if (initialCapacity <= 0) {
            initialCapacity = CAPACITY;
        }
        buffer = new char[initialCapacity];
    }

    /**
     * Constructor that creates a builder from the string, allocating 32 extra characters for growth.
     *
     * @param str
     *            the string to copy, null treated as blank string
     */
    public TextStringBuilder(final String str) {
        super();
        if (str == null) {
            buffer = new char[CAPACITY];
        } else {
            buffer = new char[str.length() + CAPACITY];
            append(str);
        }
    }

    // -----------------------------------------------------------------------
    /**
     * Gets the text to be appended when a new line is added.
     *
     * @return The new line text, null means use system default
     */
    public String getNewLineText() {
        return newLine;
    }

    /**
     * Sets the text to be appended when a new line is added.
     *
     * @param newLine
     *            the new line text, null means use system default
     * @return this, to enable chaining
     */
    public TextStringBuilder setNewLineText(final String newLine) {
        this.newLine = newLine;
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Gets the text to be appended when null is added.
     *
     * @return The null text, null means no append
     */
    public String getNullText() {
        return nullText;
    }

    /**
     * Sets the text to be appended when null is added.
     *
     * @param nullText
     *            the null text, null means no append
     * @return this, to enable chaining
     */
    public TextStringBuilder setNullText(String nullText) {
        if (nullText != null && nullText.isEmpty()) {
            nullText = null;
        }
        this.nullText = nullText;
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Gets the length of the string builder.
     *
     * @return The length
     */
    @Override
    public int length() {
        return size;
    }

    /**
     * Updates the length of the builder by either dropping the last characters or adding filler of Unicode zero.
     *
     * @param length
     *            the length to set to, must be zero or positive
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the length is negative
     */
    public TextStringBuilder setLength(final int length) {
        if (length < 0) {
            throw new StringIndexOutOfBoundsException(length);
        }
        if (length < size) {
            size = length;
        } else if (length > size) {
            ensureCapacity(length);
            final int oldEnd = size;
            final int newEnd = length;
            size = length;
            for (int i = oldEnd; i < newEnd; i++) {
                buffer[i] = '\0';
            }
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Gets the current size of the internal character array buffer.
     *
     * @return The capacity
     */
    public int capacity() {
        return buffer.length;
    }

    /**
     * Checks the capacity and ensures that it is at least the size specified.
     *
     * @param capacity
     *            the capacity to ensure
     * @return this, to enable chaining
     */
    public TextStringBuilder ensureCapacity(final int capacity) {
        if (capacity > buffer.length) {
            final char[] old = buffer;
            buffer = new char[capacity * 2];
            System.arraycopy(old, 0, buffer, 0, size);
        }
        return this;
    }

    /**
     * Minimizes the capacity to the actual length of the string.
     *
     * @return this, to enable chaining
     */
    public TextStringBuilder minimizeCapacity() {
        if (buffer.length > length()) {
            final char[] old = buffer;
            buffer = new char[length()];
            System.arraycopy(old, 0, buffer, 0, size);
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Gets the length of the string builder.
     * <p>
     * This method is the same as {@link #length()} and is provided to match the API of Collections.
     *
     * @return The length
     */
    public int size() {
        return size;
    }

    /**
     * Checks is the string builder is empty (convenience Collections API style method).
     * <p>
     * This method is the same as checking {@link #length()} and is provided to match the API of Collections.
     *
     * @return {@code true} if the size is {@code 0}.
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * Clears the string builder (convenience Collections API style method).
     * <p>
     * This method does not reduce the size of the internal character buffer. To do that, call {@code clear()}
     * followed by {@link #minimizeCapacity()}.
     * <p>
     * This method is the same as {@link #setLength(int)} called with zero and is provided to match the API of
     * Collections.
     *
     * @return this, to enable chaining
     */
    public TextStringBuilder clear() {
        size = 0;
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Gets the character at the specified index.
     *
     * @see #setCharAt(int, char)
     * @see #deleteCharAt(int)
     * @param index
     *            the index to retrieve, must be valid
     * @return The character at the index
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    @Override
    public char charAt(final int index) {
        if (index < 0 || index >= length()) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return buffer[index];
    }

    /**
     * Sets the character at the specified index.
     *
     * @see #charAt(int)
     * @see #deleteCharAt(int)
     * @param index
     *            the index to set
     * @param ch
     *            the new character
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder setCharAt(final int index, final char ch) {
        if (index < 0 || index >= length()) {
            throw new StringIndexOutOfBoundsException(index);
        }
        buffer[index] = ch;
        return this;
    }

    /**
     * Deletes the character at the specified index.
     *
     * @see #charAt(int)
     * @see #setCharAt(int, char)
     * @param index
     *            the index to delete
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder deleteCharAt(final int index) {
        if (index < 0 || index >= size) {
            throw new StringIndexOutOfBoundsException(index);
        }
        deleteImpl(index, index + 1, 1);
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Copies the builder's character array into a new character array.
     *
     * @return a new array that represents the contents of the builder
     */
    public char[] toCharArray() {
        if (size == 0) {
            return new char[0];
        }
        final char[] chars = new char[size];
        System.arraycopy(buffer, 0, chars, 0, size);
        return chars;
    }

    /**
     * Copies part of the builder's character array into a new character array.
     *
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param endIndex
     *            the end index, exclusive, must be valid except that if too large it is treated as end of string
     * @return a new array that holds part of the contents of the builder
     * @throws IndexOutOfBoundsException
     *             if startIndex is invalid, or if endIndex is invalid (but endIndex greater than size is valid)
     */
    public char[] toCharArray(final int startIndex, int endIndex) {
        endIndex = validateRange(startIndex, endIndex);
        final int len = endIndex - startIndex;
        if (len == 0) {
            return new char[0];
        }
        final char[] chars = new char[len];
        System.arraycopy(buffer, startIndex, chars, 0, len);
        return chars;
    }

    /**
     * Copies the character array into the specified array.
     *
     * @param destination
     *            the destination array, null will cause an array to be created
     * @return The input array, unless that was null or too small
     */
    public char[] getChars(char[] destination) {
        final int len = length();
        if (destination == null || destination.length < len) {
            destination = new char[len];
        }
        System.arraycopy(buffer, 0, destination, 0, len);
        return destination;
    }

    /**
     * Copies the character array into the specified array.
     *
     * @param startIndex
     *            first index to copy, inclusive, must be valid
     * @param endIndex
     *            last index, exclusive, must be valid
     * @param destination
     *            the destination array, must not be null or too small
     * @param destinationIndex
     *            the index to start copying in destination
     * @throws NullPointerException
     *             if the array is null
     * @throws IndexOutOfBoundsException
     *             if any index is invalid
     */
    public void getChars(final int startIndex, final int endIndex, final char[] destination,
            final int destinationIndex) {
        if (startIndex < 0) {
            throw new StringIndexOutOfBoundsException(startIndex);
        }
        if (endIndex < 0 || endIndex > length()) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        if (startIndex > endIndex) {
            throw new StringIndexOutOfBoundsException("end < start");
        }
        System.arraycopy(buffer, startIndex, destination, destinationIndex, endIndex - startIndex);
    }

    // -----------------------------------------------------------------------
    /**
     * If possible, reads chars from the provided {@link Readable} directly into underlying character buffer without
     * making extra copies.
     *
     * @param readable
     *            object to read from
     * @return The number of characters read
     * @throws IOException
     *             if an I/O error occurs
     *
     * @see #appendTo(Appendable)
     */
    public int readFrom(final Readable readable) throws IOException {
        final int oldSize = size;
        if (readable instanceof Reader) {
            final Reader r = (Reader) readable;
            ensureCapacity(size + 1);
            int read;
            while ((read = r.read(buffer, size, buffer.length - size)) != -1) {
                size += read;
                ensureCapacity(size + 1);
            }
        } else if (readable instanceof CharBuffer) {
            final CharBuffer cb = (CharBuffer) readable;
            final int remaining = cb.remaining();
            ensureCapacity(size + remaining);
            cb.get(buffer, size, remaining);
            size += remaining;
        } else {
            while (true) {
                ensureCapacity(size + 1);
                final CharBuffer buf = CharBuffer.wrap(buffer, size, buffer.length - size);
                final int read = readable.read(buf);
                if (read == -1) {
                    break;
                }
                size += read;
            }
        }
        return size - oldSize;
    }

    // -----------------------------------------------------------------------
    /**
     * Appends the new line string to this string builder.
     * <p>
     * The new line string can be altered using {@link #setNewLineText(String)}. This might be used to force the output
     * to always use Unix line endings even when on Windows.
     *
     * @return this, to enable chaining
     */
    public TextStringBuilder appendNewLine() {
        if (newLine == null) {
            append(System.lineSeparator());
            return this;
        }
        return append(newLine);
    }

    /**
     * Appends the text representing {@code null} to this string builder.
     *
     * @return this, to enable chaining
     */
    public TextStringBuilder appendNull() {
        if (nullText == null) {
            return this;
        }
        return append(nullText);
    }

    /**
     * Appends an object to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param obj
     *            the object to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final Object obj) {
        if (obj == null) {
            return appendNull();
        }
        if (obj instanceof CharSequence) {
            return append((CharSequence) obj);
        }
        return append(obj.toString());
    }

    /**
     * Appends a CharSequence to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param seq
     *            the CharSequence to append
     * @return this, to enable chaining
     */
    @Override
    public TextStringBuilder append(final CharSequence seq) {
        if (seq == null) {
            return appendNull();
        }
        if (seq instanceof TextStringBuilder) {
            return append((TextStringBuilder) seq);
        }
        if (seq instanceof StringBuilder) {
            return append((StringBuilder) seq);
        }
        if (seq instanceof StringBuffer) {
            return append((StringBuffer) seq);
        }
        if (seq instanceof CharBuffer) {
            return append((CharBuffer) seq);
        }
        return append(seq.toString());
    }

    /**
     * Appends part of a CharSequence to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param seq
     *            the CharSequence to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param endIndex
     *            the end index, exclusive, must be valid
     * @return this, to enable chaining
     */
    @Override
    public TextStringBuilder append(final CharSequence seq, final int startIndex, final int endIndex) {
        if (seq == null) {
            return appendNull();
        }
        if (endIndex <= 0) {
            throw new StringIndexOutOfBoundsException("endIndex must be valid");
        }
        if (startIndex >= endIndex) {
            throw new StringIndexOutOfBoundsException("endIndex must be greater than startIndex");
        }
        return append(seq.toString(), startIndex, endIndex - startIndex);
    }

    /**
     * Appends a string to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param str
     *            the string to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final String str) {
        if (str == null) {
            return appendNull();
        }
        final int strLen = str.length();
        if (strLen > 0) {
            final int len = length();
            ensureCapacity(len + strLen);
            str.getChars(0, strLen, buffer, len);
            size += strLen;
        }
        return this;
    }

    /**
     * Appends part of a string to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param str
     *            the string to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param length
     *            the length to append, must be valid
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final String str, final int startIndex, final int length) {
        if (str == null) {
            return appendNull();
        }
        if (startIndex < 0 || startIndex > str.length()) {
            throw new StringIndexOutOfBoundsException("startIndex must be valid");
        }
        if (length < 0 || startIndex + length > str.length()) {
            throw new StringIndexOutOfBoundsException("length must be valid");
        }
        if (length > 0) {
            final int len = length();
            ensureCapacity(len + length);
            str.getChars(startIndex, startIndex + length, buffer, len);
            size += length;
        }
        return this;
    }

    /**
     * Calls {@link String#format(String, Object...)} and appends the result.
     *
     * @param format
     *            the format string
     * @param objs
     *            the objects to use in the format string
     * @return {@code this} to enable chaining
     * @see String#format(String, Object...)
     */
    public TextStringBuilder append(final String format, final Object... objs) {
        return append(String.format(format, objs));
    }

    /**
     * Appends the contents of a char buffer to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param buf
     *            the char buffer to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final CharBuffer buf) {
        if (buf == null) {
            return appendNull();
        }
        if (buf.hasArray()) {
            final int length = buf.remaining();
            final int len = length();
            ensureCapacity(len + length);
            System.arraycopy(buf.array(), buf.arrayOffset() + buf.position(), buffer, len, length);
            size += length;
        } else {
            append(buf.toString());
        }
        return this;
    }

    /**
     * Appends the contents of a char buffer to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param buf
     *            the char buffer to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param length
     *            the length to append, must be valid
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final CharBuffer buf, final int startIndex, final int length) {
        if (buf == null) {
            return appendNull();
        }
        if (buf.hasArray()) {
            final int totalLength = buf.remaining();
            if (startIndex < 0 || startIndex > totalLength) {
                throw new StringIndexOutOfBoundsException("startIndex must be valid");
            }
            if (length < 0 || startIndex + length > totalLength) {
                throw new StringIndexOutOfBoundsException("length must be valid");
            }
            final int len = length();
            ensureCapacity(len + length);
            System.arraycopy(buf.array(), buf.arrayOffset() + buf.position() + startIndex, buffer, len, length);
            size += length;
        } else {
            append(buf.toString(), startIndex, length);
        }
        return this;
    }

    /**
     * Appends a string buffer to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param str
     *            the string buffer to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final StringBuffer str) {
        if (str == null) {
            return appendNull();
        }
        final int strLen = str.length();
        if (strLen > 0) {
            final int len = length();
            ensureCapacity(len + strLen);
            str.getChars(0, strLen, buffer, len);
            size += strLen;
        }
        return this;
    }

    /**
     * Appends part of a string buffer to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param str
     *            the string to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param length
     *            the length to append, must be valid
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final StringBuffer str, final int startIndex, final int length) {
        if (str == null) {
            return appendNull();
        }
        if (startIndex < 0 || startIndex > str.length()) {
            throw new StringIndexOutOfBoundsException("startIndex must be valid");
        }
        if (length < 0 || startIndex + length > str.length()) {
            throw new StringIndexOutOfBoundsException("length must be valid");
        }
        if (length > 0) {
            final int len = length();
            ensureCapacity(len + length);
            str.getChars(startIndex, startIndex + length, buffer, len);
            size += length;
        }
        return this;
    }

    /**
     * Appends a StringBuilder to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param str
     *            the StringBuilder to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final StringBuilder str) {
        if (str == null) {
            return appendNull();
        }
        final int strLen = str.length();
        if (strLen > 0) {
            final int len = length();
            ensureCapacity(len + strLen);
            str.getChars(0, strLen, buffer, len);
            size += strLen;
        }
        return this;
    }

    /**
     * Appends part of a StringBuilder to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param str
     *            the StringBuilder to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param length
     *            the length to append, must be valid
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final StringBuilder str, final int startIndex, final int length) {
        if (str == null) {
            return appendNull();
        }
        if (startIndex < 0 || startIndex > str.length()) {
            throw new StringIndexOutOfBoundsException("startIndex must be valid");
        }
        if (length < 0 || startIndex + length > str.length()) {
            throw new StringIndexOutOfBoundsException("length must be valid");
        }
        if (length > 0) {
            final int len = length();
            ensureCapacity(len + length);
            str.getChars(startIndex, startIndex + length, buffer, len);
            size += length;
        }
        return this;
    }

    /**
     * Appends another string builder to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param str
     *            the string builder to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final TextStringBuilder str) {
        if (str == null) {
            return appendNull();
        }
        final int strLen = str.length();
        if (strLen > 0) {
            final int len = length();
            ensureCapacity(len + strLen);
            System.arraycopy(str.buffer, 0, buffer, len, strLen);
            size += strLen;
        }
        return this;
    }

    /**
     * Appends part of a string builder to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param str
     *            the string to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param length
     *            the length to append, must be valid
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final TextStringBuilder str, final int startIndex, final int length) {
        if (str == null) {
            return appendNull();
        }
        if (startIndex < 0 || startIndex > str.length()) {
            throw new StringIndexOutOfBoundsException("startIndex must be valid");
        }
        if (length < 0 || startIndex + length > str.length()) {
            throw new StringIndexOutOfBoundsException("length must be valid");
        }
        if (length > 0) {
            final int len = length();
            ensureCapacity(len + length);
            str.getChars(startIndex, startIndex + length, buffer, len);
            size += length;
        }
        return this;
    }

    /**
     * Appends a char array to the string builder. Appending null will call {@link #appendNull()}.
     *
     * @param chars
     *            the char array to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final char[] chars) {
        if (chars == null) {
            return appendNull();
        }
        final int strLen = chars.length;
        if (strLen > 0) {
            final int len = length();
            ensureCapacity(len + strLen);
            System.arraycopy(chars, 0, buffer, len, strLen);
            size += strLen;
        }
        return this;
    }

    /**
     * Appends a char array to the string builder. Appending null will call {@link #appendNull()}.
     *
     * @param chars
     *            the char array to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param length
     *            the length to append, must be valid
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final char[] chars, final int startIndex, final int length) {
        if (chars == null) {
            return appendNull();
        }
        if (startIndex < 0 || startIndex > chars.length) {
            throw new StringIndexOutOfBoundsException("Invalid startIndex: " + length);
        }
        if (length < 0 || startIndex + length > chars.length) {
            throw new StringIndexOutOfBoundsException("Invalid length: " + length);
        }
        if (length > 0) {
            final int len = length();
            ensureCapacity(len + length);
            System.arraycopy(chars, startIndex, buffer, len, length);
            size += length;
        }
        return this;
    }

    /**
     * Appends a boolean value to the string builder.
     *
     * @param value
     *            the value to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final boolean value) {
        if (value) {
            ensureCapacity(size + TRUE_STRING_SIZE);
            buffer[size++] = 't';
            buffer[size++] = 'r';
            buffer[size++] = 'u';
            buffer[size++] = 'e';
        } else {
            ensureCapacity(size + FALSE_STRING_SIZE);
            buffer[size++] = 'f';
            buffer[size++] = 'a';
            buffer[size++] = 'l';
            buffer[size++] = 's';
            buffer[size++] = 'e';
        }
        return this;
    }

    /**
     * Appends a char value to the string builder.
     *
     * @param ch
     *            the value to append
     * @return this, to enable chaining
     */
    @Override
    public TextStringBuilder append(final char ch) {
        final int len = length();
        ensureCapacity(len + 1);
        buffer[size++] = ch;
        return this;
    }

    /**
     * Appends an int value to the string builder using {@code String.valueOf}.
     *
     * @param value
     *            the value to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final int value) {
        return append(String.valueOf(value));
    }

    /**
     * Appends a long value to the string builder using {@code String.valueOf}.
     *
     * @param value
     *            the value to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final long value) {
        return append(String.valueOf(value));
    }

    /**
     * Appends a float value to the string builder using {@code String.valueOf}.
     *
     * @param value
     *            the value to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final float value) {
        return append(String.valueOf(value));
    }

    /**
     * Appends a double value to the string builder using {@code String.valueOf}.
     *
     * @param value
     *            the value to append
     * @return this, to enable chaining
     */
    public TextStringBuilder append(final double value) {
        return append(String.valueOf(value));
    }

    // -----------------------------------------------------------------------
    /**
     * Appends an object followed by a new line to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param obj
     *            the object to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final Object obj) {
        return append(obj).appendNewLine();
    }

    /**
     * Appends a string followed by a new line to this string builder. Appending null will call {@link #appendNull()}.
     *
     * @param str
     *            the string to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final String str) {
        return append(str).appendNewLine();
    }

    /**
     * Appends part of a string followed by a new line to this string builder. Appending null will call
     * {@link #appendNull()}.
     *
     * @param str
     *            the string to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param length
     *            the length to append, must be valid
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final String str, final int startIndex, final int length) {
        return append(str, startIndex, length).appendNewLine();
    }

    /**
     * Calls {@link String#format(String, Object...)} and appends the result.
     *
     * @param format
     *            the format string
     * @param objs
     *            the objects to use in the format string
     * @return {@code this} to enable chaining
     * @see String#format(String, Object...)
     */
    public TextStringBuilder appendln(final String format, final Object... objs) {
        return append(format, objs).appendNewLine();
    }

    /**
     * Appends a string buffer followed by a new line to this string builder. Appending null will call
     * {@link #appendNull()}.
     *
     * @param str
     *            the string buffer to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final StringBuffer str) {
        return append(str).appendNewLine();
    }

    /**
     * Appends a string builder followed by a new line to this string builder. Appending null will call
     * {@link #appendNull()}.
     *
     * @param str
     *            the string builder to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final StringBuilder str) {
        return append(str).appendNewLine();
    }

    /**
     * Appends part of a string builder followed by a new line to this string builder. Appending null will call
     * {@link #appendNull()}.
     *
     * @param str
     *            the string builder to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param length
     *            the length to append, must be valid
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final StringBuilder str, final int startIndex, final int length) {
        return append(str, startIndex, length).appendNewLine();
    }

    /**
     * Appends part of a string buffer followed by a new line to this string builder. Appending null will call
     * {@link #appendNull()}.
     *
     * @param str
     *            the string to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param length
     *            the length to append, must be valid
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final StringBuffer str, final int startIndex, final int length) {
        return append(str, startIndex, length).appendNewLine();
    }

    /**
     * Appends another string builder followed by a new line to this string builder. Appending null will call
     * {@link #appendNull()}.
     *
     * @param str
     *            the string builder to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final TextStringBuilder str) {
        return append(str).appendNewLine();
    }

    /**
     * Appends part of a string builder followed by a new line to this string builder. Appending null will call
     * {@link #appendNull()}.
     *
     * @param str
     *            the string to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param length
     *            the length to append, must be valid
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final TextStringBuilder str, final int startIndex, final int length) {
        return append(str, startIndex, length).appendNewLine();
    }

    /**
     * Appends a char array followed by a new line to the string builder. Appending null will call
     * {@link #appendNull()}.
     *
     * @param chars
     *            the char array to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final char[] chars) {
        return append(chars).appendNewLine();
    }

    /**
     * Appends a char array followed by a new line to the string builder. Appending null will call
     * {@link #appendNull()}.
     *
     * @param chars
     *            the char array to append
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param length
     *            the length to append, must be valid
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final char[] chars, final int startIndex, final int length) {
        return append(chars, startIndex, length).appendNewLine();
    }

    /**
     * Appends a boolean value followed by a new line to the string builder.
     *
     * @param value
     *            the value to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final boolean value) {
        return append(value).appendNewLine();
    }

    /**
     * Appends a char value followed by a new line to the string builder.
     *
     * @param ch
     *            the value to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final char ch) {
        return append(ch).appendNewLine();
    }

    /**
     * Appends an int value followed by a new line to the string builder using {@code String.valueOf}.
     *
     * @param value
     *            the value to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final int value) {
        return append(value).appendNewLine();
    }

    /**
     * Appends a long value followed by a new line to the string builder using {@code String.valueOf}.
     *
     * @param value
     *            the value to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final long value) {
        return append(value).appendNewLine();
    }

    /**
     * Appends a float value followed by a new line to the string builder using {@code String.valueOf}.
     *
     * @param value
     *            the value to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final float value) {
        return append(value).appendNewLine();
    }

    /**
     * Appends a double value followed by a new line to the string builder using {@code String.valueOf}.
     *
     * @param value
     *            the value to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendln(final double value) {
        return append(value).appendNewLine();
    }

    // -----------------------------------------------------------------------
    /**
     * Appends each item in an array to the builder without any separators. Appending a null array will have no effect.
     * Each object is appended using {@link #append(Object)}.
     *
     * @param <T>
     *            the element type
     * @param array
     *            the array to append
     * @return this, to enable chaining
     */
    public <T> TextStringBuilder appendAll(@SuppressWarnings("unchecked") final T... array) {
        /*
         * @SuppressWarnings used to hide warning about vararg usage. We cannot use @SafeVarargs, since this method is
         * not final. Using @SuppressWarnings is fine, because it isn't inherited by subclasses, so each subclass must
         * vouch for itself whether its use of 'array' is safe.
         */
        if (array != null && array.length > 0) {
            for (final Object element : array) {
                append(element);
            }
        }
        return this;
    }

    /**
     * Appends each item in an iterable to the builder without any separators. Appending a null iterable will have no
     * effect. Each object is appended using {@link #append(Object)}.
     *
     * @param iterable
     *            the iterable to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendAll(final Iterable<?> iterable) {
        if (iterable != null) {
            for (final Object o : iterable) {
                append(o);
            }
        }
        return this;
    }

    /**
     * Appends each item in an iterator to the builder without any separators. Appending a null iterator will have no
     * effect. Each object is appended using {@link #append(Object)}.
     *
     * @param it
     *            the iterator to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendAll(final Iterator<?> it) {
        if (it != null) {
            while (it.hasNext()) {
                append(it.next());
            }
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Appends an array placing separators between each value, but not before the first or after the last. Appending a
     * null array will have no effect. Each object is appended using {@link #append(Object)}.
     *
     * @param array
     *            the array to append
     * @param separator
     *            the separator to use, null means no separator
     * @return this, to enable chaining
     */
    public TextStringBuilder appendWithSeparators(final Object[] array, final String separator) {
        if (array != null && array.length > 0) {
            final String sep = Objects.toString(separator, "");
            append(array[0]);
            for (int i = 1; i < array.length; i++) {
                append(sep);
                append(array[i]);
            }
        }
        return this;
    }

    /**
     * Appends an iterable placing separators between each value, but not before the first or after the last. Appending
     * a null iterable will have no effect. Each object is appended using {@link #append(Object)}.
     *
     * @param iterable
     *            the iterable to append
     * @param separator
     *            the separator to use, null means no separator
     * @return this, to enable chaining
     */
    public TextStringBuilder appendWithSeparators(final Iterable<?> iterable, final String separator) {
        if (iterable != null) {
            final String sep = Objects.toString(separator, "");
            final Iterator<?> it = iterable.iterator();
            while (it.hasNext()) {
                append(it.next());
                if (it.hasNext()) {
                    append(sep);
                }
            }
        }
        return this;
    }

    /**
     * Appends an iterator placing separators between each value, but not before the first or after the last. Appending
     * a null iterator will have no effect. Each object is appended using {@link #append(Object)}.
     *
     * @param it
     *            the iterator to append
     * @param separator
     *            the separator to use, null means no separator
     * @return this, to enable chaining
     */
    public TextStringBuilder appendWithSeparators(final Iterator<?> it, final String separator) {
        if (it != null) {
            final String sep = Objects.toString(separator, "");
            while (it.hasNext()) {
                append(it.next());
                if (it.hasNext()) {
                    append(sep);
                }
            }
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Appends a separator if the builder is currently non-empty. Appending a null separator will have no effect. The
     * separator is appended using {@link #append(String)}.
     * <p>
     * This method is useful for adding a separator each time around the loop except the first.
     *
     * <pre>
     * for (Iterator it = list.iterator(); it.hasNext();) {
     *     appendSeparator(",");
     *     append(it.next());
     * }
     * </pre>
     *
     * Note that for this simple example, you should use {@link #appendWithSeparators(Iterable, String)}.
     *
     * @param separator
     *            the separator to use, null means no separator
     * @return this, to enable chaining
     */
    public TextStringBuilder appendSeparator(final String separator) {
        return appendSeparator(separator, null);
    }

    /**
     * Appends one of both separators to the StrBuilder. If the builder is currently empty it will append the
     * defaultIfEmpty-separator Otherwise it will append the standard-separator
     *
     * Appending a null separator will have no effect. The separator is appended using {@link #append(String)}.
     * <p>
     * This method is for example useful for constructing queries
     *
     * <pre>
     * StrBuilder whereClause = new StrBuilder();
     * if(searchCommand.getPriority() != null) {
     *  whereClause.appendSeparator(" and", " where");
     *  whereClause.append(" priority = ?")
     * }
     * if(searchCommand.getComponent() != null) {
     *  whereClause.appendSeparator(" and", " where");
     *  whereClause.append(" component = ?")
     * }
     * selectClause.append(whereClause)
     * </pre>
     *
     * @param standard
     *            the separator if builder is not empty, null means no separator
     * @param defaultIfEmpty
     *            the separator if builder is empty, null means no separator
     * @return this, to enable chaining
     */
    public TextStringBuilder appendSeparator(final String standard, final String defaultIfEmpty) {
        final String str = isEmpty() ? defaultIfEmpty : standard;
        if (str != null) {
            append(str);
        }
        return this;
    }

    /**
     * Appends a separator if the builder is currently non-empty. The separator is appended using {@link #append(char)}.
     * <p>
     * This method is useful for adding a separator each time around the loop except the first.
     *
     * <pre>
     * for (Iterator it = list.iterator(); it.hasNext();) {
     *     appendSeparator(',');
     *     append(it.next());
     * }
     * </pre>
     *
     * Note that for this simple example, you should use {@link #appendWithSeparators(Iterable, String)}.
     *
     * @param separator
     *            the separator to use
     * @return this, to enable chaining
     */
    public TextStringBuilder appendSeparator(final char separator) {
        if (size() > 0) {
            append(separator);
        }
        return this;
    }

    /**
     * Append one of both separators to the builder If the builder is currently empty it will append the
     * defaultIfEmpty-separator Otherwise it will append the standard-separator
     *
     * The separator is appended using {@link #append(char)}.
     *
     * @param standard
     *            the separator if builder is not empty
     * @param defaultIfEmpty
     *            the separator if builder is empty
     * @return this, to enable chaining
     */
    public TextStringBuilder appendSeparator(final char standard, final char defaultIfEmpty) {
        if (size() > 0) {
            append(standard);
        } else {
            append(defaultIfEmpty);
        }
        return this;
    }

    /**
     * Appends a separator to the builder if the loop index is greater than zero. Appending a null separator will have
     * no effect. The separator is appended using {@link #append(String)}.
     * <p>
     * This method is useful for adding a separator each time around the loop except the first.
     * </p>
     *
     * <pre>
     * for (int i = 0; i &lt; list.size(); i++) {
     *     appendSeparator(",", i);
     *     append(list.get(i));
     * }
     * </pre>
     *
     * Note that for this simple example, you should use {@link #appendWithSeparators(Iterable, String)}.
     *
     * @param separator
     *            the separator to use, null means no separator
     * @param loopIndex
     *            the loop index
     * @return this, to enable chaining
     */
    public TextStringBuilder appendSeparator(final String separator, final int loopIndex) {
        if (separator != null && loopIndex > 0) {
            append(separator);
        }
        return this;
    }

    /**
     * Appends a separator to the builder if the loop index is greater than zero. The separator is appended using
     * {@link #append(char)}.
     * <p>
     * This method is useful for adding a separator each time around the loop except the first.
     * </p>
     *
     * <pre>
     * for (int i = 0; i &lt; list.size(); i++) {
     *     appendSeparator(",", i);
     *     append(list.get(i));
     * }
     * </pre>
     *
     * Note that for this simple example, you should use {@link #appendWithSeparators(Iterable, String)}.
     *
     * @param separator
     *            the separator to use
     * @param loopIndex
     *            the loop index
     * @return this, to enable chaining
     */
    public TextStringBuilder appendSeparator(final char separator, final int loopIndex) {
        if (loopIndex > 0) {
            append(separator);
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Appends the pad character to the builder the specified number of times.
     *
     * @param length
     *            the length to append, negative means no append
     * @param padChar
     *            the character to append
     * @return this, to enable chaining
     */
    public TextStringBuilder appendPadding(final int length, final char padChar) {
        if (length >= 0) {
            ensureCapacity(size + length);
            for (int i = 0; i < length; i++) {
                buffer[size++] = padChar;
            }
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Appends an object to the builder padding on the left to a fixed width. The {@code toString} of the object is
     * used. If the object is larger than the length, the left hand side is lost. If the object is null, the null text
     * value is used.
     *
     * @param obj
     *            the object to append, null uses null text
     * @param width
     *            the fixed field width, zero or negative has no effect
     * @param padChar
     *            the pad character to use
     * @return this, to enable chaining
     */
    public TextStringBuilder appendFixedWidthPadLeft(final Object obj, final int width, final char padChar) {
        if (width > 0) {
            ensureCapacity(size + width);
            String str = obj == null ? getNullText() : obj.toString();
            if (str == null) {
                str = "";
            }
            final int strLen = str.length();
            if (strLen >= width) {
                str.getChars(strLen - width, strLen, buffer, size);
            } else {
                final int padLen = width - strLen;
                for (int i = 0; i < padLen; i++) {
                    buffer[size + i] = padChar;
                }
                str.getChars(0, strLen, buffer, size + padLen);
            }
            size += width;
        }
        return this;
    }

    /**
     * Appends an object to the builder padding on the left to a fixed width. The {@code String.valueOf} of the
     * {@code int} value is used. If the formatted value is larger than the length, the left hand side is lost.
     *
     * @param value
     *            the value to append
     * @param width
     *            the fixed field width, zero or negative has no effect
     * @param padChar
     *            the pad character to use
     * @return this, to enable chaining
     */
    public TextStringBuilder appendFixedWidthPadLeft(final int value, final int width, final char padChar) {
        return appendFixedWidthPadLeft(String.valueOf(value), width, padChar);
    }

    /**
     * Appends an object to the builder padding on the right to a fixed length. The {@code toString} of the object
     * is used. If the object is larger than the length, the right hand side is lost. If the object is null, null text
     * value is used.
     *
     * @param obj
     *            the object to append, null uses null text
     * @param width
     *            the fixed field width, zero or negative has no effect
     * @param padChar
     *            the pad character to use
     * @return this, to enable chaining
     */
    public TextStringBuilder appendFixedWidthPadRight(final Object obj, final int width, final char padChar) {
        if (width > 0) {
            ensureCapacity(size + width);
            String str = obj == null ? getNullText() : obj.toString();
            if (str == null) {
                str = "";
            }
            final int strLen = str.length();
            if (strLen >= width) {
                str.getChars(0, width, buffer, size);
            } else {
                final int padLen = width - strLen;
                str.getChars(0, strLen, buffer, size);
                for (int i = 0; i < padLen; i++) {
                    buffer[size + strLen + i] = padChar;
                }
            }
            size += width;
        }
        return this;
    }

    /**
     * Appends an object to the builder padding on the right to a fixed length. The {@code String.valueOf} of the
     * {@code int} value is used. If the object is larger than the length, the right hand side is lost.
     *
     * @param value
     *            the value to append
     * @param width
     *            the fixed field width, zero or negative has no effect
     * @param padChar
     *            the pad character to use
     * @return this, to enable chaining
     */
    public TextStringBuilder appendFixedWidthPadRight(final int value, final int width, final char padChar) {
        return appendFixedWidthPadRight(String.valueOf(value), width, padChar);
    }

    // -----------------------------------------------------------------------
    /**
     * Inserts the string representation of an object into this builder. Inserting null will use the stored null text
     * value.
     *
     * @param index
     *            the index to add at, must be valid
     * @param obj
     *            the object to insert
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder insert(final int index, final Object obj) {
        if (obj == null) {
            return insert(index, nullText);
        }
        return insert(index, obj.toString());
    }

    /**
     * Inserts the string into this builder. Inserting null will use the stored null text value.
     *
     * @param index
     *            the index to add at, must be valid
     * @param str
     *            the string to insert
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder insert(final int index, String str) {
        validateIndex(index);
        if (str == null) {
            str = nullText;
        }
        if (str != null) {
            final int strLen = str.length();
            if (strLen > 0) {
                final int newSize = size + strLen;
                ensureCapacity(newSize);
                System.arraycopy(buffer, index, buffer, index + strLen, size - index);
                size = newSize;
                str.getChars(0, strLen, buffer, index);
            }
        }
        return this;
    }

    /**
     * Inserts the character array into this builder. Inserting null will use the stored null text value.
     *
     * @param index
     *            the index to add at, must be valid
     * @param chars
     *            the char array to insert
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder insert(final int index, final char[] chars) {
        validateIndex(index);
        if (chars == null) {
            return insert(index, nullText);
        }
        final int len = chars.length;
        if (len > 0) {
            ensureCapacity(size + len);
            System.arraycopy(buffer, index, buffer, index + len, size - index);
            System.arraycopy(chars, 0, buffer, index, len);
            size += len;
        }
        return this;
    }

    /**
     * Inserts part of the character array into this builder. Inserting null will use the stored null text value.
     *
     * @param index
     *            the index to add at, must be valid
     * @param chars
     *            the char array to insert
     * @param offset
     *            the offset into the character array to start at, must be valid
     * @param length
     *            the length of the character array part to copy, must be positive
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if any index is invalid
     */
    public TextStringBuilder insert(final int index, final char[] chars, final int offset, final int length) {
        validateIndex(index);
        if (chars == null) {
            return insert(index, nullText);
        }
        if (offset < 0 || offset > chars.length) {
            throw new StringIndexOutOfBoundsException("Invalid offset: " + offset);
        }
        if (length < 0 || offset + length > chars.length) {
            throw new StringIndexOutOfBoundsException("Invalid length: " + length);
        }
        if (length > 0) {
            ensureCapacity(size + length);
            System.arraycopy(buffer, index, buffer, index + length, size - index);
            System.arraycopy(chars, offset, buffer, index, length);
            size += length;
        }
        return this;
    }

    /**
     * Inserts the value into this builder.
     *
     * @param index
     *            the index to add at, must be valid
     * @param value
     *            the value to insert
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder insert(int index, final boolean value) {
        validateIndex(index);
        if (value) {
            ensureCapacity(size + TRUE_STRING_SIZE);
            System.arraycopy(buffer, index, buffer, index + TRUE_STRING_SIZE, size - index);
            buffer[index++] = 't';
            buffer[index++] = 'r';
            buffer[index++] = 'u';
            buffer[index] = 'e';
            size += TRUE_STRING_SIZE;
        } else {
            ensureCapacity(size + FALSE_STRING_SIZE);
            System.arraycopy(buffer, index, buffer, index + FALSE_STRING_SIZE, size - index);
            buffer[index++] = 'f';
            buffer[index++] = 'a';
            buffer[index++] = 'l';
            buffer[index++] = 's';
            buffer[index] = 'e';
            size += FALSE_STRING_SIZE;
        }
        return this;
    }

    /**
     * Inserts the value into this builder.
     *
     * @param index
     *            the index to add at, must be valid
     * @param value
     *            the value to insert
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder insert(final int index, final char value) {
        validateIndex(index);
        ensureCapacity(size + 1);
        System.arraycopy(buffer, index, buffer, index + 1, size - index);
        buffer[index] = value;
        size++;
        return this;
    }

    /**
     * Inserts the value into this builder.
     *
     * @param index
     *            the index to add at, must be valid
     * @param value
     *            the value to insert
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder insert(final int index, final int value) {
        return insert(index, String.valueOf(value));
    }

    /**
     * Inserts the value into this builder.
     *
     * @param index
     *            the index to add at, must be valid
     * @param value
     *            the value to insert
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder insert(final int index, final long value) {
        return insert(index, String.valueOf(value));
    }

    /**
     * Inserts the value into this builder.
     *
     * @param index
     *            the index to add at, must be valid
     * @param value
     *            the value to insert
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder insert(final int index, final float value) {
        return insert(index, String.valueOf(value));
    }

    /**
     * Inserts the value into this builder.
     *
     * @param index
     *            the index to add at, must be valid
     * @param value
     *            the value to insert
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder insert(final int index, final double value) {
        return insert(index, String.valueOf(value));
    }

    // -----------------------------------------------------------------------
    /**
     * Internal method to delete a range without validation.
     *
     * @param startIndex
     *            the start index, must be valid
     * @param endIndex
     *            the end index (exclusive), must be valid
     * @param len
     *            the length, must be valid
     * @throws IndexOutOfBoundsException
     *             if any index is invalid
     */
    private void deleteImpl(final int startIndex, final int endIndex, final int len) {
        System.arraycopy(buffer, endIndex, buffer, startIndex, size - endIndex);
        size -= len;
    }

    /**
     * Deletes the characters between the two specified indices.
     *
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param endIndex
     *            the end index, exclusive, must be valid except that if too large it is treated as end of string
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder delete(final int startIndex, int endIndex) {
        endIndex = validateRange(startIndex, endIndex);
        final int len = endIndex - startIndex;
        if (len > 0) {
            deleteImpl(startIndex, endIndex, len);
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Deletes the character wherever it occurs in the builder.
     *
     * @param ch
     *            the character to delete
     * @return this, to enable chaining
     */
    public TextStringBuilder deleteAll(final char ch) {
        for (int i = 0; i < size; i++) {
            if (buffer[i] == ch) {
                final int start = i;
                while (++i < size) {
                    if (buffer[i] != ch) {
                        break;
                    }
                }
                final int len = i - start;
                deleteImpl(start, i, len);
                i -= len;
            }
        }
        return this;
    }

    /**
     * Deletes the character wherever it occurs in the builder.
     *
     * @param ch
     *            the character to delete
     * @return this, to enable chaining
     */
    public TextStringBuilder deleteFirst(final char ch) {
        for (int i = 0; i < size; i++) {
            if (buffer[i] == ch) {
                deleteImpl(i, i + 1, 1);
                break;
            }
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Deletes the string wherever it occurs in the builder.
     *
     * @param str
     *            the string to delete, null causes no action
     * @return this, to enable chaining
     */
    public TextStringBuilder deleteAll(final String str) {
        final int len = str == null ? 0 : str.length();
        if (len > 0) {
            int index = indexOf(str, 0);
            while (index >= 0) {
                deleteImpl(index, index + len, len);
                index = indexOf(str, index);
            }
        }
        return this;
    }

    /**
     * Deletes the string wherever it occurs in the builder.
     *
     * @param str
     *            the string to delete, null causes no action
     * @return this, to enable chaining
     */
    public TextStringBuilder deleteFirst(final String str) {
        final int len = str == null ? 0 : str.length();
        if (len > 0) {
            final int index = indexOf(str, 0);
            if (index >= 0) {
                deleteImpl(index, index + len, len);
            }
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Deletes all parts of the builder that the matcher matches.
     * <p>
     * Matchers can be used to perform advanced deletion behavior. For example you could write a matcher to delete all
     * occurrences where the character 'a' is followed by a number.
     *
     * @param matcher
     *            the matcher to use to find the deletion, null causes no action
     * @return this, to enable chaining
     */
    public TextStringBuilder deleteAll(final StringMatcher matcher) {
        return replace(matcher, null, 0, size, -1);
    }

    /**
     * Deletes the first match within the builder using the specified matcher.
     * <p>
     * Matchers can be used to perform advanced deletion behavior. For example you could write a matcher to delete
     * where the character 'a' is followed by a number.
     *
     * @param matcher
     *            the matcher to use to find the deletion, null causes no action
     * @return this, to enable chaining
     */
    public TextStringBuilder deleteFirst(final StringMatcher matcher) {
        return replace(matcher, null, 0, size, 1);
    }

    // -----------------------------------------------------------------------
    /**
     * Internal method to delete a range without validation.
     *
     * @param startIndex
     *            the start index, must be valid
     * @param endIndex
     *            the end index (exclusive), must be valid
     * @param removeLen
     *            the length to remove (endIndex - startIndex), must be valid
     * @param insertStr
     *            the string to replace with, null means delete range
     * @param insertLen
     *            the length of the insert string, must be valid
     * @throws IndexOutOfBoundsException
     *             if any index is invalid
     */
    private void replaceImpl(final int startIndex, final int endIndex, final int removeLen, final String insertStr,
            final int insertLen) {
        final int newSize = size - removeLen + insertLen;
        if (insertLen != removeLen) {
            ensureCapacity(newSize);
            System.arraycopy(buffer, endIndex, buffer, startIndex + insertLen, size - endIndex);
            size = newSize;
        }
        if (insertLen > 0) {
            insertStr.getChars(0, insertLen, buffer, startIndex);
        }
    }

    /**
     * Replaces a portion of the string builder with another string. The length of the inserted string does not have to
     * match the removed length.
     *
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param endIndex
     *            the end index, exclusive, must be valid except that if too large it is treated as end of string
     * @param replaceStr
     *            the string to replace with, null means delete range
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public TextStringBuilder replace(final int startIndex, int endIndex, final String replaceStr) {
        endIndex = validateRange(startIndex, endIndex);
        final int insertLen = replaceStr == null ? 0 : replaceStr.length();
        replaceImpl(startIndex, endIndex, endIndex - startIndex, replaceStr, insertLen);
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Replaces the search character with the replace character throughout the builder.
     *
     * @param search
     *            the search character
     * @param replace
     *            the replace character
     * @return this, to enable chaining
     */
    public TextStringBuilder replaceAll(final char search, final char replace) {
        if (search != replace) {
            for (int i = 0; i < size; i++) {
                if (buffer[i] == search) {
                    buffer[i] = replace;
                }
            }
        }
        return this;
    }

    /**
     * Replaces the first instance of the search character with the replace character in the builder.
     *
     * @param search
     *            the search character
     * @param replace
     *            the replace character
     * @return this, to enable chaining
     */
    public TextStringBuilder replaceFirst(final char search, final char replace) {
        if (search != replace) {
            for (int i = 0; i < size; i++) {
                if (buffer[i] == search) {
                    buffer[i] = replace;
                    break;
                }
            }
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Replaces the search string with the replace string throughout the builder.
     *
     * @param searchStr
     *            the search string, null causes no action to occur
     * @param replaceStr
     *            the replace string, null is equivalent to an empty string
     * @return this, to enable chaining
     */
    public TextStringBuilder replaceAll(final String searchStr, final String replaceStr) {
        final int searchLen = searchStr == null ? 0 : searchStr.length();
        if (searchLen > 0) {
            final int replaceLen = replaceStr == null ? 0 : replaceStr.length();
            int index = indexOf(searchStr, 0);
            while (index >= 0) {
                replaceImpl(index, index + searchLen, searchLen, replaceStr, replaceLen);
                index = indexOf(searchStr, index + replaceLen);
            }
        }
        return this;
    }

    /**
     * Replaces the first instance of the search string with the replace string.
     *
     * @param searchStr
     *            the search string, null causes no action to occur
     * @param replaceStr
     *            the replace string, null is equivalent to an empty string
     * @return this, to enable chaining
     */
    public TextStringBuilder replaceFirst(final String searchStr, final String replaceStr) {
        final int searchLen = searchStr == null ? 0 : searchStr.length();
        if (searchLen > 0) {
            final int index = indexOf(searchStr, 0);
            if (index >= 0) {
                final int replaceLen = replaceStr == null ? 0 : replaceStr.length();
                replaceImpl(index, index + searchLen, searchLen, replaceStr, replaceLen);
            }
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Replaces all matches within the builder with the replace string.
     * <p>
     * Matchers can be used to perform advanced replace behavior. For example you could write a matcher to replace all
     * occurrences where the character 'a' is followed by a number.
     *
     * @param matcher
     *            the matcher to use to find the deletion, null causes no action
     * @param replaceStr
     *            the replace string, null is equivalent to an empty string
     * @return this, to enable chaining
     */
    public TextStringBuilder replaceAll(final StringMatcher matcher, final String replaceStr) {
        return replace(matcher, replaceStr, 0, size, -1);
    }

    /**
     * Replaces the first match within the builder with the replace string.
     * <p>
     * Matchers can be used to perform advanced replace behavior. For example you could write a matcher to replace
     * where the character 'a' is followed by a number.
     *
     * @param matcher
     *            the matcher to use to find the deletion, null causes no action
     * @param replaceStr
     *            the replace string, null is equivalent to an empty string
     * @return this, to enable chaining
     */
    public TextStringBuilder replaceFirst(final StringMatcher matcher, final String replaceStr) {
        return replace(matcher, replaceStr, 0, size, 1);
    }

    // -----------------------------------------------------------------------
    /**
     * Advanced search and replaces within the builder using a matcher.
     * <p>
     * Matchers can be used to perform advanced behavior. For example you could write a matcher to delete all
     * occurrences where the character 'a' is followed by a number.
     *
     * @param matcher
     *            the matcher to use to find the deletion, null causes no action
     * @param replaceStr
     *            the string to replace the match with, null is a delete
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param endIndex
     *            the end index, exclusive, must be valid except that if too large it is treated as end of string
     * @param replaceCount
     *            the number of times to replace, -1 for replace all
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if start index is invalid
     */
    public TextStringBuilder replace(final StringMatcher matcher, final String replaceStr, final int startIndex,
            int endIndex, final int replaceCount) {
        endIndex = validateRange(startIndex, endIndex);
        return replaceImpl(matcher, replaceStr, startIndex, endIndex, replaceCount);
    }

    /**
     * Replaces within the builder using a matcher.
     * <p>
     * Matchers can be used to perform advanced behavior. For example you could write a matcher to delete all
     * occurrences where the character 'a' is followed by a number.
     *
     * @param matcher
     *            the matcher to use to find the deletion, null causes no action
     * @param replaceStr
     *            the string to replace the match with, null is a delete
     * @param from
     *            the start index, must be valid
     * @param to
     *            the end index (exclusive), must be valid
     * @param replaceCount
     *            the number of times to replace, -1 for replace all
     * @return this, to enable chaining
     * @throws IndexOutOfBoundsException
     *             if any index is invalid
     */
    private TextStringBuilder replaceImpl(final StringMatcher matcher, final String replaceStr, final int from, int to,
            int replaceCount) {
        if (matcher == null || size == 0) {
            return this;
        }
        final int replaceLen = replaceStr == null ? 0 : replaceStr.length();
        for (int i = from; i < to && replaceCount != 0; i++) {
            final char[] buf = buffer;
            final int removeLen = matcher.isMatch(buf, i, from, to);
            if (removeLen > 0) {
                replaceImpl(i, i + removeLen, removeLen, replaceStr, replaceLen);
                to = to - removeLen + replaceLen;
                i = i + replaceLen - 1;
                if (replaceCount > 0) {
                    replaceCount--;
                }
            }
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Reverses the string builder placing each character in the opposite index.
     *
     * @return this, to enable chaining
     */
    public TextStringBuilder reverse() {
        if (size == 0) {
            return this;
        }

        final int half = size / 2;
        final char[] buf = buffer;
        for (int leftIdx = 0, rightIdx = size - 1; leftIdx < half; leftIdx++, rightIdx--) {
            final char swap = buf[leftIdx];
            buf[leftIdx] = buf[rightIdx];
            buf[rightIdx] = swap;
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Trims the builder by removing characters less than or equal to a space from the beginning and end.
     *
     * @return this, to enable chaining
     */
    public TextStringBuilder trim() {
        if (size == 0) {
            return this;
        }
        int len = size;
        final char[] buf = buffer;
        int pos = 0;
        while (pos < len && buf[pos] <= ' ') {
            pos++;
        }
        while (pos < len && buf[len - 1] <= ' ') {
            len--;
        }
        if (len < size) {
            delete(len, size);
        }
        if (pos > 0) {
            delete(0, pos);
        }
        return this;
    }

    // -----------------------------------------------------------------------
    /**
     * Checks whether this builder starts with the specified string.
     * <p>
     * Note that this method handles null input quietly, unlike String.
     *
     * @param str
     *            the string to search for, null returns false
     * @return true if the builder starts with the string
     */
    public boolean startsWith(final String str) {
        if (str == null) {
            return false;
        }
        final int len = str.length();
        if (len == 0) {
            return true;
        }
        if (len > size) {
            return false;
        }
        for (int i = 0; i < len; i++) {
            if (buffer[i] != str.charAt(i)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Checks whether this builder ends with the specified string.
     * <p>
     * Note that this method handles null input quietly, unlike String.
     *
     * @param str
     *            the string to search for, null returns false
     * @return true if the builder ends with the string
     */
    public boolean endsWith(final String str) {
        if (str == null) {
            return false;
        }
        final int len = str.length();
        if (len == 0) {
            return true;
        }
        if (len > size) {
            return false;
        }
        int pos = size - len;
        for (int i = 0; i < len; i++, pos++) {
            if (buffer[pos] != str.charAt(i)) {
                return false;
            }
        }
        return true;
    }

    // -----------------------------------------------------------------------
    /**
     * {@inheritDoc}
     */
    @Override
    public CharSequence subSequence(final int startIndex, final int endIndex) {
        if (startIndex < 0) {
            throw new StringIndexOutOfBoundsException(startIndex);
        }
        if (endIndex > size) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        if (startIndex > endIndex) {
            throw new StringIndexOutOfBoundsException(endIndex - startIndex);
        }
        return substring(startIndex, endIndex);
    }

    /**
     * Extracts a portion of this string builder as a string.
     *
     * @param start
     *            the start index, inclusive, must be valid
     * @return The new string
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public String substring(final int start) {
        return substring(start, size);
    }

    /**
     * Extracts a portion of this string builder as a string.
     * <p>
     * Note: This method treats an endIndex greater than the length of the builder as equal to the length of the
     * builder, and continues without error, unlike StringBuffer or String.
     *
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param endIndex
     *            the end index, exclusive, must be valid except that if too large it is treated as end of string
     * @return The new string
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    public String substring(final int startIndex, int endIndex) {
        endIndex = validateRange(startIndex, endIndex);
        return new String(buffer, startIndex, endIndex - startIndex);
    }

    /**
     * Extracts the leftmost characters from the string builder without throwing an exception.
     * <p>
     * This method extracts the left {@code length} characters from the builder. If this many characters are not
     * available, the whole builder is returned. Thus the returned string may be shorter than the length requested.
     *
     * @param length
     *            the number of characters to extract, negative returns empty string
     * @return The new string
     */
    public String leftString(final int length) {
        if (length <= 0) {
            return "";
        } else if (length >= size) {
            return new String(buffer, 0, size);
        } else {
            return new String(buffer, 0, length);
        }
    }

    /**
     * Extracts the rightmost characters from the string builder without throwing an exception.
     * <p>
     * This method extracts the right {@code length} characters from the builder. If this many characters are not
     * available, the whole builder is returned. Thus the returned string may be shorter than the length requested.
     *
     * @param length
     *            the number of characters to extract, negative returns empty string
     * @return The new string
     */
    public String rightString(final int length) {
        if (length <= 0) {
            return "";
        } else if (length >= size) {
            return new String(buffer, 0, size);
        } else {
            return new String(buffer, size - length, length);
        }
    }

    /**
     * Extracts some characters from the middle of the string builder without throwing an exception.
     * <p>
     * This method extracts {@code length} characters from the builder at the specified index. If the index is
     * negative it is treated as zero. If the index is greater than the builder size, it is treated as the builder size.
     * If the length is negative, the empty string is returned. If insufficient characters are available in the builder,
     * as much as possible is returned. Thus the returned string may be shorter than the length requested.
     *
     * @param index
     *            the index to start at, negative means zero
     * @param length
     *            the number of characters to extract, negative returns empty string
     * @return The new string
     */
    public String midString(int index, final int length) {
        if (index < 0) {
            index = 0;
        }
        if (length <= 0 || index >= size) {
            return "";
        }
        if (size <= index + length) {
            return new String(buffer, index, size - index);
        }
        return new String(buffer, index, length);
    }

    // -----------------------------------------------------------------------
    /**
     * Checks if the string builder contains the specified char.
     *
     * @param ch
     *            the character to find
     * @return true if the builder contains the character
     */
    public boolean contains(final char ch) {
        final char[] thisBuf = buffer;
        for (int i = 0; i < this.size; i++) {
            if (thisBuf[i] == ch) {
                return true;
            }
        }
        return false;
    }

    /**
     * Checks if the string builder contains the specified string.
     *
     * @param str
     *            the string to find
     * @return true if the builder contains the string
     */
    public boolean contains(final String str) {
        return indexOf(str, 0) >= 0;
    }

    /**
     * Checks if the string builder contains a string matched using the specified matcher.
     * <p>
     * Matchers can be used to perform advanced searching behavior. For example you could write a matcher to search for
     * the character 'a' followed by a number.
     *
     * @param matcher
     *            the matcher to use, null returns -1
     * @return true if the matcher finds a match in the builder
     */
    public boolean contains(final StringMatcher matcher) {
        return indexOf(matcher, 0) >= 0;
    }

    // -----------------------------------------------------------------------
    /**
     * Searches the string builder to find the first reference to the specified char.
     *
     * @param ch
     *            the character to find
     * @return The first index of the character, or -1 if not found
     */
    public int indexOf(final char ch) {
        return indexOf(ch, 0);
    }

    /**
     * Searches the string builder to find the first reference to the specified char.
     *
     * @param ch
     *            the character to find
     * @param startIndex
     *            the index to start at, invalid index rounded to edge
     * @return The first index of the character, or -1 if not found
     */
    public int indexOf(final char ch, int startIndex) {
        startIndex = startIndex < 0 ? 0 : startIndex;
        if (startIndex >= size) {
            return -1;
        }
        final char[] thisBuf = buffer;
        for (int i = startIndex; i < size; i++) {
            if (thisBuf[i] == ch) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Searches the string builder to find the first reference to the specified string.
     * <p>
     * Note that a null input string will return -1, whereas the JDK throws an exception.
     *
     * @param str
     *            the string to find, null returns -1
     * @return The first index of the string, or -1 if not found
     */
    public int indexOf(final String str) {
        return indexOf(str, 0);
    }

    /**
     * Searches the string builder to find the first reference to the specified string starting searching from the given
     * index.
     * <p>
     * Note that a null input string will return -1, whereas the JDK throws an exception.
     *
     * @param str
     *            the string to find, null returns -1
     * @param startIndex
     *            the index to start at, invalid index rounded to edge
     * @return The first index of the string, or -1 if not found
     */
    public int indexOf(final String str, int startIndex) {
        startIndex = startIndex < 0 ? 0 : startIndex;
        if (str == null || startIndex >= size) {
            return -1;
        }
        final int strLen = str.length();
        if (strLen == 1) {
            return indexOf(str.charAt(0), startIndex);
        }
        if (strLen == 0) {
            return startIndex;
        }
        if (strLen > size) {
            return -1;
        }
        final char[] thisBuf = buffer;
        final int len = size - strLen + 1;
        outer: for (int i = startIndex; i < len; i++) {
            for (int j = 0; j < strLen; j++) {
                if (str.charAt(j) != thisBuf[i + j]) {
                    continue outer;
                }
            }
            return i;
        }
        return -1;
    }

    /**
     * Searches the string builder using the matcher to find the first match.
     * <p>
     * Matchers can be used to perform advanced searching behavior. For example you could write a matcher to find the
     * character 'a' followed by a number.
     *
     * @param matcher
     *            the matcher to use, null returns -1
     * @return The first index matched, or -1 if not found
     */
    public int indexOf(final StringMatcher matcher) {
        return indexOf(matcher, 0);
    }

    /**
     * Searches the string builder using the matcher to find the first match searching from the given index.
     * <p>
     * Matchers can be used to perform advanced searching behavior. For example you could write a matcher to find the
     * character 'a' followed by a number.
     *
     * @param matcher
     *            the matcher to use, null returns -1
     * @param startIndex
     *            the index to start at, invalid index rounded to edge
     * @return The first index matched, or -1 if not found
     */
    public int indexOf(final StringMatcher matcher, int startIndex) {
        startIndex = startIndex < 0 ? 0 : startIndex;
        if (matcher == null || startIndex >= size) {
            return -1;
        }
        final int len = size;
        final char[] buf = buffer;
        for (int i = startIndex; i < len; i++) {
            if (matcher.isMatch(buf, i, startIndex, len) > 0) {
                return i;
            }
        }
        return -1;
    }

    // -----------------------------------------------------------------------
    /**
     * Searches the string builder to find the last reference to the specified char.
     *
     * @param ch
     *            the character to find
     * @return The last index of the character, or -1 if not found
     */
    public int lastIndexOf(final char ch) {
        return lastIndexOf(ch, size - 1);
    }

    /**
     * Searches the string builder to find the last reference to the specified char.
     *
     * @param ch
     *            the character to find
     * @param startIndex
     *            the index to start at, invalid index rounded to edge
     * @return The last index of the character, or -1 if not found
     */
    public int lastIndexOf(final char ch, int startIndex) {
        startIndex = startIndex >= size ? size - 1 : startIndex;
        if (startIndex < 0) {
            return -1;
        }
        for (int i = startIndex; i >= 0; i--) {
            if (buffer[i] == ch) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Searches the string builder to find the last reference to the specified string.
     * <p>
     * Note that a null input string will return -1, whereas the JDK throws an exception.
     *
     * @param str
     *            the string to find, null returns -1
     * @return The last index of the string, or -1 if not found
     */
    public int lastIndexOf(final String str) {
        return lastIndexOf(str, size - 1);
    }

    /**
     * Searches the string builder to find the last reference to the specified string starting searching from the given
     * index.
     * <p>
     * Note that a null input string will return -1, whereas the JDK throws an exception.
     *
     * @param str
     *            the string to find, null returns -1
     * @param startIndex
     *            the index to start at, invalid index rounded to edge
     * @return The last index of the string, or -1 if not found
     */
    public int lastIndexOf(final String str, int startIndex) {
        startIndex = startIndex >= size ? size - 1 : startIndex;
        if (str == null || startIndex < 0) {
            return -1;
        }
        final int strLen = str.length();
        if (strLen > 0 && strLen <= size) {
            if (strLen == 1) {
                return lastIndexOf(str.charAt(0), startIndex);
            }

            outer: for (int i = startIndex - strLen + 1; i >= 0; i--) {
                for (int j = 0; j < strLen; j++) {
                    if (str.charAt(j) != buffer[i + j]) {
                        continue outer;
                    }
                }
                return i;
            }

        } else if (strLen == 0) {
            return startIndex;
        }
        return -1;
    }

    /**
     * Searches the string builder using the matcher to find the last match.
     * <p>
     * Matchers can be used to perform advanced searching behavior. For example you could write a matcher to find the
     * character 'a' followed by a number.
     *
     * @param matcher
     *            the matcher to use, null returns -1
     * @return The last index matched, or -1 if not found
     */
    public int lastIndexOf(final StringMatcher matcher) {
        return lastIndexOf(matcher, size);
    }

    /**
     * Searches the string builder using the matcher to find the last match searching from the given index.
     * <p>
     * Matchers can be used to perform advanced searching behavior. For example you could write a matcher to find the
     * character 'a' followed by a number.
     *
     * @param matcher
     *            the matcher to use, null returns -1
     * @param startIndex
     *            the index to start at, invalid index rounded to edge
     * @return The last index matched, or -1 if not found
     */
    public int lastIndexOf(final StringMatcher matcher, int startIndex) {
        startIndex = startIndex >= size ? size - 1 : startIndex;
        if (matcher == null || startIndex < 0) {
            return -1;
        }
        final char[] buf = buffer;
        final int endIndex = startIndex + 1;
        for (int i = startIndex; i >= 0; i--) {
            if (matcher.isMatch(buf, i, 0, endIndex) > 0) {
                return i;
            }
        }
        return -1;
    }

    // -----------------------------------------------------------------------
    /**
     * Creates a tokenizer that can tokenize the contents of this builder.
     * <p>
     * This method allows the contents of this builder to be tokenized. The tokenizer will be setup by default to
     * tokenize on space, tab, newline and form feed (as per StringTokenizer). These values can be changed on the
     * tokenizer class, before retrieving the tokens.
     * <p>
     * The returned tokenizer is linked to this builder. You may intermix calls to the builder and tokenizer within
     * certain limits, however there is no synchronization. Once the tokenizer has been used once, it must be
     * {@link StringTokenizer#reset() reset} to pickup the latest changes in the builder. For example:
     *
     * <pre>
     * StrBuilder b = new StrBuilder();
     * b.append("a b ");
     * StrTokenizer t = b.asTokenizer();
     * String[] tokens1 = t.getTokenArray(); // returns a,b
     * b.append("c d ");
     * String[] tokens2 = t.getTokenArray(); // returns a,b (c and d ignored)
     * t.reset(); // reset causes builder changes to be picked up
     * String[] tokens3 = t.getTokenArray(); // returns a,b,c,d
     * </pre>
     *
     * In addition to simply intermixing appends and tokenization, you can also call the set methods on the tokenizer to
     * alter how it tokenizes. Just remember to call reset when you want to pickup builder changes.
     * <p>
     * Calling {@link StringTokenizer#reset(String)} or {@link StringTokenizer#reset(char[])} with a non-null value will
     * break the link with the builder.
     *
     * @return a tokenizer that is linked to this builder
     */
    public StringTokenizer asTokenizer() {
        return new TextStringBuilderTokenizer();
    }

    // -----------------------------------------------------------------------
    /**
     * Gets the contents of this builder as a Reader.
     * <p>
     * This method allows the contents of the builder to be read using any standard method that expects a Reader.
     * <p>
     * To use, simply create a {@code StrBuilder}, populate it with data, call {@code asReader}, and then read
     * away.
     * <p>
     * The internal character array is shared between the builder and the reader. This allows you to append to the
     * builder after creating the reader, and the changes will be picked up. Note however, that no synchronization
     * occurs, so you must perform all operations with the builder and the reader in one thread.
     * <p>
     * The returned reader supports marking, and ignores the flush method.
     *
     * @return a reader that reads from this builder
     */
    public Reader asReader() {
        return new StrBuilderReader();
    }

    // -----------------------------------------------------------------------
    /**
     * Gets this builder as a Writer that can be written to.
     * <p>
     * This method allows you to populate the contents of the builder using any standard method that takes a Writer.
     * <p>
     * To use, simply create a {@code StrBuilder}, call {@code asWriter}, and populate away. The data is
     * available at any time using the methods of the {@code StrBuilder}.
     * <p>
     * The internal character array is shared between the builder and the writer. This allows you to intermix calls that
     * append to the builder and write using the writer and the changes will be occur correctly. Note however, that no
     * synchronization occurs, so you must perform all operations with the builder and the writer in one thread.
     * <p>
     * The returned writer ignores the close and flush methods.
     *
     * @return a writer that populates this builder
     */
    public Writer asWriter() {
        return new StrBuilderWriter();
    }

    /**
     * Appends current contents of this {@code StrBuilder} to the provided {@link Appendable}.
     * <p>
     * This method tries to avoid doing any extra copies of contents.
     *
     * @param appendable
     *            the appendable to append data to
     * @throws IOException
     *             if an I/O error occurs
     *
     * @see #readFrom(Readable)
     */
    public void appendTo(final Appendable appendable) throws IOException {
        if (appendable instanceof Writer) {
            ((Writer) appendable).write(buffer, 0, size);
        } else if (appendable instanceof StringBuilder) {
            ((StringBuilder) appendable).append(buffer, 0, size);
        } else if (appendable instanceof StringBuffer) {
            ((StringBuffer) appendable).append(buffer, 0, size);
        } else if (appendable instanceof CharBuffer) {
            ((CharBuffer) appendable).put(buffer, 0, size);
        } else {
            appendable.append(this);
        }
    }

    /**
     * Checks the contents of this builder against another to see if they contain the same character content ignoring
     * case.
     *
     * @param other
     *            the object to check, null returns false
     * @return true if the builders contain the same characters in the same order
     */
    public boolean equalsIgnoreCase(final TextStringBuilder other) {
        if (this == other) {
            return true;
        }
        if (this.size != other.size) {
            return false;
        }
        final char[] thisBuf = this.buffer;
        final char[] otherBuf = other.buffer;
        for (int i = size - 1; i >= 0; i--) {
            final char c1 = thisBuf[i];
            final char c2 = otherBuf[i];
            if (c1 != c2 && Character.toUpperCase(c1) != Character.toUpperCase(c2)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Checks the contents of this builder against another to see if they contain the same character content.
     *
     * @param other
     *            the object to check, null returns false
     * @return true if the builders contain the same characters in the same order
     */
    public boolean equals(final TextStringBuilder other) {
        if (this == other) {
            return true;
        }
        if (other == null) {
            return false;
        }
        if (this.size != other.size) {
            return false;
        }
        final char[] thisBuf = this.buffer;
        final char[] otherBuf = other.buffer;
        for (int i = size - 1; i >= 0; i--) {
            if (thisBuf[i] != otherBuf[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * Checks the contents of this builder against another to see if they contain the same character content.
     *
     * @param obj
     *            the object to check, null returns false
     * @return true if the builders contain the same characters in the same order
     */
    @Override
    public boolean equals(final Object obj) {
        return obj instanceof TextStringBuilder && equals((TextStringBuilder) obj);
    }

    /**
     * Gets a suitable hash code for this builder.
     *
     * @return a hash code
     */
    @Override
    public int hashCode() {
        final char[] buf = buffer;
        int hash = 0;
        for (int i = size - 1; i >= 0; i--) {
            hash = 31 * hash + buf[i];
        }
        return hash;
    }

    // -----------------------------------------------------------------------
    /**
     * Gets a String version of the string builder, creating a new instance each time the method is called.
     * <p>
     * Note that unlike StringBuffer, the string version returned is independent of the string builder.
     *
     * @return The builder as a String
     */
    @Override
    public String toString() {
        return new String(buffer, 0, size);
    }

    /**
     * Gets a StringBuffer version of the string builder, creating a new instance each time the method is called.
     *
     * @return The builder as a StringBuffer
     */
    public StringBuffer toStringBuffer() {
        return new StringBuffer(size).append(buffer, 0, size);
    }

    /**
     * Gets a StringBuilder version of the string builder, creating a new instance each time the method is called.
     *
     * @return The builder as a StringBuilder
     */
    public StringBuilder toStringBuilder() {
        return new StringBuilder(size).append(buffer, 0, size);
    }

    /**
     * Implement the {@link Builder} interface.
     *
     * @return The builder as a String
     * @see #toString()
     */
    @Override
    public String build() {
        return toString();
    }

    // -----------------------------------------------------------------------
    /**
     * Validates parameters defining a range of the builder.
     *
     * @param startIndex
     *            the start index, inclusive, must be valid
     * @param endIndex
     *            the end index, exclusive, must be valid except that if too large it is treated as end of string
     * @return The new string
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    protected int validateRange(final int startIndex, int endIndex) {
        if (startIndex < 0) {
            throw new StringIndexOutOfBoundsException(startIndex);
        }
        if (endIndex > size) {
            endIndex = size;
        }
        if (startIndex > endIndex) {
            throw new StringIndexOutOfBoundsException("end < start");
        }
        return endIndex;
    }

    /**
     * Validates parameters defining a single index in the builder.
     *
     * @param index
     *            the index, must be valid
     * @throws IndexOutOfBoundsException
     *             if the index is invalid
     */
    protected void validateIndex(final int index) {
        if (index < 0 || index > size) {
            throw new StringIndexOutOfBoundsException(index);
        }
    }

    // -----------------------------------------------------------------------
    /**
     * Inner class to allow StrBuilder to operate as a tokenizer.
     */
    class TextStringBuilderTokenizer extends StringTokenizer {

        /**
         * Default constructor.
         */
        TextStringBuilderTokenizer() {
            super();
        }

        /** {@inheritDoc} */
        @Override
        protected List<String> tokenize(final char[] chars, final int offset, final int count) {
            if (chars == null) {
                return super.tokenize(TextStringBuilder.this.buffer, 0, TextStringBuilder.this.size());
            }
            return super.tokenize(chars, offset, count);
        }

        /** {@inheritDoc} */
        @Override
        public String getContent() {
            final String str = super.getContent();
            if (str == null) {
                return TextStringBuilder.this.toString();
            }
            return str;
        }
    }

    // -----------------------------------------------------------------------
    /**
     * Inner class to allow StrBuilder to operate as a reader.
     */
    class StrBuilderReader extends Reader {
        /** The current stream position. */
        private int pos;
        /** The last mark position. */
        private int mark;

        /**
         * Default constructor.
         */
        StrBuilderReader() {
            super();
        }

        /** {@inheritDoc} */
        @Override
        public void close() {
            // do nothing
        }

        /** {@inheritDoc} */
        @Override
        public int read() {
            if (!ready()) {
                return -1;
            }
            return TextStringBuilder.this.charAt(pos++);
        }

        /** {@inheritDoc} */
        @Override
        public int read(final char[] b, final int off, int len) {
            if (off < 0 || len < 0 || off > b.length || off + len > b.length || off + len < 0) {
                throw new IndexOutOfBoundsException();
            }
            if (len == 0) {
                return 0;
            }
            if (pos >= TextStringBuilder.this.size()) {
                return -1;
            }
            if (pos + len > size()) {
                len = TextStringBuilder.this.size() - pos;
            }
            TextStringBuilder.this.getChars(pos, pos + len, b, off);
            pos += len;
            return len;
        }

        /** {@inheritDoc} */
        @Override
        public long skip(long n) {
            if (pos + n > TextStringBuilder.this.size()) {
                n = TextStringBuilder.this.size() - pos;
            }
            if (n < 0) {
                return 0;
            }
            pos += n;
            return n;
        }

        /** {@inheritDoc} */
        @Override
        public boolean ready() {
            return pos < TextStringBuilder.this.size();
        }

        /** {@inheritDoc} */
        @Override
        public boolean markSupported() {
            return true;
        }

        /** {@inheritDoc} */
        @Override
        public void mark(final int readAheadLimit) {
            mark = pos;
        }

        /** {@inheritDoc} */
        @Override
        public void reset() {
            pos = mark;
        }
    }

    // -----------------------------------------------------------------------
    /**
     * Inner class to allow StrBuilder to operate as a writer.
     */
    class StrBuilderWriter extends Writer {

        /**
         * Default constructor.
         */
        StrBuilderWriter() {
            super();
        }

        /** {@inheritDoc} */
        @Override
        public void close() {
            // do nothing
        }

        /** {@inheritDoc} */
        @Override
        public void flush() {
            // do nothing
        }

        /** {@inheritDoc} */
        @Override
        public void write(final int c) {
            TextStringBuilder.this.append((char) c);
        }

        /** {@inheritDoc} */
        @Override
        public void write(final char[] cbuf) {
            TextStringBuilder.this.append(cbuf);
        }

        /** {@inheritDoc} */
        @Override
        public void write(final char[] cbuf, final int off, final int len) {
            TextStringBuilder.this.append(cbuf, off, len);
        }

        /** {@inheritDoc} */
        @Override
        public void write(final String str) {
            TextStringBuilder.this.append(str);
        }

        /** {@inheritDoc} */
        @Override
        public void write(final String str, final int off, final int len) {
            TextStringBuilder.this.append(str, off, len);
        }
    }

}
