package org.jlib.core.text;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * Iterator over the {@link Character Characters} of a {@link StringBuilder}.
 * 
 * @author Igor Akkerman
 */
public class StringBuilderIterator
extends CharSequenceIterator {

    /**
     * Returns an {@link Iterable} creating StringBuilderIterators over the
     * {@link Character Characters} of a {@link StringBuilder}.
     * 
     * @param iterableStringBuilder
     *        {@link StringBuilder} to iterate
     * @return {@link Iterable} creating StringBuilderIterators over the
     *         {@link Character Characters} of {@code iterableStringBuilder}
     */
    public static Iterable<Character> iterable(final StringBuilder iterableStringBuilder) {
        return new Iterable<Character>() {

            @Override
            public Iterator<Character> iterator() {
                return new StringBuilderIterator(iterableStringBuilder);
            }
        };
    }

    /**
     * Returns an {@link Iterable} creating StringBuilderIterators over the
     * {@link Character Characters} of the subsequence specified by the index of
     * its first character (inclusive) contained by the specified
     * {@link StringBuilder}.
     * 
     * @param iterableStringBuilder
     *        {@link StringBuilder} to iterate
     * @param firstCharacterIndex
     *        integer specifying the index of the first character of the
     *        subsequence
     * @return {@link Iterable} creating StringBuilderIterators over the
     *         {@link Character Characters} of the subsequence
     * @throws CharSequenceBeginIndexNegativeException
     *         if {@code firstCharacterIndex < 0}
     * @throws CharSequenceBeginIndexAboveBoundException
     *         if {@code firstCharacterIndex >= iteratedStringBuilder.length()}
     */
    public static Iterable<Character> iterable(final StringBuilder iterableStringBuilder, final int firstCharacterIndex)
    throws CharSequenceBeginIndexNegativeException, CharSequenceBeginIndexAboveBoundException {
        return new Iterable<Character>() {

            @Override
            public Iterator<Character> iterator() {
                return new StringBuilderIterator(iterableStringBuilder, firstCharacterIndex);
            }
        };
    }

    /**
     * Returns an {@link Iterable} creating StringBuilderIterators over the
     * {@link Character Characters} of the subsequence specified by the indices
     * of its first and last characters (inclusive) contained by the specified
     * {@link StringBuilder}.
     * 
     * @param iterableStringBuilder
     *        {@link StringBuilder} to iterate
     * @param firstCharacterIndex
     *        integer specifying the index of the first character of the
     *        subsequence
     * @param lastCharacterIndex
     *        integer specifying the index of the last character of the
     *        subsequence
     * @return {@link Iterable} creating StringBuilderIterators over the
     *         {@link Character Characters} of the subsequence
     * @throws CharSequenceBeginIndexNegativeException
     *         if {@code firstCharacterIndex < 0}
     * @throws CharSequenceEndIndexBelowStartIndexException
     *         if {@code lastCharacterIndex < firstCharacterIndex}
     * @throws CharSequenceEndIndexAboveBoundException
     *         if {@code lastCharacterIndex >= iteratedStringBuilder.length()}
     */
    public static Iterable<Character> iterable(final StringBuilder iterableStringBuilder, final int firstCharacterIndex,
                                               final int lastCharacterIndex)
    throws CharSequenceBeginIndexNegativeException, CharSequenceEndIndexBelowStartIndexException,
    CharSequenceEndIndexAboveBoundException {
        return new Iterable<Character>() {

            @Override
            public Iterator<Character> iterator() {
                return new StringBuilderIterator(iterableStringBuilder, firstCharacterIndex, lastCharacterIndex);
            }
        };
    }

    /** {@link StringBuilder} iterated by this StringBuilderIterator */
    private final StringBuilder iteratedStringBuilder;

    /**
     * Creates a new StringBuilderIterator over the {@link Character Characters}
     * of the specified {@link StringBuilder}.
     * 
     * @param iteratedStringBuilder
     *        {@link StringBuilder} to iterate
     */
    public StringBuilderIterator(StringBuilder iteratedStringBuilder) {
        super(iteratedStringBuilder);
        this.iteratedStringBuilder = iteratedStringBuilder;
    }

    /**
     * Creates a new StringBuilderIterator over the {@link Character Characters}
     * of the subsequence specified by the index of its first character
     * (inclusive) contained by the specified {@link StringBuilder}.
     * 
     * @param iteratedStringBuilder
     *        {@link StringBuilder} to iterate
     * @param firstCharacterIndex
     *        integer specifying the index of the first character of the
     *        subsequence
     * @throws CharSequenceBeginIndexNegativeException
     *         if {@code firstCharacterIndex < 0}
     * @throws CharSequenceBeginIndexAboveBoundException
     *         if {@code firstCharacterIndex >= iteratedStringBuilder.length()}
     */
    public StringBuilderIterator(StringBuilder iteratedStringBuilder, int firstCharacterIndex) {
        super(iteratedStringBuilder, firstCharacterIndex);
        this.iteratedStringBuilder = iteratedStringBuilder;
    }

    /**
     * Creates a new StringBuilderIterator over the {@link Character Characters}
     * of the subsequence specified by the indices of its first and last
     * characters (inclusive) contained by the specified {@link StringBuilder}.
     * 
     * @param iteratedStringBuilder
     *        {@link StringBuilder} to iterate
     * @param firstCharacterIndex
     *        integer specifying the index of the first character of the
     *        subsequence
     * @param lastCharacterIndex
     *        integer specifying the index of the last character of the
     *        subsequence
     * @throws CharSequenceBeginIndexNegativeException
     *         if {@code firstCharacterIndex < 0}
     * @throws CharSequenceEndIndexBelowStartIndexException
     *         if {@code lastCharacterIndex < firstCharacterIndex}
     * @throws CharSequenceEndIndexAboveBoundException
     *         if {@code lastCharacterIndex >= iteratedStringBuilder.length()}
     */
    public StringBuilderIterator(StringBuilder iteratedStringBuilder, int firstCharacterIndex, int lastCharacterIndex)
    throws CharSequenceBeginIndexNegativeException, CharSequenceEndIndexBelowStartIndexException,
    CharSequenceEndIndexAboveBoundException {
        super(iteratedStringBuilder, firstCharacterIndex, lastCharacterIndex);
        this.iteratedStringBuilder = iteratedStringBuilder;
    }

    /**
     * Deletes the last {@link Character} returned by this StringBuilderIterator
     * from the {@link StringBuilder}.
     */
    @Override
    public void remove() {
        if (nextCharacterIndex >= iteratedStringBuilder.length())
            throw new NoSuchElementException("['" + iteratedStringBuilder + "', " + nextCharacterIndex + "]");
        iteratedStringBuilder.deleteCharAt(nextCharacterIndex - 1);
        lastCharacterIndex --;
    }
}

@@ -55,50 +55,8 @@
 or;%0D
-%0Aimport java.util.NoSuchElementException;%0D
 %0A%0D%0A/
@@ -4244,16 +4244,131 @@
 uilder;%0D
+%0A    %0D%0A    /** last %7B@link Character%7D returned by %7B@link #next()%7D */%0D%0A    private Character lastReturnedCharacter;%0D
 %0A%0D%0A    /
@@ -7149,363 +7149,553 @@
    /
-**%0D%0A     * Deletes the last %7B@link Character%7D returned by this StringBuilderIterator%0D%0A     * from the %7B@link StringBuilder%7D.%0D%0A     */%0D%0A    @Override%0D%0A    public void remove() %7B%0D%0A        if (nextCharacterIndex %3E= iteratedStringBuilder.length())%0D%0A            throw new NoSuchElementException(%22%5B'%22 + iteratedStringBuilder + %22', %22 + nextCharacterIndex + %22%5D%22);
+/ @see org.jlib.core.text.CharSequenceIterator#next()%0D%0A    @Override%0D%0A    public Character next() %7B%0D%0A        lastReturnedCharacter = super.next();%0D%0A        return lastReturnedCharacter;%0D%0A    %7D%0D%0A    %0D%0A    /**%0D%0A     * Deletes the last %7B@link Character%7D returned by this StringBuilderIterator%0D%0A     * from the %7B@link StringBuilder%7D.%0D%0A     * %0D%0A     * @throws IllegalStateException%0D%0A     *         if no %0D%0A     */%0D%0A    @Override%0D%0A    public void remove() %7B%0D%0A        if (lastReturnedCharacter == null)%0D%0A            throw new IllegalStateException();%0D%0A
 %0D%0A  

delete method optimized