You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2010/03/17 01:34:38 UTC

svn commit: r924074 [3/6] - in /wicket/trunk: testing/wicket-threadtest/src/main/java/org/apache/wicket/threadtest/ wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/repeater/data/table/filter/ wicket-guice/src/test/java/org/apac...

Added: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/AppendingStringBuffer.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/AppendingStringBuffer.java?rev=924074&view=auto
==============================================================================
--- wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/AppendingStringBuffer.java (added)
+++ wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/AppendingStringBuffer.java Wed Mar 17 00:34:34 2010
@@ -0,0 +1,1735 @@
+/*
+ * 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.wicket.util.string;
+
+import java.io.IOException;
+
+/**
+ * This is a copy or combination of <code>java.lang.StringBuffer</code> and
+ * <code>java.lang.String</code> It has a special method getValue() which returns the internal char
+ * array.
+ * 
+ * Hashcode and equals methods are also implemented.
+ * 
+ * This AppendingStringBuffer is not synchronized.
+ * 
+ * @author Johan Compagner
+ * @see java.lang.StringBuffer
+ */
+
+public final class AppendingStringBuffer implements java.io.Serializable, CharSequence
+{
+	/** use serialVersionUID from JDK 1.0.2 for interoperability */
+	static final long serialVersionUID = 1L;
+
+	private static final AppendingStringBuffer NULL = new AppendingStringBuffer("null");
+	private static final StringBuffer SB_NULL = new StringBuffer("null");
+
+	/**
+	 * The value is used for character storage.
+	 * 
+	 * @serial
+	 */
+	private char value[];
+
+	/**
+	 * The count is the number of characters in the buffer.
+	 * 
+	 * @serial
+	 */
+	private int count;
+
+	/**
+	 * Constructs a string buffer with no characters in it and an initial capacity of 16 characters.
+	 */
+	public AppendingStringBuffer()
+	{
+		this(16);
+	}
+
+	/**
+	 * Constructs a string buffer with no characters in it and an initial capacity specified by the
+	 * <code>length</code> argument.
+	 * 
+	 * @param length
+	 *            the initial capacity.
+	 * @exception NegativeArraySizeException
+	 *                if the <code>length</code> argument is less than <code>0</code>.
+	 */
+	public AppendingStringBuffer(int length)
+	{
+		value = new char[length];
+	}
+
+	/**
+	 * Constructs a string buffer so that it represents the same sequence of characters as the
+	 * string argument; in other words, the initial contents of the string buffer is a copy of the
+	 * argument string. The initial capacity of the string buffer is <code>16</code> plus the length
+	 * of the string argument.
+	 * 
+	 * @param str
+	 *            the initial contents of the buffer.
+	 * @exception NullPointerException
+	 *                if <code>str</code> is <code>null</code>
+	 */
+	public AppendingStringBuffer(CharSequence str)
+	{
+		this(str.length() + 16);
+		append(str);
+	}
+
+	/**
+	 * Returns the length (character count) of this string buffer.
+	 * 
+	 * @return the length of the sequence of characters currently represented by this string buffer.
+	 */
+	public int length()
+	{
+		return count;
+	}
+
+	/**
+	 * Returns the current capacity of the String buffer. The capacity is the amount of storage
+	 * available for newly inserted characters; beyond which an allocation will occur.
+	 * 
+	 * @return the current capacity of this string buffer.
+	 */
+	public int capacity()
+	{
+		return value.length;
+	}
+
+	/**
+	 * Ensures that the capacity of the buffer is at least equal to the specified minimum. If the
+	 * current capacity of this string buffer is less than the argument, then a new internal buffer
+	 * is allocated with greater capacity. The new capacity is the larger of:
+	 * <ul>
+	 * <li>The <code>minimumCapacity</code> argument.
+	 * <li>Twice the old capacity, plus <code>2</code>.
+	 * </ul>
+	 * If the <code>minimumCapacity</code> argument is nonpositive, this method takes no action and
+	 * simply returns.
+	 * 
+	 * @param minimumCapacity
+	 *            the minimum desired capacity.
+	 */
+	public void ensureCapacity(int minimumCapacity)
+	{
+		if (minimumCapacity > value.length)
+		{
+			expandCapacity(minimumCapacity);
+		}
+	}
+
+	/**
+	 * This implements the expansion semantics of ensureCapacity but is unsynchronized for use
+	 * internally by methods which are already synchronized.
+	 * 
+	 * @param minimumCapacity
+	 * 
+	 * @see java.lang.StringBuffer#ensureCapacity(int)
+	 */
+	private void expandCapacity(int minimumCapacity)
+	{
+		int newCapacity = (value.length + 1) * 2;
+		if (newCapacity < 0)
+		{
+			newCapacity = Integer.MAX_VALUE;
+		}
+		else if (minimumCapacity > newCapacity)
+		{
+			newCapacity = minimumCapacity;
+		}
+
+		char newValue[] = new char[newCapacity];
+		System.arraycopy(value, 0, newValue, 0, count);
+		value = newValue;
+	}
+
+	/**
+	 * Sets the length of this String buffer. This string buffer is altered to represent a new
+	 * character sequence whose length is specified by the argument. For every nonnegative index
+	 * <i>k</i> less than <code>newLength</code>, the character at index <i>k</i> in the new
+	 * character sequence is the same as the character at index <i>k</i> in the old sequence if
+	 * <i>k</i> is less than the length of the old character sequence; otherwise, it is the null
+	 * character <code>'&#92;u0000'</code>.
+	 * 
+	 * In other words, if the <code>newLength</code> argument is less than the current length of the
+	 * string buffer, the string buffer is truncated to contain exactly the number of characters
+	 * given by the <code>newLength</code> argument.
+	 * <p>
+	 * If the <code>newLength</code> argument is greater than or equal to the current length,
+	 * sufficient null characters (<code>'&#92;u0000'</code>) are appended to the string buffer so that length becomes
+	 * the <code>newLength</code> argument.
+	 * <p>
+	 * The <code>newLength</code> argument must be greater than or equal to <code>0</code>.
+	 * 
+	 * @param newLength
+	 *            the new length of the buffer.
+	 * @exception IndexOutOfBoundsException
+	 *                if the <code>newLength</code> argument is negative.
+	 * @see java.lang.StringBuffer#length()
+	 */
+	public void setLength(int newLength)
+	{
+		if (newLength < 0)
+		{
+			throw new StringIndexOutOfBoundsException(newLength);
+		}
+
+		if (newLength > value.length)
+		{
+			expandCapacity(newLength);
+		}
+
+		if (count < newLength)
+		{
+			for (; count < newLength; count++)
+			{
+				value[count] = '\0';
+			}
+		}
+		else
+		{
+			count = newLength;
+		}
+	}
+
+	/**
+	 * The specified character of the sequence currently represented by the string buffer, as
+	 * indicated by the <code>index</code> argument, is returned. The first character of a string
+	 * buffer is at index <code>0</code>, the next at index <code>1</code>, and so on, for array
+	 * indexing.
+	 * <p>
+	 * The index argument must be greater than or equal to <code>0</code>, and less than the length
+	 * of this string buffer.
+	 * 
+	 * @param index
+	 *            the index of the desired character.
+	 * @return the character at the specified index of this string buffer.
+	 * @exception IndexOutOfBoundsException
+	 *                if <code>index</code> is negative or greater than or equal to
+	 *                <code>length()</code>.
+	 * @see java.lang.StringBuffer#length()
+	 */
+	public char charAt(int index)
+	{
+		if ((index < 0) || (index >= count))
+		{
+			throw new StringIndexOutOfBoundsException(index);
+		}
+		return value[index];
+	}
+
+	/**
+	 * Characters are copied from this string buffer into the destination character array
+	 * <code>dst</code>. The first character to be copied is at index <code>srcBegin</code>; the
+	 * last character to be copied is at index <code>srcEnd-1</code>. The total number of characters
+	 * to be copied is <code>srcEnd-srcBegin</code>. The characters are copied into the subarray of
+	 * <code>dst</code> starting at index <code>dstBegin</code> and ending at index:
+	 * <p>
+	 * <blockquote>
+	 * 
+	 * <pre>
+	 * dstbegin + (srcEnd - srcBegin) - 1
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * 
+	 * @param srcBegin
+	 *            start copying at this offset in the string buffer.
+	 * @param srcEnd
+	 *            stop copying at this offset in the string buffer.
+	 * @param dst
+	 *            the array to copy the data into.
+	 * @param dstBegin
+	 *            offset into <code>dst</code>.
+	 * @exception NullPointerException
+	 *                if <code>dst</code> is <code>null</code>.
+	 * @exception IndexOutOfBoundsException
+	 *                if any of the following is true:
+	 *                <ul>
+	 *                <li><code>srcBegin</code> is negative <li><code>dstBegin</code> is negative
+	 *                <li>the <code>srcBegin</code> argument is greater than the <code>srcEnd</code>
+	 *                argument. <li><code>srcEnd</code> is greater than <code>this.length()</code>,
+	 *                the current length of this string buffer. <li><code>dstBegin+srcEnd-srcBegin
+	 *                </code> is greater than <code>dst.length</code>
+	 *                </ul>
+	 */
+	public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
+	{
+		if (srcBegin < 0)
+		{
+			throw new StringIndexOutOfBoundsException(srcBegin);
+		}
+		if ((srcEnd < 0) || (srcEnd > count))
+		{
+			throw new StringIndexOutOfBoundsException(srcEnd);
+		}
+		if (srcBegin > srcEnd)
+		{
+			throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
+		}
+		System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
+	}
+
+	/**
+	 * The character at the specified index of this string buffer is set to <code>ch</code>. The
+	 * string buffer is altered to represent a new character sequence that is identical to the old
+	 * character sequence, except that it contains the character <code>ch</code> at position
+	 * <code>index</code>.
+	 * <p>
+	 * The index argument must be greater than or equal to <code>0</code>, and less than the length
+	 * of this string buffer.
+	 * 
+	 * @param index
+	 *            the index of the character to modify.
+	 * @param ch
+	 *            the new character.
+	 * @exception IndexOutOfBoundsException
+	 *                if <code>index</code> is negative or greater than or equal to
+	 *                <code>length()</code>.
+	 * @see java.lang.StringBuffer#length()
+	 */
+	public void setCharAt(int index, char ch)
+	{
+		if ((index < 0) || (index >= count))
+		{
+			throw new StringIndexOutOfBoundsException(index);
+		}
+		value[index] = ch;
+	}
+
+	/**
+	 * Appends the string representation of the <code>Object</code> argument to this string buffer.
+	 * <p>
+	 * The argument is converted to a string as if by the method <code>String.valueOf</code>, and
+	 * the characters of that string are then appended to this string buffer.
+	 * 
+	 * @param obj
+	 *            an <code>Object</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @see java.lang.String#valueOf(java.lang.Object)
+	 * @see java.lang.StringBuffer#append(java.lang.String)
+	 */
+	public AppendingStringBuffer append(Object obj)
+	{
+		if (obj instanceof AppendingStringBuffer)
+		{
+			return append((AppendingStringBuffer)obj);
+		}
+		else if (obj instanceof StringBuffer)
+		{
+			return append((StringBuffer)obj);
+		}
+		return append(String.valueOf(obj));
+	}
+
+	/**
+	 * Appends the string to this string buffer.
+	 * <p>
+	 * The characters of the <code>String</code> argument are appended, in order, to the contents of
+	 * this string buffer, increasing the length of this string buffer by the length of the
+	 * argument. If <code>str</code> is <code>null</code>, then the four characters
+	 * <code>"null"</code> are appended to this string buffer.
+	 * <p>
+	 * Let <i>n</i> be the length of the old character sequence, the one contained in the string
+	 * buffer just prior to execution of the <code>append</code> method. Then the character at index
+	 * <i>k</i> in the new character sequence is equal to the character at index <i>k</i> in the old
+	 * character sequence, if <i>k</i> is less than <i>n</i>; otherwise, it is equal to the
+	 * character at index <i>k-n</i> in the argument <code>str</code>.
+	 * 
+	 * @param str
+	 *            a string.
+	 * @return a reference to this <code>AppendingStringBuffer</code>.
+	 */
+	public AppendingStringBuffer append(String str)
+	{
+		if (str == null)
+		{
+			str = String.valueOf(str);
+		}
+
+		int len = str.length();
+		int newcount = count + len;
+		if (newcount > value.length)
+		{
+			expandCapacity(newcount);
+		}
+		str.getChars(0, len, value, count);
+		count = newcount;
+		return this;
+	}
+
+	/**
+	 * Appends the specified <tt>AppendingStringBuffer</tt> to this <tt>AppendingStringBuffer</tt>.
+	 * <p>
+	 * The characters of the <tt>AppendingStringBuffer</tt> argument are appended, in order, to the
+	 * contents of this <tt>AppendingStringBuffer</tt>, increasing the length of this
+	 * <tt>AppendingStringBuffer</tt> by the length of the argument. If <tt>sb</tt> is <tt>null</tt>
+	 * , then the four characters <tt>"null"</tt> are appended to this
+	 * <tt>AppendingStringBuffer</tt>.
+	 * <p>
+	 * Let <i>n</i> be the length of the old character sequence, the one contained in the
+	 * <tt>AppendingStringBuffer</tt> just prior to execution of the <tt>append</tt> method. Then
+	 * the character at index <i>k</i> in the new character sequence is equal to the character at
+	 * index <i>k</i> in the old character sequence, if <i>k</i> is less than <i>n</i>; otherwise,
+	 * it is equal to the character at index <i>k-n</i> in the argument <code>sb</code>.
+	 * <p>
+	 * The method <tt>ensureCapacity</tt> is first called on this <tt>AppendingStringBuffer</tt>
+	 * with the new buffer length as its argument. (This ensures that the storage of this
+	 * <tt>AppendingStringBuffer</tt> is adequate to contain the additional characters being
+	 * appended.)
+	 * 
+	 * @param sb
+	 *            the <tt>AppendingStringBuffer</tt> to append.
+	 * @return a reference to this <tt>AppendingStringBuffer</tt>.
+	 * @since 1.4
+	 */
+	public AppendingStringBuffer append(AppendingStringBuffer sb)
+	{
+		if (sb == null)
+		{
+			sb = NULL;
+		}
+
+		int len = sb.length();
+		int newcount = count + len;
+		if (newcount > value.length)
+		{
+			expandCapacity(newcount);
+		}
+		sb.getChars(0, len, value, count);
+		count = newcount;
+		return this;
+	}
+
+	/**
+	 * Appends the specified <tt>AppendingStringBuffer</tt> to this <tt>AppendingStringBuffer</tt>.
+	 * <p>
+	 * The characters of the <tt>AppendingStringBuffer</tt> argument are appended, in order, to the
+	 * contents of this <tt>AppendingStringBuffer</tt>, increasing the length of this
+	 * <tt>AppendingStringBuffer</tt> by the length of the argument. If <tt>sb</tt> is <tt>null</tt>
+	 * , then the four characters <tt>"null"</tt> are appended to this
+	 * <tt>AppendingStringBuffer</tt>.
+	 * <p>
+	 * Let <i>n</i> be the length of the old character sequence, the one contained in the
+	 * <tt>AppendingStringBuffer</tt> just prior to execution of the <tt>append</tt> method. Then
+	 * the character at index <i>k</i> in the new character sequence is equal to the character at
+	 * index <i>k</i> in the old character sequence, if <i>k</i> is less than <i>n</i>; otherwise,
+	 * it is equal to the character at index <i>k-n</i> in the argument <code>sb</code>.
+	 * <p>
+	 * The method <tt>ensureCapacity</tt> is first called on this <tt>AppendingStringBuffer</tt>
+	 * with the new buffer length as its argument. (This ensures that the storage of this
+	 * <tt>AppendingStringBuffer</tt> is adequate to contain the additional characters being
+	 * appended.)
+	 * 
+	 * @param sb
+	 *            the <tt>AppendingStringBuffer</tt> to append.
+	 * @return a reference to this <tt>AppendingStringBuffer</tt>.
+	 * @since 1.4
+	 */
+	public AppendingStringBuffer append(StringBuffer sb)
+	{
+		if (sb == null)
+		{
+			sb = SB_NULL;
+		}
+
+		int len = sb.length();
+		int newcount = count + len;
+		if (newcount > value.length)
+		{
+			expandCapacity(newcount);
+		}
+		sb.getChars(0, len, value, count);
+		count = newcount;
+		return this;
+	}
+
+
+	/**
+	 * Appends the specified <tt>AppendingStringBuffer</tt> to this <tt>AppendingStringBuffer</tt>.
+	 * <p>
+	 * The characters of the <tt>AppendingStringBuffer</tt> argument are appended, in order, to the
+	 * contents of this <tt>AppendingStringBuffer</tt>, increasing the length of this
+	 * <tt>AppendingStringBuffer</tt> by the length of the argument. If <tt>sb</tt> is <tt>null</tt>
+	 * , then the four characters <tt>"null"</tt> are appended to this
+	 * <tt>AppendingStringBuffer</tt>.
+	 * <p>
+	 * Let <i>n</i> be the length of the old character sequence, the one contained in the
+	 * <tt>AppendingStringBuffer</tt> just prior to execution of the <tt>append</tt> method. Then
+	 * the character at index <i>k</i> in the new character sequence is equal to the character at
+	 * index <i>k</i> in the old character sequence, if <i>k</i> is less than <i>n</i>; otherwise,
+	 * it is equal to the character at index <i>k-n</i> in the argument <code>sb</code>.
+	 * <p>
+	 * The method <tt>ensureCapacity</tt> is first called on this <tt>AppendingStringBuffer</tt>
+	 * with the new buffer length as its argument. (This ensures that the storage of this
+	 * <tt>AppendingStringBuffer</tt> is adequate to contain the additional characters being
+	 * appended.)
+	 * 
+	 * @param sb
+	 *            the <tt>AppendingStringBuffer</tt> to append.
+	 * @param from
+	 *            The index where it must start from
+	 * @param length
+	 *            The length that must be copied
+	 * @return a reference to this <tt>AppendingStringBuffer</tt>.
+	 */
+	public AppendingStringBuffer append(StringBuffer sb, int from, int length)
+	{
+		if (sb == null)
+		{
+			sb = SB_NULL;
+		}
+
+		int newcount = count + length;
+		if (newcount > value.length)
+		{
+			expandCapacity(newcount);
+		}
+		sb.getChars(from, length, value, count);
+		count = newcount;
+		return this;
+	}
+
+	/**
+	 * Appends the string representation of the <code>char</code> array argument to this string
+	 * buffer.
+	 * <p>
+	 * The characters of the array argument are appended, in order, to the contents of this string
+	 * buffer. The length of this string buffer increases by the length of the argument.
+	 * <p>
+	 * The overall effect is exactly as if the argument were converted to a string by the method
+	 * {@link String#valueOf(char[])} and the characters of that string were then
+	 * {@link #append(String) appended} to this <code>AppendingStringBuffer</code> object.
+	 * 
+	 * @param str
+	 *            the characters to be appended.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 */
+	public AppendingStringBuffer append(char str[])
+	{
+		int len = str.length;
+		int newcount = count + len;
+		if (newcount > value.length)
+		{
+			expandCapacity(newcount);
+		}
+		System.arraycopy(str, 0, value, count, len);
+		count = newcount;
+		return this;
+	}
+
+	/**
+	 * Appends the string representation of a subarray of the <code>char</code> array argument to
+	 * this string buffer.
+	 * <p>
+	 * Characters of the character array <code>str</code>, starting at index <code>offset</code>,
+	 * are appended, in order, to the contents of this string buffer. The length of this string
+	 * buffer increases by the value of <code>len</code>.
+	 * <p>
+	 * The overall effect is exactly as if the arguments were converted to a string by the method
+	 * {@link String#valueOf(char[],int,int)} and the characters of that string were then
+	 * {@link #append(String) appended} to this <code>AppendingStringBuffer</code> object.
+	 * 
+	 * @param str
+	 *            the characters to be appended.
+	 * @param offset
+	 *            the index of the first character to append.
+	 * @param len
+	 *            the number of characters to append.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 */
+	public AppendingStringBuffer append(char str[], int offset, int len)
+	{
+		int newcount = count + len;
+		if (newcount > value.length)
+		{
+			expandCapacity(newcount);
+		}
+		System.arraycopy(str, offset, value, count, len);
+		count = newcount;
+		return this;
+	}
+
+	/**
+	 * Appends the string representation of the <code>boolean</code> argument to the string buffer.
+	 * <p>
+	 * The argument is converted to a string as if by the method <code>String.valueOf</code>, and
+	 * the characters of that string are then appended to this string buffer.
+	 * 
+	 * @param b
+	 *            a <code>boolean</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code>.
+	 * @see java.lang.String#valueOf(boolean)
+	 * @see java.lang.StringBuffer#append(java.lang.String)
+	 */
+	public AppendingStringBuffer append(boolean b)
+	{
+		if (b)
+		{
+			int newcount = count + 4;
+			if (newcount > value.length)
+			{
+				expandCapacity(newcount);
+			}
+			value[count++] = 't';
+			value[count++] = 'r';
+			value[count++] = 'u';
+			value[count++] = 'e';
+		}
+		else
+		{
+			int newcount = count + 5;
+			if (newcount > value.length)
+			{
+				expandCapacity(newcount);
+			}
+			value[count++] = 'f';
+			value[count++] = 'a';
+			value[count++] = 'l';
+			value[count++] = 's';
+			value[count++] = 'e';
+		}
+		return this;
+	}
+
+	/**
+	 * Appends the string representation of the <code>char</code> argument to this string buffer.
+	 * <p>
+	 * The argument is appended to the contents of this string buffer. The length of this string
+	 * buffer increases by <code>1</code>.
+	 * <p>
+	 * The overall effect is exactly as if the argument were converted to a string by the method
+	 * {@link String#valueOf(char)} and the character in that string were then
+	 * {@link #append(String) appended} to this <code>AppendingStringBuffer</code> object.
+	 * 
+	 * @param c
+	 *            a <code>char</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 */
+	public AppendingStringBuffer append(char c)
+	{
+		int newcount = count + 1;
+		if (newcount > value.length)
+		{
+			expandCapacity(newcount);
+		}
+		value[count++] = c;
+		return this;
+	}
+
+	/**
+	 * Appends the string representation of the <code>int</code> argument to this string buffer.
+	 * <p>
+	 * The argument is converted to a string as if by the method <code>String.valueOf</code>, and
+	 * the characters of that string are then appended to this string buffer.
+	 * 
+	 * @param i
+	 *            an <code>int</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @see java.lang.String#valueOf(int)
+	 * @see java.lang.StringBuffer#append(java.lang.String)
+	 */
+	public AppendingStringBuffer append(int i)
+	{
+		return append(String.valueOf(i));
+	}
+
+	/**
+	 * Appends the string representation of the <code>long</code> argument to this string buffer.
+	 * <p>
+	 * The argument is converted to a string as if by the method <code>String.valueOf</code>, and
+	 * the characters of that string are then appended to this string buffer.
+	 * 
+	 * @param l
+	 *            a <code>long</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @see java.lang.String#valueOf(long)
+	 * @see java.lang.StringBuffer#append(java.lang.String)
+	 */
+	public AppendingStringBuffer append(long l)
+	{
+		return append(String.valueOf(l));
+	}
+
+	/**
+	 * Appends the string representation of the <code>float</code> argument to this string buffer.
+	 * <p>
+	 * The argument is converted to a string as if by the method <code>String.valueOf</code>, and
+	 * the characters of that string are then appended to this string buffer.
+	 * 
+	 * @param f
+	 *            a <code>float</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @see java.lang.String#valueOf(float)
+	 * @see java.lang.StringBuffer#append(java.lang.String)
+	 */
+	public AppendingStringBuffer append(float f)
+	{
+		return append(String.valueOf(f));
+	}
+
+	/**
+	 * Appends the string representation of the <code>double</code> argument to this string buffer.
+	 * <p>
+	 * The argument is converted to a string as if by the method <code>String.valueOf</code>, and
+	 * the characters of that string are then appended to this string buffer.
+	 * 
+	 * @param d
+	 *            a <code>double</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @see java.lang.String#valueOf(double)
+	 * @see java.lang.StringBuffer#append(java.lang.String)
+	 */
+	public AppendingStringBuffer append(double d)
+	{
+		return append(String.valueOf(d));
+	}
+
+	/**
+	 * Removes the characters in a substring of this <code>AppendingStringBuffer</code>. The
+	 * substring begins at the specified <code>start</code> and extends to the character at index
+	 * <code>end - 1</code> or to the end of the <code>AppendingStringBuffer</code> if no such
+	 * character exists. If <code>start</code> is equal to <code>end</code>, no changes are made.
+	 * 
+	 * @param start
+	 *            The beginning index, inclusive.
+	 * @param end
+	 *            The ending index, exclusive.
+	 * @return This string buffer.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if <code>start</code> is negative, greater than <code>length()</code>, or
+	 *                greater than <code>end</code>.
+	 * @since 1.2
+	 */
+	public AppendingStringBuffer delete(int start, int end)
+	{
+		if (start < 0)
+		{
+			throw new StringIndexOutOfBoundsException(start);
+		}
+		if (end > count)
+		{
+			end = count;
+		}
+		if (start > end)
+		{
+			throw new StringIndexOutOfBoundsException();
+		}
+
+		int len = end - start;
+		if (len > 0)
+		{
+			System.arraycopy(value, start + len, value, start, count - end);
+			count -= len;
+		}
+		return this;
+	}
+
+	/**
+	 * Removes the character at the specified position in this <code>AppendingStringBuffer</code>
+	 * (shortening the <code>AppendingStringBuffer</code> by one character).
+	 * 
+	 * @param index
+	 *            Index of character to remove
+	 * @return This string buffer.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if the <code>index</code> is negative or greater than or equal to
+	 *                <code>length()</code>.
+	 * @since 1.2
+	 */
+	public AppendingStringBuffer deleteCharAt(int index)
+	{
+		if ((index < 0) || (index >= count))
+		{
+			throw new StringIndexOutOfBoundsException();
+		}
+		System.arraycopy(value, index + 1, value, index, count - index - 1);
+		count--;
+		return this;
+	}
+
+	/**
+	 * Replaces the characters in a substring of this <code>AppendingStringBuffer</code> with
+	 * characters in the specified <code>String</code>. The substring begins at the specified
+	 * <code>start</code> and extends to the character at index <code>end - 1</code> or to the end
+	 * of the <code>AppendingStringBuffer</code> if no such character exists. First the characters
+	 * in the substring are removed and then the specified <code>String</code> is inserted at
+	 * <code>start</code>. (The <code>AppendingStringBuffer</code> will be lengthened to accommodate
+	 * the specified String if necessary.)
+	 * 
+	 * @param start
+	 *            The beginning index, inclusive.
+	 * @param end
+	 *            The ending index, exclusive.
+	 * @param str
+	 *            String that will replace previous contents.
+	 * @return This string buffer.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if <code>start</code> is negative, greater than <code>length()</code>, or
+	 *                greater than <code>end</code>.
+	 * @since 1.2
+	 */
+	public AppendingStringBuffer replace(int start, int end, String str)
+	{
+		if (start < 0)
+		{
+			throw new StringIndexOutOfBoundsException(start);
+		}
+		if (end > count)
+		{
+			end = count;
+		}
+		if (start > end)
+		{
+			throw new StringIndexOutOfBoundsException();
+		}
+
+		int len = str.length();
+		int newCount = count + len - (end - start);
+		if (newCount > value.length)
+		{
+			expandCapacity(newCount);
+		}
+
+		System.arraycopy(value, end, value, start + len, count - end);
+		str.getChars(0, len, value, start);
+		count = newCount;
+		return this;
+	}
+
+	/**
+	 * Returns a new <code>String</code> that contains a subsequence of characters currently
+	 * contained in this <code>AppendingStringBuffer</code>.The substring begins at the specified
+	 * index and extends to the end of the <code>AppendingStringBuffer</code>.
+	 * 
+	 * @param start
+	 *            The beginning index, inclusive.
+	 * @return The new string.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if <code>start</code> is less than zero, or greater than the length of this
+	 *                <code>AppendingStringBuffer</code>.
+	 * @since 1.2
+	 */
+	public String substring(int start)
+	{
+		return substring(start, count);
+	}
+
+	/**
+	 * Returns a new character sequence that is a subsequence of this sequence.
+	 * 
+	 * <p>
+	 * An invocation of this method of the form
+	 * 
+	 * <blockquote>
+	 * 
+	 * <pre>
+	 * sb.subSequence(begin, end)
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * 
+	 * behaves in exactly the same way as the invocation
+	 * 
+	 * <blockquote>
+	 * 
+	 * <pre>
+	 * sb.substring(begin, end)
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * 
+	 * This method is provided so that the <tt>AppendingStringBuffer</tt> class can implement the
+	 * {@link CharSequence} interface.
+	 * </p>
+	 * 
+	 * @param start
+	 *            the start index, inclusive.
+	 * @param end
+	 *            the end index, exclusive.
+	 * @return the specified subsequence.
+	 * 
+	 * @throws IndexOutOfBoundsException
+	 *             if <tt>start</tt> or <tt>end</tt> are negative, if <tt>end</tt> is greater than
+	 *             <tt>length()</tt>, or if <tt>start</tt> is greater than <tt>end</tt>
+	 * 
+	 * @since 1.4
+	 * @spec JSR-51
+	 */
+	public CharSequence subSequence(int start, int end)
+	{
+		return this.substring(start, end);
+	}
+
+	/**
+	 * Returns a new <code>String</code> that contains a subsequence of characters currently
+	 * contained in this <code>AppendingStringBuffer</code>. The substring begins at the specified
+	 * <code>start</code> and extends to the character at index <code>end - 1</code>. An exception
+	 * is thrown if
+	 * 
+	 * @param start
+	 *            The beginning index, inclusive.
+	 * @param end
+	 *            The ending index, exclusive.
+	 * @return The new string.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if <code>start</code> or <code>end</code> are negative or greater than
+	 *                <code>length()</code>, or <code>start</code> is greater than <code>end</code>.
+	 * @since 1.2
+	 */
+	public String substring(int start, int end)
+	{
+		if (start < 0)
+		{
+			throw new StringIndexOutOfBoundsException(start);
+		}
+		if (end > count)
+		{
+			throw new StringIndexOutOfBoundsException(end);
+		}
+		if (start > end)
+		{
+			throw new StringIndexOutOfBoundsException(end - start);
+		}
+		return new String(value, start, end - start);
+	}
+
+	/**
+	 * Inserts the string representation of a subarray of the <code>str</code> array argument into
+	 * this string buffer. The subarray begins at the specified <code>offset</code> and extends
+	 * <code>len</code> characters. The characters of the subarray are inserted into this string
+	 * buffer at the position indicated by <code>index</code>. The length of this
+	 * <code>AppendingStringBuffer</code> increases by <code>len</code> characters.
+	 * 
+	 * @param index
+	 *            position at which to insert subarray.
+	 * @param str
+	 *            A character array.
+	 * @param offset
+	 *            the index of the first character in subarray to to be inserted.
+	 * @param len
+	 *            the number of characters in the subarray to to be inserted.
+	 * @return This string buffer.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if <code>index</code> is negative or greater than <code>length()</code>, or
+	 *                <code>offset</code> or <code>len</code> are negative, or
+	 *                <code>(offset+len)</code> is greater than <code>str.length</code>.
+	 * @since 1.2
+	 */
+	public AppendingStringBuffer insert(int index, char str[], int offset, int len)
+	{
+		if ((index < 0) || (index > count))
+		{
+			throw new StringIndexOutOfBoundsException();
+		}
+		if ((offset < 0) || (offset + len < 0) || (offset + len > str.length))
+		{
+			throw new StringIndexOutOfBoundsException(offset);
+		}
+		if (len < 0)
+		{
+			throw new StringIndexOutOfBoundsException(len);
+		}
+		int newCount = count + len;
+		if (newCount > value.length)
+		{
+			expandCapacity(newCount);
+		}
+		System.arraycopy(value, index, value, index + len, count - index);
+		System.arraycopy(str, offset, value, index, len);
+		count = newCount;
+		return this;
+	}
+
+	/**
+	 * Inserts the string representation of the <code>Object</code> argument into this string
+	 * buffer.
+	 * <p>
+	 * The second argument is converted to a string as if by the method <code>String.valueOf</code>,
+	 * and the characters of that string are then inserted into this string buffer at the indicated
+	 * offset.
+	 * <p>
+	 * The offset argument must be greater than or equal to <code>0</code>, and less than or equal
+	 * to the length of this string buffer.
+	 * 
+	 * @param offset
+	 *            the offset.
+	 * @param obj
+	 *            an <code>Object</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if the offset is invalid.
+	 * @see java.lang.String#valueOf(java.lang.Object)
+	 * @see AppendingStringBuffer#insert(int, java.lang.String)
+	 * @see AppendingStringBuffer#length()
+	 */
+	public AppendingStringBuffer insert(int offset, Object obj)
+	{
+		if (obj instanceof AppendingStringBuffer)
+		{
+			AppendingStringBuffer asb = (AppendingStringBuffer)obj;
+			return insert(offset, asb.value, 0, asb.count);
+		}
+		else if (obj instanceof StringBuffer)
+		{
+			return insert(offset, (StringBuffer)obj);
+		}
+		return insert(offset, String.valueOf(obj));
+	}
+
+	/**
+	 * Inserts the string into this string buffer.
+	 * <p>
+	 * The characters of the <code>String</code> argument are inserted, in order, into this string
+	 * buffer at the indicated offset, moving up any characters originally above that position and
+	 * increasing the length of this string buffer by the length of the argument. If
+	 * <code>str</code> is <code>null</code>, then the four characters <code>"null"</code> are
+	 * inserted into this string buffer.
+	 * <p>
+	 * The character at index <i>k</i> in the new character sequence is equal to:
+	 * <ul>
+	 * <li>the character at index <i>k</i> in the old character sequence, if <i>k</i> is less than
+	 * <code>offset</code>
+	 * <li>the character at index <i>k</i><code>-offset</code> in the argument <code>str</code>, if
+	 * <i>k</i> is not less than <code>offset</code> but is less than
+	 * <code>offset+str.length()</code>
+	 * <li>the character at index <i>k</i><code>-str.length()</code> in the old character sequence,
+	 * if <i>k</i> is not less than <code>offset+str.length()</code>
+	 * </ul>
+	 * <p>
+	 * The offset argument must be greater than or equal to <code>0</code>, and less than or equal
+	 * to the length of this string buffer.
+	 * 
+	 * @param offset
+	 *            the offset.
+	 * @param str
+	 *            a string.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if the offset is invalid.
+	 * @see java.lang.StringBuffer#length()
+	 */
+	public AppendingStringBuffer insert(int offset, String str)
+	{
+		if ((offset < 0) || (offset > count))
+		{
+			throw new StringIndexOutOfBoundsException();
+		}
+
+		if (str == null)
+		{
+			str = String.valueOf(str);
+		}
+		int len = str.length();
+		int newcount = count + len;
+		if (newcount > value.length)
+		{
+			expandCapacity(newcount);
+		}
+		System.arraycopy(value, offset, value, offset + len, count - offset);
+		str.getChars(0, len, value, offset);
+		count = newcount;
+		return this;
+	}
+
+	/**
+	 * Inserts the string into this string buffer.
+	 * <p>
+	 * The characters of the <code>String</code> argument are inserted, in order, into this string
+	 * buffer at the indicated offset, moving up any characters originally above that position and
+	 * increasing the length of this string buffer by the length of the argument. If
+	 * <code>str</code> is <code>null</code>, then the four characters <code>"null"</code> are
+	 * inserted into this string buffer.
+	 * <p>
+	 * The character at index <i>k</i> in the new character sequence is equal to:
+	 * <ul>
+	 * <li>the character at index <i>k</i> in the old character sequence, if <i>k</i> is less than
+	 * <code>offset</code>
+	 * <li>the character at index <i>k</i><code>-offset</code> in the argument <code>str</code>, if
+	 * <i>k</i> is not less than <code>offset</code> but is less than
+	 * <code>offset+str.length()</code>
+	 * <li>the character at index <i>k</i><code>-str.length()</code> in the old character sequence,
+	 * if <i>k</i> is not less than <code>offset+str.length()</code>
+	 * </ul>
+	 * <p>
+	 * The offset argument must be greater than or equal to <code>0</code>, and less than or equal
+	 * to the length of this string buffer.
+	 * 
+	 * @param offset
+	 *            the offset.
+	 * @param str
+	 *            a string.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if the offset is invalid.
+	 * @see java.lang.StringBuffer#length()
+	 */
+	public AppendingStringBuffer insert(int offset, StringBuffer str)
+	{
+		if ((offset < 0) || (offset > count))
+		{
+			throw new StringIndexOutOfBoundsException();
+		}
+
+		if (str == null)
+		{
+			str = SB_NULL;
+		}
+		int len = str.length();
+		int newcount = count + len;
+		if (newcount > value.length)
+		{
+			expandCapacity(newcount);
+		}
+		System.arraycopy(value, offset, value, offset + len, count - offset);
+		str.getChars(0, len, value, offset);
+		count = newcount;
+		return this;
+	}
+
+	/**
+	 * Inserts the string representation of the <code>char</code> array argument into this string
+	 * buffer.
+	 * <p>
+	 * The characters of the array argument are inserted into the contents of this string buffer at
+	 * the position indicated by <code>offset</code>. The length of this string buffer increases by
+	 * the length of the argument.
+	 * <p>
+	 * The overall effect is exactly as if the argument were converted to a string by the method
+	 * {@link String#valueOf(char[])} and the characters of that string were then
+	 * {@link #insert(int,String) inserted} into this <code>AppendingStringBuffer</code> object at
+	 * the position indicated by <code>offset</code>.
+	 * 
+	 * @param offset
+	 *            the offset.
+	 * @param str
+	 *            a character array.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if the offset is invalid.
+	 */
+	public AppendingStringBuffer insert(int offset, char str[])
+	{
+		if ((offset < 0) || (offset > count))
+		{
+			throw new StringIndexOutOfBoundsException();
+		}
+		int len = str.length;
+		int newcount = count + len;
+		if (newcount > value.length)
+		{
+			expandCapacity(newcount);
+		}
+		System.arraycopy(value, offset, value, offset + len, count - offset);
+		System.arraycopy(str, 0, value, offset, len);
+		count = newcount;
+		return this;
+	}
+
+	/**
+	 * Inserts the string representation of the <code>boolean</code> argument into this string
+	 * buffer.
+	 * <p>
+	 * The second argument is converted to a string as if by the method <code>String.valueOf</code>,
+	 * and the characters of that string are then inserted into this string buffer at the indicated
+	 * offset.
+	 * <p>
+	 * The offset argument must be greater than or equal to <code>0</code>, and less than or equal
+	 * to the length of this string buffer.
+	 * 
+	 * @param offset
+	 *            the offset.
+	 * @param b
+	 *            a <code>boolean</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if the offset is invalid.
+	 * @see java.lang.String#valueOf(boolean)
+	 * @see java.lang.StringBuffer#insert(int, java.lang.String)
+	 * @see java.lang.StringBuffer#length()
+	 */
+	public AppendingStringBuffer insert(int offset, boolean b)
+	{
+		return insert(offset, String.valueOf(b));
+	}
+
+	/**
+	 * Inserts the string representation of the <code>char</code> argument into this string buffer.
+	 * <p>
+	 * The second argument is inserted into the contents of this string buffer at the position
+	 * indicated by <code>offset</code>. The length of this string buffer increases by one.
+	 * <p>
+	 * The overall effect is exactly as if the argument were converted to a string by the method
+	 * {@link String#valueOf(char)} and the character in that string were then
+	 * {@link #insert(int, String) inserted} into this <code>AppendingStringBuffer</code> object at
+	 * the position indicated by <code>offset</code>.
+	 * <p>
+	 * The offset argument must be greater than or equal to <code>0</code>, and less than or equal
+	 * to the length of this string buffer.
+	 * 
+	 * @param offset
+	 *            the offset.
+	 * @param c
+	 *            a <code>char</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @exception IndexOutOfBoundsException
+	 *                if the offset is invalid.
+	 * @see java.lang.StringBuffer#length()
+	 */
+	public AppendingStringBuffer insert(int offset, char c)
+	{
+		int newcount = count + 1;
+		if (newcount > value.length)
+		{
+			expandCapacity(newcount);
+		}
+		System.arraycopy(value, offset, value, offset + 1, count - offset);
+		value[offset] = c;
+		count = newcount;
+		return this;
+	}
+
+	/**
+	 * Inserts the string representation of the second <code>int</code> argument into this string
+	 * buffer.
+	 * <p>
+	 * The second argument is converted to a string as if by the method <code>String.valueOf</code>,
+	 * and the characters of that string are then inserted into this string buffer at the indicated
+	 * offset.
+	 * <p>
+	 * The offset argument must be greater than or equal to <code>0</code>, and less than or equal
+	 * to the length of this string buffer.
+	 * 
+	 * @param offset
+	 *            the offset.
+	 * @param i
+	 *            an <code>int</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if the offset is invalid.
+	 * @see java.lang.String#valueOf(int)
+	 * @see java.lang.StringBuffer#insert(int, java.lang.String)
+	 * @see java.lang.StringBuffer#length()
+	 */
+	public AppendingStringBuffer insert(int offset, int i)
+	{
+		return insert(offset, String.valueOf(i));
+	}
+
+	/**
+	 * Inserts the string representation of the <code>long</code> argument into this string buffer.
+	 * <p>
+	 * The second argument is converted to a string as if by the method <code>String.valueOf</code>,
+	 * and the characters of that string are then inserted into this string buffer at the position
+	 * indicated by <code>offset</code>.
+	 * <p>
+	 * The offset argument must be greater than or equal to <code>0</code>, and less than or equal
+	 * to the length of this string buffer.
+	 * 
+	 * @param offset
+	 *            the offset.
+	 * @param l
+	 *            a <code>long</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if the offset is invalid.
+	 * @see java.lang.String#valueOf(long)
+	 * @see java.lang.StringBuffer#insert(int, java.lang.String)
+	 * @see java.lang.StringBuffer#length()
+	 */
+	public AppendingStringBuffer insert(int offset, long l)
+	{
+		return insert(offset, String.valueOf(l));
+	}
+
+	/**
+	 * Inserts the string representation of the <code>float</code> argument into this string buffer.
+	 * <p>
+	 * The second argument is converted to a string as if by the method <code>String.valueOf</code>,
+	 * and the characters of that string are then inserted into this string buffer at the indicated
+	 * offset.
+	 * <p>
+	 * The offset argument must be greater than or equal to <code>0</code>, and less than or equal
+	 * to the length of this string buffer.
+	 * 
+	 * @param offset
+	 *            the offset.
+	 * @param f
+	 *            a <code>float</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if the offset is invalid.
+	 * @see java.lang.String#valueOf(float)
+	 * @see java.lang.StringBuffer#insert(int, java.lang.String)
+	 * @see java.lang.StringBuffer#length()
+	 */
+	public AppendingStringBuffer insert(int offset, float f)
+	{
+		return insert(offset, String.valueOf(f));
+	}
+
+	/**
+	 * Inserts the string representation of the <code>double</code> argument into this string
+	 * buffer.
+	 * <p>
+	 * The second argument is converted to a string as if by the method <code>String.valueOf</code>,
+	 * and the characters of that string are then inserted into this string buffer at the indicated
+	 * offset.
+	 * <p>
+	 * The offset argument must be greater than or equal to <code>0</code>, and less than or equal
+	 * to the length of this string buffer.
+	 * 
+	 * @param offset
+	 *            the offset.
+	 * @param d
+	 *            a <code>double</code>.
+	 * @return a reference to this <code>AppendingStringBuffer</code> object.
+	 * @exception StringIndexOutOfBoundsException
+	 *                if the offset is invalid.
+	 * @see java.lang.String#valueOf(double)
+	 * @see java.lang.StringBuffer#insert(int, java.lang.String)
+	 * @see java.lang.StringBuffer#length()
+	 */
+	public AppendingStringBuffer insert(int offset, double d)
+	{
+		return insert(offset, String.valueOf(d));
+	}
+
+	/**
+	 * Returns the index within this string of the first occurrence of the specified substring. The
+	 * integer returned is the smallest value <i>k</i> such that: <blockquote>
+	 * 
+	 * <pre>
+	 *       this.toString().startsWith(str, &lt;i&gt;k&lt;/i&gt;)
+	 * </pre>
+	 * 
+	 * </blockquote> is <code>true</code>.
+	 * 
+	 * @param str
+	 *            any string.
+	 * @return if the string argument occurs as a substring within this object, then the index of
+	 *         the first character of the first such substring is returned; if it does not occur as
+	 *         a substring, <code>-1</code> is returned.
+	 * @exception java.lang.NullPointerException
+	 *                if <code>str</code> is <code>null</code>.
+	 * @since 1.4
+	 */
+	public int indexOf(String str)
+	{
+		return indexOf(str, 0);
+	}
+
+	/**
+	 * Returns the index within this string of the first occurrence of the specified substring,
+	 * starting at the specified index. The integer returned is the smallest value <tt>k</tt> for
+	 * which: <blockquote>
+	 * 
+	 * <pre>
+	 * k &gt;= Math.min(fromIndex, str.length()) &amp;&amp; this.toString().startsWith(str, k)
+	 * </pre>
+	 * 
+	 * </blockquote> If no such value of <i>k</i> exists, then -1 is returned.
+	 * 
+	 * @param str
+	 *            the substring for which to search.
+	 * @param fromIndex
+	 *            the index from which to start the search.
+	 * @return the index within this string of the first occurrence of the specified substring,
+	 *         starting at the specified index.
+	 * @exception java.lang.NullPointerException
+	 *                if <code>str</code> is <code>null</code>.
+	 * @since 1.4
+	 */
+	public int indexOf(String str, int fromIndex)
+	{
+		return indexOf(value, 0, count, str.toCharArray(), 0, str.length(), fromIndex);
+	}
+
+	static int indexOf(char[] source, int sourceOffset, int sourceCount, char[] target,
+		int targetOffset, int targetCount, int fromIndex)
+	{
+		if (fromIndex >= sourceCount)
+		{
+			return (targetCount == 0 ? sourceCount : -1);
+		}
+		if (fromIndex < 0)
+		{
+			fromIndex = 0;
+		}
+		if (targetCount == 0)
+		{
+			return fromIndex;
+		}
+
+		char first = target[targetOffset];
+		int i = sourceOffset + fromIndex;
+		int max = sourceOffset + (sourceCount - targetCount);
+
+		startSearchForFirstChar : while (true)
+		{
+			/* Look for first character. */
+			while (i <= max && source[i] != first)
+			{
+				i++;
+			}
+			if (i > max)
+			{
+				return -1;
+			}
+
+			/* Found first character, now look at the rest of v2 */
+			int j = i + 1;
+			int end = j + targetCount - 1;
+			int k = targetOffset + 1;
+			while (j < end)
+			{
+				if (source[j++] != target[k++])
+				{
+					i++;
+					/* Look for str's first char again. */
+					continue startSearchForFirstChar;
+				}
+			}
+			return i - sourceOffset; /* Found whole string. */
+		}
+	}
+
+	/**
+	 * Returns the index within this string of the rightmost occurrence of the specified substring.
+	 * The rightmost empty string "" is considered to occur at the index value
+	 * <code>this.length()</code>. The returned index is the largest value <i>k</i> such that
+	 * <blockquote>
+	 * 
+	 * <pre>
+	 * this.toString().startsWith(str, k)
+	 * </pre>
+	 * 
+	 * </blockquote> is true.
+	 * 
+	 * @param str
+	 *            the substring to search for.
+	 * @return if the string argument occurs one or more times as a substring within this object,
+	 *         then the index of the first character of the last such substring is returned. If it
+	 *         does not occur as a substring, <code>-1</code> is returned.
+	 * @exception java.lang.NullPointerException
+	 *                if <code>str</code> is <code>null</code>.
+	 * @since 1.4
+	 */
+	public int lastIndexOf(String str)
+	{
+		return lastIndexOf(str, count);
+	}
+
+	/**
+	 * Returns the index within this string of the last occurrence of the specified substring. The
+	 * integer returned is the largest value <i>k</i> such that: <blockquote>
+	 * 
+	 * <pre>
+	 * k &lt;= Math.min(fromIndex, str.length()) &amp;&amp; this.toString().startsWith(str, k)
+	 * </pre>
+	 * 
+	 * </blockquote> If no such value of <i>k</i> exists, then -1 is returned.
+	 * 
+	 * @param str
+	 *            the substring to search for.
+	 * @param fromIndex
+	 *            the index to start the search from.
+	 * @return the index within this string of the last occurrence of the specified substring.
+	 * @exception java.lang.NullPointerException
+	 *                if <code>str</code> is <code>null</code>.
+	 * @since 1.4
+	 */
+	public int lastIndexOf(String str, int fromIndex)
+	{
+		return lastIndexOf(value, 0, count, str.toCharArray(), 0, str.length(), fromIndex);
+	}
+
+	static int lastIndexOf(char[] source, int sourceOffset, int sourceCount, char[] target,
+		int targetOffset, int targetCount, int fromIndex)
+	{
+		/*
+		 * Check arguments; return immediately where possible. For consistency, don't check for null
+		 * str.
+		 */
+		int rightIndex = sourceCount - targetCount;
+		if (fromIndex < 0)
+		{
+			return -1;
+		}
+		if (fromIndex > rightIndex)
+		{
+			fromIndex = rightIndex;
+		}
+		/* Empty string always matches. */
+		if (targetCount == 0)
+		{
+			return fromIndex;
+		}
+
+		int strLastIndex = targetOffset + targetCount - 1;
+		char strLastChar = target[strLastIndex];
+		int min = sourceOffset + targetCount - 1;
+		int i = min + fromIndex;
+
+		startSearchForLastChar : while (true)
+		{
+			while (i >= min && source[i] != strLastChar)
+			{
+				i--;
+			}
+			if (i < min)
+			{
+				return -1;
+			}
+			int j = i - 1;
+			int start = j - (targetCount - 1);
+			int k = strLastIndex - 1;
+
+			while (j > start)
+			{
+				if (source[j--] != target[k--])
+				{
+					i--;
+					continue startSearchForLastChar;
+				}
+			}
+			return start - sourceOffset + 1;
+		}
+	}
+
+	/**
+	 * Tests if this AppendingStringBuffer starts with the specified prefix beginning a specified
+	 * index.
+	 * 
+	 * @param prefix
+	 *            the prefix.
+	 * @param toffset
+	 *            where to begin looking in the string.
+	 * @return <code>true</code> if the character sequence represented by the argument is a prefix
+	 *         of the substring of this object starting at index <code>toffset</code>;
+	 *         <code>false</code> otherwise. The result is <code>false</code> if
+	 *         <code>toffset</code> is negative or greater than the length of this
+	 *         <code>String</code> object; otherwise the result is the same as the result of the
+	 *         expression
+	 * 
+	 *         <pre>
+	 * this.subString(toffset).startsWith(prefix)
+	 * </pre>
+	 */
+	public boolean startsWith(CharSequence prefix, int toffset)
+	{
+		char ta[] = value;
+		int to = toffset;
+		int po = 0;
+		int pc = prefix.length();
+		// Note: toffset might be near -1>>>1.
+		if ((toffset < 0) || (toffset > count - pc))
+		{
+			return false;
+		}
+		while (--pc >= 0)
+		{
+			if (ta[to++] != prefix.charAt(po++))
+			{
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Tests if this AppendingStringBuffer starts with the specified prefix.
+	 * 
+	 * @param prefix
+	 *            the prefix.
+	 * @return <code>true</code> if the character sequence represented by the argument is a prefix
+	 *         of the character sequence represented by this AppendingStringBuffer;
+	 *         <code>false</code> otherwise. Note also that <code>true</code> will be returned if
+	 *         the argument is an empty string or is equal to this
+	 *         <code>AppendingStringBuffer</code> object as determined by the
+	 *         {@link #equals(Object)} method.
+	 * @since 1. 0
+	 */
+	public boolean startsWith(CharSequence prefix)
+	{
+		return startsWith(prefix, 0);
+	}
+
+	/**
+	 * Tests if this AppendingStringBuffer ends with the specified suffix.
+	 * 
+	 * @param suffix
+	 *            the suffix.
+	 * @return <code>true</code> if the character sequence represented by the argument is a suffix
+	 *         of the character sequence represented by this AppendingStringBuffer;
+	 *         <code>false</code> otherwise. Note that the result will be <code>true</code> if the
+	 *         argument is the empty string or is equal to this <code>AppendingStringBuffer</code>
+	 *         object as determined by the {@link #equals(Object)} method.
+	 */
+	public boolean endsWith(CharSequence suffix)
+	{
+		return startsWith(suffix, count - suffix.length());
+	}
+
+	/**
+	 * Converts to a string representing the data in this AppendingStringBuffer. A new
+	 * <code>String</code> object is allocated and initialized to contain the character sequence
+	 * currently represented by this string buffer. This <code>String</code> is then returned.
+	 * Subsequent changes to the string buffer do not affect the contents of the <code>String</code>
+	 * .
+	 * <p>
+	 * Implementation advice: This method can be coded so as to create a new <code>String</code>
+	 * object without allocating new memory to hold a copy of the character sequence. Instead, the
+	 * string can share the memory used by the string buffer. Any subsequent operation that alters
+	 * the content or capacity of the string buffer must then make a copy of the internal buffer at
+	 * that time. This strategy is effective for reducing the amount of memory allocated by a string
+	 * concatenation operation when it is implemented using a string buffer.
+	 * 
+	 * @return a string representation of the string buffer.
+	 */
+	@Override
+	public String toString()
+	{
+		return new String(value, 0, count);
+	}
+
+	/**
+	 * This method returns the internal char array. So it is not
+	 * 
+	 * @return The internal char array
+	 */
+	public final char[] getValue()
+	{
+		return value;
+	}
+
+
+	/**
+	 * readObject is called to restore the state of the AppendingStringBuffer from a stream.
+	 * 
+	 * @param s
+	 * @throws ClassNotFoundException
+	 * @throws IOException
+	 */
+	private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException
+	{
+		s.defaultReadObject();
+		value = value.clone();
+	}
+
+	/**
+	 * Compares this AppendingStringBuffer to the specified object. The result is <code>true</code>
+	 * if and only if the argument is not <code>null</code> and is a
+	 * <code>AppendingStringBuffer</code> object or another charsequence object! that represents the
+	 * same sequence of characters as this object.
+	 * 
+	 * @param anObject
+	 *            the object to compare this <code>AppendingStringBuffer</code> against.
+	 * @return <code>true</code> if the <code>AppendingStringBuffer</code>are equal;
+	 *         <code>false</code> otherwise.
+	 */
+	@Override
+	public boolean equals(Object anObject)
+	{
+		if (this == anObject)
+		{
+			return true;
+		}
+		if (anObject instanceof AppendingStringBuffer)
+		{
+			AppendingStringBuffer anotherString = (AppendingStringBuffer)anObject;
+			int n = count;
+			if (n == anotherString.count)
+			{
+				char v1[] = value;
+				char v2[] = anotherString.value;
+				int i = 0;
+				while (n-- != 0)
+				{
+					if (v1[i] != v2[i++])
+					{
+						return false;
+					}
+				}
+				return true;
+			}
+		}
+		else if (anObject instanceof CharSequence)
+		{
+			CharSequence sequence = (CharSequence)anObject;
+			int n = count;
+			if (sequence.length() == count)
+			{
+				char v1[] = value;
+				int i = 0;
+				while (n-- != 0)
+				{
+					if (v1[i] != sequence.charAt(i++))
+					{
+						return false;
+					}
+				}
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns a hash code for this AppendingStringBuffer. The hash code for a
+	 * <code>AppendingStringBuffer</code> object is computed as <blockquote>
+	 * 
+	 * <pre>
+	 *    s[0]*31&circ;(n-1) + s[1]*31&circ;(n-2) + ... + s[n-1]
+	 * </pre>
+	 * 
+	 * </blockquote> using <code>int</code> arithmetic, where <code>s[i]</code> is the <i>i</i>th
+	 * character of the AppendingStringBuffer, <code>n</code> is the length of the
+	 * AppendingStringBuffer, and <code>^</code> indicates exponentiation. (The hash value of the
+	 * empty AppendingStringBuffer is zero.)
+	 * 
+	 * @return a hash code value for this object.
+	 */
+	@Override
+	public int hashCode()
+	{
+		int h = 0;
+		if (h == 0)
+		{
+			int off = 0;
+			char val[] = value;
+			int len = count;
+
+			for (int i = 0; i < len; i++)
+			{
+				h = 31 * h + val[off++];
+			}
+		}
+		return h;
+	}
+
+	/**
+	 * Clears the buffer contents, but leaves the allocated size intact
+	 */
+	public void clear()
+	{
+		count = 0;
+	}
+}
\ No newline at end of file

Propchange: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/AppendingStringBuffer.java
------------------------------------------------------------------------------
    svn:executable = *

Added: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/IStringIterator.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/IStringIterator.java?rev=924074&view=auto
==============================================================================
--- wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/IStringIterator.java (added)
+++ wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/IStringIterator.java Wed Mar 17 00:34:34 2010
@@ -0,0 +1,35 @@
+/*
+ * 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.wicket.util.string;
+
+/**
+ * Typesafe string iterator interface
+ * 
+ * @author Jonathan Locke
+ */
+public interface IStringIterator
+{
+	/**
+	 * @return True if there is a next string
+	 */
+	boolean hasNext();
+
+	/**
+	 * @return The next string!
+	 */
+	String next();
+}
\ No newline at end of file

Propchange: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/IStringIterator.java
------------------------------------------------------------------------------
    svn:executable = *

Added: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/IStringSequence.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/IStringSequence.java?rev=924074&view=auto
==============================================================================
--- wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/IStringSequence.java (added)
+++ wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/IStringSequence.java Wed Mar 17 00:34:34 2010
@@ -0,0 +1,47 @@
+/*
+ * 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.wicket.util.string;
+
+/**
+ * Typesafe interface to an ordered sequence of strings. An IStringIterator can be retrieved for the
+ * sequence by calling iterator(), the number of Strings in the sequence can be determined by
+ * calling size() and a given String can be retrieved by calling get(int index).
+ * 
+ * @author Jonathan Locke
+ */
+public interface IStringSequence
+{
+	/**
+	 * Gets a string at a given index in the sequence
+	 * 
+	 * @param index
+	 *            The index
+	 * @return The string at the given index
+	 * @throws IndexOutOfBoundsException
+	 */
+	String get(int index) throws IndexOutOfBoundsException;
+
+	/**
+	 * @return Typesafe string iterator
+	 */
+	IStringIterator iterator();
+
+	/**
+	 * @return Number of strings in this sequence
+	 */
+	int size();
+}

Propchange: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/IStringSequence.java
------------------------------------------------------------------------------
    svn:executable = *

Added: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/PrependingStringBuffer.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/PrependingStringBuffer.java?rev=924074&view=auto
==============================================================================
--- wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/PrependingStringBuffer.java (added)
+++ wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/PrependingStringBuffer.java Wed Mar 17 00:34:34 2010
@@ -0,0 +1,164 @@
+/*
+ * 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.wicket.util.string;
+
+/**
+ * This is a prepending stringbuffer optimized for constantly prepending strings to the front of the
+ * buffer.
+ * 
+ * @author jcompagner
+ */
+public class PrependingStringBuffer
+{
+	private int size;
+	private int position;
+
+	private char[] buffer;
+
+	/**
+	 * Default constructor, the internal initial buffer size will be 16
+	 */
+	public PrependingStringBuffer()
+	{
+		this(16);
+	}
+
+	/**
+	 * Constructs this PrependingStringBuffer with the given buffer size.
+	 * 
+	 * @param size
+	 *            The initial size of the buffer.
+	 */
+	public PrependingStringBuffer(int size)
+	{
+		buffer = new char[size];
+		position = size;
+		this.size = 0;
+	}
+
+	/**
+	 * Constructs and direct inserts the given string. The buffer size will be string.length+16
+	 * 
+	 * @param start
+	 *            The string that is directly inserted.
+	 */
+	public PrependingStringBuffer(String start)
+	{
+		this(start.length() + 16);
+		prepend(start);
+	}
+
+	/**
+	 * Prepends one char to this PrependingStringBuffer
+	 * 
+	 * @param ch
+	 *            The char that will be prepended
+	 * @return this
+	 */
+	public PrependingStringBuffer prepend(char ch)
+	{
+		int len = 1;
+		if (position < len)
+		{
+			expandCapacity(size + len);
+		}
+		position -= len;
+		buffer[position] = ch;
+		size += len;
+		return this;
+	}
+
+	/**
+	 * Prepends the string to this PrependingStringBuffer
+	 * 
+	 * @param str
+	 *            The string that will be prepended
+	 * @return this
+	 */
+	public PrependingStringBuffer prepend(String str)
+	{
+		int len = str.length();
+		if (position < len)
+		{
+			expandCapacity(size + len);
+		}
+		str.getChars(0, len, buffer, position - len);
+		position -= len;
+		size += len;
+		return this;
+	}
+
+	private void expandCapacity(int minimumCapacity)
+	{
+		int newCapacity = (buffer.length + 1) * 2;
+		if (newCapacity < 0)
+		{
+			newCapacity = Integer.MAX_VALUE;
+		}
+		else if (minimumCapacity > newCapacity)
+		{
+			newCapacity = minimumCapacity;
+		}
+
+		char newValue[] = new char[newCapacity];
+		System.arraycopy(buffer, position, newValue, newCapacity - size, size);
+		buffer = newValue;
+		position = newCapacity - size;
+	}
+
+	/**
+	 * Returns the size of this PrependingStringBuffer
+	 * 
+	 * @return The size
+	 */
+	public int length()
+	{
+		return size;
+	}
+
+	/**
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString()
+	{
+		return new String(buffer, position, size);
+	}
+
+	@Override
+	public boolean equals(Object obj)
+	{
+		if (obj == this)
+		{
+			return true;
+		}
+		else if (obj == null)
+		{
+			return false;
+		}
+		else
+		{
+			return toString().equals(obj.toString());
+		}
+	}
+
+	@Override
+	public int hashCode()
+	{
+		return toString().hashCode();
+	}
+}
\ No newline at end of file

Propchange: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/PrependingStringBuffer.java
------------------------------------------------------------------------------
    svn:executable = *

Added: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/StringList.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/StringList.java?rev=924074&view=auto
==============================================================================
--- wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/StringList.java (added)
+++ wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/StringList.java Wed Mar 17 00:34:34 2010
@@ -0,0 +1,388 @@
+/*
+ * 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.wicket.util.string;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * A typesafe, mutable list of strings supporting a variety of convenient operations as well as
+ * expected operations from List such as add(), size(), remove(), iterator(), get(int index) and
+ * toArray(). Instances of the class are not threadsafe.
+ * <p>
+ * StringList objects can be constructed empty or they can be created using any of several static
+ * factory methods:
+ * <ul>
+ * <li>valueOf(String[])
+ * <li>valueOf(String)
+ * <li>valueOf(Collection)
+ * <li>valueOf(Object[])
+ * </ul>
+ * In the case of the Collection and Object[] factory methods, each Object in the collection or
+ * array is converted to a String via toString() before being added to the StringList.
+ * <p>
+ * The tokenize() factory methods allow easy creation of StringLists via StringTokenizer. The
+ * repeat() static factory method creates a StringList that repeats a given String a given number of
+ * times.
+ * <p>
+ * The prepend() method adds a String to the beginning of the StringList. The removeLast() method
+ * pops a String off the end of the list. The sort() method sorts strings in the List using
+ * Collections.sort(). The class also inherits useful methods from AbstractStringList that include
+ * join() methods ala Perl and a toString() method which joins the list of strings with comma
+ * separators for easy viewing.
+ * 
+ * @author Jonathan Locke
+ */
+public final class StringList extends AbstractStringList
+{
+	private static final long serialVersionUID = 1L;
+
+	// The underlying list of strings
+	private final List<String> strings;
+
+	// The total length of all strings in the list
+	private int totalLength;
+
+	/**
+	 * Returns a list of a string repeated a given number of times.
+	 * 
+	 * @param count
+	 *            The number of times to repeat the string
+	 * @param string
+	 *            The string to repeat
+	 * @return The list of strings
+	 */
+	public static StringList repeat(final int count, final String string)
+	{
+		final StringList list = new StringList(count);
+
+		for (int i = 0; i < count; i++)
+		{
+			list.add(string);
+		}
+
+		return list;
+	}
+
+	/**
+	 * Extracts tokens from a comma and space delimited string.
+	 * 
+	 * @param string
+	 *            The string
+	 * @return The string tokens as a list
+	 */
+	public static StringList tokenize(final String string)
+	{
+		return tokenize(string, ", ");
+	}
+
+	/**
+	 * Extracts tokens from a delimited string.
+	 * 
+	 * @param string
+	 *            The string
+	 * @param delimiters
+	 *            The delimiters
+	 * @return The string tokens as a list
+	 */
+	public static StringList tokenize(final String string, final String delimiters)
+	{
+		final StringTokenizer tokenizer = new StringTokenizer(string, delimiters);
+		final StringList strings = new StringList();
+
+		while (tokenizer.hasMoreTokens())
+		{
+			strings.add(tokenizer.nextToken());
+		}
+
+		return strings;
+	}
+
+	/**
+	 * Converts a collection of objects into a list of string values by using the conversion methods
+	 * of the StringValue class.
+	 * 
+	 * @param collection
+	 *            The collection to add as strings
+	 * @return The list
+	 */
+	public static StringList valueOf(final Collection<?> collection)
+	{
+		if (collection != null)
+		{
+			final StringList strings = new StringList(collection.size());
+
+			for (Object object : collection)
+			{
+				strings.add(StringValue.valueOf(object));
+			}
+
+			return strings;
+		}
+		else
+		{
+			return new StringList();
+		}
+	}
+
+	/**
+	 * Converts an array of objects into a list of strings by using the object to string conversion
+	 * method of the StringValue class.
+	 * 
+	 * @param objects
+	 *            The objects to convert
+	 * @return The list of strings
+	 */
+	public static StringList valueOf(final Object[] objects)
+	{
+		// check for null parameter
+		int length = (objects == null) ? 0 : objects.length;
+		final StringList strings = new StringList(length);
+
+		for (int i = 0; i < length; i++)
+		{
+			strings.add(StringValue.valueOf(objects[i]));
+		}
+
+		return strings;
+	}
+
+	/**
+	 * Returns a string list with just one string in it.
+	 * 
+	 * @param string
+	 *            The string
+	 * @return The list of one string
+	 */
+	public static StringList valueOf(final String string)
+	{
+		final StringList strings = new StringList();
+
+		if (string != null)
+		{
+			strings.add(string);
+		}
+
+		return strings;
+	}
+
+	/**
+	 * Converts a string array to a string list.
+	 * 
+	 * @param array
+	 *            The array
+	 * @return The list
+	 */
+	public static StringList valueOf(final String[] array)
+	{
+		int length = (array == null) ? 0 : array.length;
+		final StringList strings = new StringList(length);
+
+		for (int i = 0; i < length; i++)
+		{
+			strings.add(array[i]);
+		}
+
+		return strings;
+	}
+
+	/**
+	 * Constructor.
+	 */
+	public StringList()
+	{
+		strings = new ArrayList<String>();
+	}
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param size
+	 *            Number of elements to preallocate
+	 */
+	public StringList(final int size)
+	{
+		strings = new ArrayList<String>(size);
+	}
+
+	/**
+	 * Adds a string to the back of this list.
+	 * 
+	 * @param string
+	 *            String to add
+	 */
+	public void add(final String string)
+	{
+		// Add to list
+		add(size(), string);
+	}
+
+	/**
+	 * Adds the string to the stringlist at position pos.
+	 * 
+	 * @param pos
+	 *            the position to add the string at
+	 * @param string
+	 *            the string to add.
+	 */
+	public void add(final int pos, final String string)
+	{
+		strings.add(pos, string == null ? "" : string);
+
+		// Increase total length
+		totalLength += string == null ? 0 : string.length();
+	}
+
+	/**
+	 * Adds a string value to this list as a string.
+	 * 
+	 * @param value
+	 *            The value to add
+	 */
+	public void add(final StringValue value)
+	{
+		add(value.toString());
+	}
+
+	/**
+	 * @param string
+	 *            The string to look for
+	 * @return True if the list contains the string
+	 */
+	public boolean contains(final String string)
+	{
+		return strings.contains(string);
+	}
+
+	/**
+	 * Gets the string at the given index.
+	 * 
+	 * @param index
+	 *            The index
+	 * @return The string at the index
+	 * @throws IndexOutOfBoundsException
+	 */
+	@Override
+	public String get(final int index)
+	{
+		return strings.get(index);
+	}
+
+	/**
+	 * @return List value (not a copy of this list)
+	 */
+	public List<String> getList()
+	{
+		return strings;
+	}
+
+	/**
+	 * Returns a typesafe iterator over this collection of strings.
+	 * 
+	 * @return Typesafe string iterator
+	 */
+	@Override
+	public IStringIterator iterator()
+	{
+		return new IStringIterator()
+		{
+			private final Iterator<String> iterator = strings.iterator();
+
+			public boolean hasNext()
+			{
+				return iterator.hasNext();
+			}
+
+			public String next()
+			{
+				return iterator.next();
+			}
+		};
+	}
+
+	/**
+	 * Adds the given string to the front of the list.
+	 * 
+	 * @param string
+	 *            The string to add
+	 */
+	public void prepend(final String string)
+	{
+		add(0, string);
+	}
+
+	/**
+	 * Removes the string at the given index.
+	 * 
+	 * @param index
+	 *            The index
+	 */
+	public void remove(final int index)
+	{
+		String string = strings.remove(index);
+		totalLength = totalLength - string.length();
+	}
+
+	/**
+	 * Removes the last string in this list.
+	 */
+	public void removeLast()
+	{
+		remove(size() - 1);
+	}
+
+	/**
+	 * @return The number of strings in this list.
+	 */
+	@Override
+	public int size()
+	{
+		return strings.size();
+	}
+
+	/**
+	 * Sorts this string list alphabetically.
+	 */
+	public void sort()
+	{
+		Collections.sort(strings);
+	}
+
+	/**
+	 * Converts this string list to a string array.
+	 * 
+	 * @return The string array
+	 */
+	@Override
+	public String[] toArray()
+	{
+		return strings.toArray(new String[size()]);
+	}
+
+	/**
+	 * @return The total length of all strings in this list.
+	 */
+	@Override
+	public int totalLength()
+	{
+		return totalLength;
+	}
+}

Propchange: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/StringList.java
------------------------------------------------------------------------------
    svn:executable = *