1 /*
   2  * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package java.lang;
  27 
  28 import sun.misc.FloatingDecimal;
  29 import java.util.Arrays;
  30 import java.util.Iterator;
  31 
  32 /**
  33  * A mutable sequence of characters.
  34  * <p>
  35  * Implements a modifiable string. At any point in time it contains some
  36  * particular sequence of characters, but the length and content of the
  37  * sequence can be changed through certain method calls.
  38  *
  39  * @author      Michael McCloskey
  40  * @since       1.5
  41  */
  42 abstract class AbstractStringBuilder implements Appendable, CharSequence {
  43     /**
  44      * The value is used for character storage.
  45      */
  46     char[] value;
  47 
  48     /**
  49      * The count is the number of characters used.
  50      */
  51     int count;
  52 
  53     /**
  54      * This no-arg constructor is necessary for serialization of subclasses.
  55      */
  56     AbstractStringBuilder() {
  57     }
  58 
  59     /**
  60      * Creates an AbstractStringBuilder of the specified capacity.
  61      */
  62     AbstractStringBuilder(int capacity) {
  63         value = new char[capacity];
  64     }
  65 
  66     /**
  67      * Returns the length (character count).
  68      *
  69      * @return  the length of the sequence of characters currently
  70      *          represented by this object
  71      */
  72     public int length() {
  73         return count;
  74     }
  75 
  76     /**
  77      * Returns the current capacity. The capacity is the amount of storage
  78      * available for newly inserted characters, beyond which an allocation
  79      * will occur.
  80      *
  81      * @return  the current capacity
  82      */
  83     public int capacity() {
  84         return value.length;
  85     }
  86 
  87     /**
  88      * Ensures that the capacity is at least equal to the specified minimum.
  89      * If the current capacity is less than the argument, then a new internal
  90      * array is allocated with greater capacity. The new capacity is the
  91      * larger of:
  92      * <ul>
  93      * <li>The <code>minimumCapacity</code> argument.
  94      * <li>Twice the old capacity, plus <code>2</code>.
  95      * </ul>
  96      * If the <code>minimumCapacity</code> argument is nonpositive, this
  97      * method takes no action and simply returns.
  98      *
  99      * @param   minimumCapacity   the minimum desired capacity.
 100      */
 101     public void ensureCapacity(int minimumCapacity) {
 102         if (minimumCapacity > value.length) {
 103             expandCapacity(minimumCapacity);
 104         }
 105     }
 106 
 107     /**
 108      * This implements the expansion semantics of ensureCapacity with no
 109      * size check or synchronization.
 110      */
 111     void expandCapacity(int minimumCapacity) {
 112         int newCapacity = (value.length + 1) * 2;
 113         if (newCapacity < 0) {
 114             newCapacity = Integer.MAX_VALUE;
 115         } else if (minimumCapacity > newCapacity) {
 116             newCapacity = minimumCapacity;
 117         }
 118         value = Arrays.copyOf(value, newCapacity);
 119     }
 120 
 121     /**
 122      * Attempts to reduce storage used for the character sequence.
 123      * If the buffer is larger than necessary to hold its current sequence of
 124      * characters, then it may be resized to become more space efficient.
 125      * Calling this method may, but is not required to, affect the value
 126      * returned by a subsequent call to the {@link #capacity()} method.
 127      */
 128     public void trimToSize() {
 129         if (count < value.length) {
 130             value = Arrays.copyOf(value, count);
 131         }
 132     }
 133 
 134     /**
 135      * Sets the length of the character sequence.
 136      * The sequence is changed to a new character sequence
 137      * whose length is specified by the argument. For every nonnegative
 138      * index <i>k</i> less than <code>newLength</code>, the character at
 139      * index <i>k</i> in the new character sequence is the same as the
 140      * character at index <i>k</i> in the old sequence if <i>k</i> is less
 141      * than the length of the old character sequence; otherwise, it is the
 142      * null character <code>'&#92;u0000'</code>.
 143      *
 144      * In other words, if the <code>newLength</code> argument is less than
 145      * the current length, the length is changed to the specified length.
 146      * <p>
 147      * If the <code>newLength</code> argument is greater than or equal
 148      * to the current length, sufficient null characters
 149      * (<code>'&#92;u0000'</code>) are appended so that
 150      * length becomes the <code>newLength</code> argument.
 151      * <p>
 152      * The <code>newLength</code> argument must be greater than or equal
 153      * to <code>0</code>.
 154      *
 155      * @param      newLength   the new length
 156      * @throws     IndexOutOfBoundsException  if the
 157      *               <code>newLength</code> argument is negative.
 158      */
 159     public void setLength(int newLength) {
 160         if (newLength < 0)
 161             throw new StringIndexOutOfBoundsException(newLength);
 162         if (newLength > value.length)
 163             expandCapacity(newLength);
 164 
 165         if (count < newLength) {
 166             for (; count < newLength; count++)
 167                 value[count] = '\0';
 168         } else {
 169             count = newLength;
 170         }
 171     }
 172 
 173     /**
 174      * Returns the <code>char</code> value in this sequence at the specified index.
 175      * The first <code>char</code> value is at index <code>0</code>, the next at index
 176      * <code>1</code>, and so on, as in array indexing.
 177      * <p>
 178      * The index argument must be greater than or equal to
 179      * <code>0</code>, and less than the length of this sequence.
 180      *
 181      * <p>If the <code>char</code> value specified by the index is a
 182      * <a href="Character.html#unicode">surrogate</a>, the surrogate
 183      * value is returned.
 184      *
 185      * @param      index   the index of the desired <code>char</code> value.
 186      * @return     the <code>char</code> value at the specified index.
 187      * @throws     IndexOutOfBoundsException  if <code>index</code> is
 188      *             negative or greater than or equal to <code>length()</code>.
 189      */
 190     public char charAt(int index) {
 191         if ((index < 0) || (index >= count))
 192             throw new StringIndexOutOfBoundsException(index);
 193         return value[index];
 194     }
 195 
 196     /**
 197      * Returns the character (Unicode code point) at the specified
 198      * index. The index refers to <code>char</code> values
 199      * (Unicode code units) and ranges from <code>0</code> to
 200      * {@link #length()}<code> - 1</code>.
 201      *
 202      * <p> If the <code>char</code> value specified at the given index
 203      * is in the high-surrogate range, the following index is less
 204      * than the length of this sequence, and the
 205      * <code>char</code> value at the following index is in the
 206      * low-surrogate range, then the supplementary code point
 207      * corresponding to this surrogate pair is returned. Otherwise,
 208      * the <code>char</code> value at the given index is returned.
 209      *
 210      * @param      index the index to the <code>char</code> values
 211      * @return     the code point value of the character at the
 212      *             <code>index</code>
 213      * @exception  IndexOutOfBoundsException  if the <code>index</code>
 214      *             argument is negative or not less than the length of this
 215      *             sequence.
 216      */
 217     public int codePointAt(int index) {
 218         if ((index < 0) || (index >= count)) {
 219             throw new StringIndexOutOfBoundsException(index);
 220         }
 221         return Character.codePointAt(value, index);
 222     }
 223 
 224     /**
 225      * Returns the character (Unicode code point) before the specified
 226      * index. The index refers to <code>char</code> values
 227      * (Unicode code units) and ranges from <code>1</code> to {@link
 228      * #length()}.
 229      *
 230      * <p> If the <code>char</code> value at <code>(index - 1)</code>
 231      * is in the low-surrogate range, <code>(index - 2)</code> is not
 232      * negative, and the <code>char</code> value at <code>(index -
 233      * 2)</code> is in the high-surrogate range, then the
 234      * supplementary code point value of the surrogate pair is
 235      * returned. If the <code>char</code> value at <code>index -
 236      * 1</code> is an unpaired low-surrogate or a high-surrogate, the
 237      * surrogate value is returned.
 238      *
 239      * @param     index the index following the code point that should be returned
 240      * @return    the Unicode code point value before the given index.
 241      * @exception IndexOutOfBoundsException if the <code>index</code>
 242      *            argument is less than 1 or greater than the length
 243      *            of this sequence.
 244      */
 245     public int codePointBefore(int index) {
 246         int i = index - 1;
 247         if ((i < 0) || (i >= count)) {
 248             throw new StringIndexOutOfBoundsException(index);
 249         }
 250         return Character.codePointBefore(value, index);
 251     }
 252 
 253     /**
 254      * Returns the number of Unicode code points in the specified text
 255      * range of this sequence. The text range begins at the specified
 256      * <code>beginIndex</code> and extends to the <code>char</code> at
 257      * index <code>endIndex - 1</code>. Thus the length (in
 258      * <code>char</code>s) of the text range is
 259      * <code>endIndex-beginIndex</code>. Unpaired surrogates within
 260      * this sequence count as one code point each.
 261      *
 262      * @param beginIndex the index to the first <code>char</code> of
 263      * the text range.
 264      * @param endIndex the index after the last <code>char</code> of
 265      * the text range.
 266      * @return the number of Unicode code points in the specified text
 267      * range
 268      * @exception IndexOutOfBoundsException if the
 269      * <code>beginIndex</code> is negative, or <code>endIndex</code>
 270      * is larger than the length of this sequence, or
 271      * <code>beginIndex</code> is larger than <code>endIndex</code>.
 272      */
 273     public int codePointCount(int beginIndex, int endIndex) {
 274         if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
 275             throw new IndexOutOfBoundsException();
 276         }
 277         return Character.codePointCountImpl(value, beginIndex, endIndex-beginIndex);
 278     }
 279 
 280     /**
 281      * Returns the index within this sequence that is offset from the
 282      * given <code>index</code> by <code>codePointOffset</code> code
 283      * points. Unpaired surrogates within the text range given by
 284      * <code>index</code> and <code>codePointOffset</code> count as
 285      * one code point each.
 286      *
 287      * @param index the index to be offset
 288      * @param codePointOffset the offset in code points
 289      * @return the index within this sequence
 290      * @exception IndexOutOfBoundsException if <code>index</code>
 291      *   is negative or larger then the length of this sequence,
 292      *   or if <code>codePointOffset</code> is positive and the subsequence
 293      *   starting with <code>index</code> has fewer than
 294      *   <code>codePointOffset</code> code points,
 295      *   or if <code>codePointOffset</code> is negative and the subsequence
 296      *   before <code>index</code> has fewer than the absolute value of
 297      *   <code>codePointOffset</code> code points.
 298      */
 299     public int offsetByCodePoints(int index, int codePointOffset) {
 300         if (index < 0 || index > count) {
 301             throw new IndexOutOfBoundsException();
 302         }
 303         return Character.offsetByCodePointsImpl(value, 0, count,
 304                                                 index, codePointOffset);
 305     }
 306 
 307     /**
 308      * Characters are copied from this sequence into the
 309      * destination character array <code>dst</code>. The first character to
 310      * be copied is at index <code>srcBegin</code>; the last character to
 311      * be copied is at index <code>srcEnd-1</code>. The total number of
 312      * characters to be copied is <code>srcEnd-srcBegin</code>. The
 313      * characters are copied into the subarray of <code>dst</code> starting
 314      * at index <code>dstBegin</code> and ending at index:
 315      * <p><blockquote><pre>
 316      * dstbegin + (srcEnd-srcBegin) - 1
 317      * </pre></blockquote>
 318      *
 319      * @param      srcBegin   start copying at this offset.
 320      * @param      srcEnd     stop copying at this offset.
 321      * @param      dst        the array to copy the data into.
 322      * @param      dstBegin   offset into <code>dst</code>.
 323      * @throws     NullPointerException if <code>dst</code> is
 324      *             <code>null</code>.
 325      * @throws     IndexOutOfBoundsException  if any of the following is true:
 326      *             <ul>
 327      *             <li><code>srcBegin</code> is negative
 328      *             <li><code>dstBegin</code> is negative
 329      *             <li>the <code>srcBegin</code> argument is greater than
 330      *             the <code>srcEnd</code> argument.
 331      *             <li><code>srcEnd</code> is greater than
 332      *             <code>this.length()</code>.
 333      *             <li><code>dstBegin+srcEnd-srcBegin</code> is greater than
 334      *             <code>dst.length</code>
 335      *             </ul>
 336      */
 337     public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
 338     {
 339         if (srcBegin < 0)
 340             throw new StringIndexOutOfBoundsException(srcBegin);
 341         if ((srcEnd < 0) || (srcEnd > count))
 342             throw new StringIndexOutOfBoundsException(srcEnd);
 343         if (srcBegin > srcEnd)
 344             throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
 345         System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
 346     }
 347 
 348     /**
 349      * The character at the specified index is set to <code>ch</code>. This
 350      * sequence is altered to represent a new character sequence that is
 351      * identical to the old character sequence, except that it contains the
 352      * character <code>ch</code> at position <code>index</code>.
 353      * <p>
 354      * The index argument must be greater than or equal to
 355      * <code>0</code>, and less than the length of this sequence.
 356      *
 357      * @param      index   the index of the character to modify.
 358      * @param      ch      the new character.
 359      * @throws     IndexOutOfBoundsException  if <code>index</code> is
 360      *             negative or greater than or equal to <code>length()</code>.
 361      */
 362     public void setCharAt(int index, char ch) {
 363         if ((index < 0) || (index >= count))
 364             throw new StringIndexOutOfBoundsException(index);
 365         value[index] = ch;
 366     }
 367 
 368     /**
 369      * Appends the string representation of the {@code Object} argument.
 370      * <p>
 371      * The overall effect is exactly as if the argument were converted
 372      * to a string by the method {@link String#valueOf(Object)},
 373      * and the characters of that string were then
 374      * {@link #append(String) appended} to this character sequence.
 375      *
 376      * @param   obj   an {@code Object}.
 377      * @return  a reference to this object.
 378      */
 379     public AbstractStringBuilder append(Object obj) {
 380         return append(String.valueOf(obj));
 381     }
 382 
 383     /**
 384      * Appends the specified string to this character sequence.
 385      * <p>
 386      * The characters of the {@code String} argument are appended, in
 387      * order, increasing the length of this sequence by the length of the
 388      * argument. If {@code str} is {@code null}, then the four
 389      * characters {@code "null"} are appended.
 390      * <p>
 391      * Let <i>n</i> be the length of this character sequence just prior to
 392      * execution of the {@code append} method. Then the character at
 393      * index <i>k</i> in the new character sequence is equal to the character
 394      * at index <i>k</i> in the old character sequence, if <i>k</i> is less
 395      * than <i>n</i>; otherwise, it is equal to the character at index
 396      * <i>k-n</i> in the argument {@code str}.
 397      *
 398      * @param   str   a string.
 399      * @return  a reference to this object.
 400      */
 401     public AbstractStringBuilder append(String str) {
 402         if (str == null) str = "null";
 403         int len = str.length();
 404         if (len == 0) return this;
 405         int newCount = count + len;
 406         if (newCount > value.length)
 407             expandCapacity(newCount);
 408         str.getChars(0, len, value, count);
 409         count = newCount;
 410         return this;
 411     }
 412 
 413     // Documentation in subclasses because of synchro difference
 414     public AbstractStringBuilder append(StringBuffer sb) {
 415         if (sb == null)
 416             return append("null");
 417         int len = sb.length();
 418         int newCount = count + len;
 419         if (newCount > value.length)
 420             expandCapacity(newCount);
 421         sb.getChars(0, len, value, count);
 422         count = newCount;
 423         return this;
 424     }
 425 
 426     // Documentation in subclasses because of synchro difference
 427     public AbstractStringBuilder append(CharSequence s) {
 428         if (s == null)
 429             s = "null";
 430         if (s instanceof String)
 431             return this.append((String)s);
 432         if (s instanceof StringBuffer)
 433             return this.append((StringBuffer)s);
 434         return this.append(s, 0, s.length());
 435     }
 436 
 437     /**
 438      * Appends a subsequence of the specified {@code CharSequence} to this
 439      * sequence.
 440      * <p>
 441      * Characters of the argument {@code s}, starting at
 442      * index {@code start}, are appended, in order, to the contents of
 443      * this sequence up to the (exclusive) index {@code end}. The length
 444      * of this sequence is increased by the value of {@code end - start}.
 445      * <p>
 446      * Let <i>n</i> be the length of this character sequence just prior to
 447      * execution of the {@code append} method. Then the character at
 448      * index <i>k</i> in this character sequence becomes equal to the
 449      * character at index <i>k</i> in this sequence, if <i>k</i> is less than
 450      * <i>n</i>; otherwise, it is equal to the character at index
 451      * <i>k+start-n</i> in the argument {@code s}.
 452      * <p>
 453      * If {@code s} is {@code null}, then this method appends
 454      * characters as if the s parameter was a sequence containing the four
 455      * characters {@code "null"}.
 456      *
 457      * @param   s the sequence to append.
 458      * @param   start   the starting index of the subsequence to be appended.
 459      * @param   end     the end index of the subsequence to be appended.
 460      * @return  a reference to this object.
 461      * @throws     IndexOutOfBoundsException if
 462      *             {@code start} is negative, or
 463      *             {@code start} is greater than {@code end} or
 464      *             {@code end} is greater than {@code s.length()}
 465      */
 466     public AbstractStringBuilder append(CharSequence s, int start, int end) {
 467         if (s == null)
 468             s = "null";
 469         if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
 470             throw new IndexOutOfBoundsException(
 471                 "start " + start + ", end " + end + ", s.length() "
 472                 + s.length());
 473         int len = end - start;
 474         if (len == 0)
 475             return this;
 476         int newCount = count + len;
 477         if (newCount > value.length)
 478             expandCapacity(newCount);
 479         for (int i=start; i<end; i++)
 480             value[count++] = s.charAt(i);
 481         count = newCount;
 482         return this;
 483     }
 484 
 485     /**
 486      * Appends the string representation of the {@code char} array
 487      * argument to this sequence.
 488      * <p>
 489      * The characters of the array argument are appended, in order, to
 490      * the contents of this sequence. The length of this sequence
 491      * increases by the length of the argument.
 492      * <p>
 493      * The overall effect is exactly as if the argument were converted
 494      * to a string by the method {@link String#valueOf(char[])},
 495      * and the characters of that string were then
 496      * {@link #append(String) appended} to this character sequence.
 497      *
 498      * @param   str   the characters to be appended.
 499      * @return  a reference to this object.
 500      */
 501     public AbstractStringBuilder append(char[] str) {
 502         int newCount = count + str.length;
 503         if (newCount > value.length)
 504             expandCapacity(newCount);
 505         System.arraycopy(str, 0, value, count, str.length);
 506         count = newCount;
 507         return this;
 508     }
 509 
 510     /**
 511      * Appends the string representation of a subarray of the
 512      * {@code char} array argument to this sequence.
 513      * <p>
 514      * Characters of the {@code char} array {@code str}, starting at
 515      * index {@code offset}, are appended, in order, to the contents
 516      * of this sequence. The length of this sequence increases
 517      * by the value of {@code len}.
 518      * <p>
 519      * The overall effect is exactly as if the arguments were converted
 520      * to a string by the method {@link String#valueOf(char[],int,int)},
 521      * and the characters of that string were then
 522      * {@link #append(String) appended} to this character sequence.
 523      *
 524      * @param   str      the characters to be appended.
 525      * @param   offset   the index of the first {@code char} to append.
 526      * @param   len      the number of {@code char}s to append.
 527      * @return  a reference to this object.
 528      * @throws IndexOutOfBoundsException
 529      *         if {@code offset < 0} or {@code len < 0}
 530      *         or {@code offset+len > str.length}
 531      */
 532     public AbstractStringBuilder append(char str[], int offset, int len) {
 533         int newCount = count + len;
 534         if (newCount > value.length)
 535             expandCapacity(newCount);
 536         System.arraycopy(str, offset, value, count, len);
 537         count = newCount;
 538         return this;
 539     }
 540 
 541     /**
 542      * Appends the string representation of the {@code boolean}
 543      * argument to the sequence.
 544      * <p>
 545      * The overall effect is exactly as if the argument were converted
 546      * to a string by the method {@link String#valueOf(boolean)},
 547      * and the characters of that string were then
 548      * {@link #append(String) appended} to this character sequence.
 549      *
 550      * @param   b   a {@code boolean}.
 551      * @return  a reference to this object.
 552      */
 553     public AbstractStringBuilder append(boolean b) {
 554         if (b) {
 555             int newCount = count + 4;
 556             if (newCount > value.length)
 557                 expandCapacity(newCount);
 558             value[count++] = 't';
 559             value[count++] = 'r';
 560             value[count++] = 'u';
 561             value[count++] = 'e';
 562         } else {
 563             int newCount = count + 5;
 564             if (newCount > value.length)
 565                 expandCapacity(newCount);
 566             value[count++] = 'f';
 567             value[count++] = 'a';
 568             value[count++] = 'l';
 569             value[count++] = 's';
 570             value[count++] = 'e';
 571         }
 572         return this;
 573     }
 574 
 575     /**
 576      * Appends the string representation of the {@code char}
 577      * argument to this sequence.
 578      * <p>
 579      * The argument is appended to the contents of this sequence.
 580      * The length of this sequence increases by {@code 1}.
 581      * <p>
 582      * The overall effect is exactly as if the argument were converted
 583      * to a string by the method {@link String#valueOf(char)},
 584      * and the character in that string were then
 585      * {@link #append(String) appended} to this character sequence.
 586      *
 587      * @param   c   a {@code char}.
 588      * @return  a reference to this object.
 589      */
 590     public AbstractStringBuilder append(char c) {
 591         int newCount = count + 1;
 592         if (newCount > value.length)
 593             expandCapacity(newCount);
 594         value[count++] = c;
 595         return this;
 596     }
 597 
 598     /**
 599      * Appends the string representation of the {@code int}
 600      * argument to this sequence.
 601      * <p>
 602      * The overall effect is exactly as if the argument were converted
 603      * to a string by the method {@link String#valueOf(int)},
 604      * and the characters of that string were then
 605      * {@link #append(String) appended} to this character sequence.
 606      *
 607      * @param   i   an {@code int}.
 608      * @return  a reference to this object.
 609      */
 610     public AbstractStringBuilder append(int i) {
 611         if (i == Integer.MIN_VALUE) {
 612             append("-2147483648");
 613             return this;
 614         }
 615         int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
 616                                      : Integer.stringSize(i);
 617         int spaceNeeded = count + appendedLength;
 618         if (spaceNeeded > value.length)
 619             expandCapacity(spaceNeeded);
 620         Integer.getChars(i, spaceNeeded, value);
 621         count = spaceNeeded;
 622         return this;
 623     }
 624 
 625     /**
 626      * Appends the string representation of the {@code long}
 627      * argument to this sequence.
 628      * <p>
 629      * The overall effect is exactly as if the argument were converted
 630      * to a string by the method {@link String#valueOf(long)},
 631      * and the characters of that string were then
 632      * {@link #append(String) appended} to this character sequence.
 633      *
 634      * @param   l   a {@code long}.
 635      * @return  a reference to this object.
 636      */
 637     public AbstractStringBuilder append(long l) {
 638         if (l == Long.MIN_VALUE) {
 639             append("-9223372036854775808");
 640             return this;
 641         }
 642         int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
 643                                      : Long.stringSize(l);
 644         int spaceNeeded = count + appendedLength;
 645         if (spaceNeeded > value.length)
 646             expandCapacity(spaceNeeded);
 647         Long.getChars(l, spaceNeeded, value);
 648         count = spaceNeeded;
 649         return this;
 650     }
 651 
 652     /**
 653      * Appends the string representation of the {@code float}
 654      * argument to this sequence.
 655      * <p>
 656      * The overall effect is exactly as if the argument were converted
 657      * to a string by the method {@link String#valueOf(float)},
 658      * and the characters of that string were then
 659      * {@link #append(String) appended} to this character sequence.
 660      *
 661      * @param   f   a {@code float}.
 662      * @return  a reference to this object.
 663      */
 664     public AbstractStringBuilder append(float f) {
 665         new FloatingDecimal(f).appendTo(this);
 666         return this;
 667     }
 668 
 669     /**
 670      * Appends the string representation of the {@code double}
 671      * argument to this sequence.
 672      * <p>
 673      * The overall effect is exactly as if the argument were converted
 674      * to a string by the method {@link String#valueOf(double)},
 675      * and the characters of that string were then
 676      * {@link #append(String) appended} to this character sequence.
 677      *
 678      * @param   d   a {@code double}.
 679      * @return  a reference to this object.
 680      */
 681     public AbstractStringBuilder append(double d) {
 682         new FloatingDecimal(d).appendTo(this);
 683         return this;
 684     }
 685 
 686     /**
 687      * Removes the characters in a substring of this sequence.
 688      * The substring begins at the specified {@code start} and extends to
 689      * the character at index {@code end - 1} or to the end of the
 690      * sequence if no such character exists. If
 691      * {@code start} is equal to {@code end}, no changes are made.
 692      *
 693      * @param      start  The beginning index, inclusive.
 694      * @param      end    The ending index, exclusive.
 695      * @return     This object.
 696      * @throws     StringIndexOutOfBoundsException  if {@code start}
 697      *             is negative, greater than {@code length()}, or
 698      *             greater than {@code end}.
 699      */
 700     public AbstractStringBuilder delete(int start, int end) {
 701         if (start < 0)
 702             throw new StringIndexOutOfBoundsException(start);
 703         if (end > count)
 704             end = count;
 705         if (start > end)
 706             throw new StringIndexOutOfBoundsException();
 707         int len = end - start;
 708         if (len > 0) {
 709             System.arraycopy(value, start+len, value, start, count-end);
 710             count -= len;
 711         }
 712         return this;
 713     }
 714 
 715     /**
 716      * Appends the string representation of the {@code codePoint}
 717      * argument to this sequence.
 718      *
 719      * <p> The argument is appended to the contents of this sequence.
 720      * The length of this sequence increases by
 721      * {@link Character#charCount(int) Character.charCount(codePoint)}.
 722      *
 723      * <p> The overall effect is exactly as if the argument were
 724      * converted to a {@code char} array by the method
 725      * {@link Character#toChars(int)} and the character in that array
 726      * were then {@link #append(char[]) appended} to this character
 727      * sequence.
 728      *
 729      * @param   codePoint   a Unicode code point
 730      * @return  a reference to this object.
 731      * @exception IllegalArgumentException if the specified
 732      * {@code codePoint} isn't a valid Unicode code point
 733      */
 734     public AbstractStringBuilder appendCodePoint(int codePoint) {
 735         if (!Character.isValidCodePoint(codePoint)) {
 736             throw new IllegalArgumentException();
 737         }
 738         int n = 1;
 739         if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
 740             n++;
 741         }
 742         int newCount = count + n;
 743         if (newCount > value.length) {
 744             expandCapacity(newCount);
 745         }
 746         if (n == 1) {
 747             value[count++] = (char) codePoint;
 748         } else {
 749             Character.toSurrogates(codePoint, value, count);
 750             count += n;
 751         }
 752         return this;
 753     }
 754 
 755     /**
 756      * Removes the <code>char</code> at the specified position in this
 757      * sequence. This sequence is shortened by one <code>char</code>.
 758      *
 759      * <p>Note: If the character at the given index is a supplementary
 760      * character, this method does not remove the entire character. If
 761      * correct handling of supplementary characters is required,
 762      * determine the number of <code>char</code>s to remove by calling
 763      * <code>Character.charCount(thisSequence.codePointAt(index))</code>,
 764      * where <code>thisSequence</code> is this sequence.
 765      *
 766      * @param       index  Index of <code>char</code> to remove
 767      * @return      This object.
 768      * @throws      StringIndexOutOfBoundsException  if the <code>index</code>
 769      *              is negative or greater than or equal to
 770      *              <code>length()</code>.
 771      */
 772     public AbstractStringBuilder deleteCharAt(int index) {
 773         if ((index < 0) || (index >= count))
 774             throw new StringIndexOutOfBoundsException(index);
 775         System.arraycopy(value, index+1, value, index, count-index-1);
 776         count--;
 777         return this;
 778     }
 779 
 780     /**
 781      * Replaces the characters in a substring of this sequence
 782      * with characters in the specified <code>String</code>. The substring
 783      * begins at the specified <code>start</code> and extends to the character
 784      * at index <code>end - 1</code> or to the end of the
 785      * sequence if no such character exists. First the
 786      * characters in the substring are removed and then the specified
 787      * <code>String</code> is inserted at <code>start</code>. (This
 788      * sequence will be lengthened to accommodate the
 789      * specified String if necessary.)
 790      *
 791      * @param      start    The beginning index, inclusive.
 792      * @param      end      The ending index, exclusive.
 793      * @param      str   String that will replace previous contents.
 794      * @return     This object.
 795      * @throws     StringIndexOutOfBoundsException  if <code>start</code>
 796      *             is negative, greater than <code>length()</code>, or
 797      *             greater than <code>end</code>.
 798      */
 799     public AbstractStringBuilder replace(int start, int end, String str) {
 800         if (start < 0)
 801             throw new StringIndexOutOfBoundsException(start);
 802         if (start > count)
 803             throw new StringIndexOutOfBoundsException("start > length()");
 804         if (start > end)
 805             throw new StringIndexOutOfBoundsException("start > end");
 806 
 807         if (end > count)
 808             end = count;
 809         int len = str.length();
 810         int newCount = count + len - (end - start);
 811         if (newCount > value.length)
 812             expandCapacity(newCount);
 813 
 814         System.arraycopy(value, end, value, start + len, count - end);
 815         str.getChars(value, start);
 816         count = newCount;
 817         return this;
 818     }
 819 
 820     /**
 821      * Returns a new <code>String</code> that contains a subsequence of
 822      * characters currently contained in this character sequence. The
 823      * substring begins at the specified index and extends to the end of
 824      * this sequence.
 825      *
 826      * @param      start    The beginning index, inclusive.
 827      * @return     The new string.
 828      * @throws     StringIndexOutOfBoundsException  if <code>start</code> is
 829      *             less than zero, or greater than the length of this object.
 830      */
 831     public String substring(int start) {
 832         return substring(start, count);
 833     }
 834 
 835     /**
 836      * Returns a new character sequence that is a subsequence of this sequence.
 837      *
 838      * <p> An invocation of this method of the form
 839      *
 840      * <blockquote><pre>
 841      * sb.subSequence(begin,&nbsp;end)</pre></blockquote>
 842      *
 843      * behaves in exactly the same way as the invocation
 844      *
 845      * <blockquote><pre>
 846      * sb.substring(begin,&nbsp;end)</pre></blockquote>
 847      *
 848      * This method is provided so that this class can
 849      * implement the {@link CharSequence} interface. </p>
 850      *
 851      * @param      start   the start index, inclusive.
 852      * @param      end     the end index, exclusive.
 853      * @return     the specified subsequence.
 854      *
 855      * @throws  IndexOutOfBoundsException
 856      *          if <tt>start</tt> or <tt>end</tt> are negative,
 857      *          if <tt>end</tt> is greater than <tt>length()</tt>,
 858      *          or if <tt>start</tt> is greater than <tt>end</tt>
 859      * @spec JSR-51
 860      */
 861     public CharSequence subSequence(int start, int end) {
 862         return substring(start, end);
 863     }
 864 
 865     /**
 866      * Returns a new <code>String</code> that contains a subsequence of
 867      * characters currently contained in this sequence. The
 868      * substring begins at the specified <code>start</code> and
 869      * extends to the character at index <code>end - 1</code>.
 870      *
 871      * @param      start    The beginning index, inclusive.
 872      * @param      end      The ending index, exclusive.
 873      * @return     The new string.
 874      * @throws     StringIndexOutOfBoundsException  if <code>start</code>
 875      *             or <code>end</code> are negative or greater than
 876      *             <code>length()</code>, or <code>start</code> is
 877      *             greater than <code>end</code>.
 878      */
 879     public String substring(int start, int end) {
 880         if (start < 0)
 881             throw new StringIndexOutOfBoundsException(start);
 882         if (end > count)
 883             throw new StringIndexOutOfBoundsException(end);
 884         if (start > end)
 885             throw new StringIndexOutOfBoundsException(end - start);
 886         return new String(value, start, end - start);
 887     }
 888 
 889     /**
 890      * Inserts the string representation of a subarray of the {@code str}
 891      * array argument into this sequence. The subarray begins at the
 892      * specified {@code offset} and extends {@code len} {@code char}s.
 893      * The characters of the subarray are inserted into this sequence at
 894      * the position indicated by {@code index}. The length of this
 895      * sequence increases by {@code len} {@code char}s.
 896      *
 897      * @param      index    position at which to insert subarray.
 898      * @param      str       A {@code char} array.
 899      * @param      offset   the index of the first {@code char} in subarray to
 900      *             be inserted.
 901      * @param      len      the number of {@code char}s in the subarray to
 902      *             be inserted.
 903      * @return     This object
 904      * @throws     StringIndexOutOfBoundsException  if {@code index}
 905      *             is negative or greater than {@code length()}, or
 906      *             {@code offset} or {@code len} are negative, or
 907      *             {@code (offset+len)} is greater than
 908      *             {@code str.length}.
 909      */
 910     public AbstractStringBuilder insert(int index, char[] str, int offset,
 911                                         int len)
 912     {
 913         if ((index < 0) || (index > length()))
 914             throw new StringIndexOutOfBoundsException(index);
 915         if ((offset < 0) || (len < 0) || (offset > str.length - len))
 916             throw new StringIndexOutOfBoundsException(
 917                 "offset " + offset + ", len " + len + ", str.length "
 918                 + str.length);
 919         int newCount = count + len;
 920         if (newCount > value.length)
 921             expandCapacity(newCount);
 922         System.arraycopy(value, index, value, index + len, count - index);
 923         System.arraycopy(str, offset, value, index, len);
 924         count = newCount;
 925         return this;
 926     }
 927 
 928     /**
 929      * Inserts the string representation of the {@code Object}
 930      * argument into this character sequence.
 931      * <p>
 932      * The overall effect is exactly as if the second argument were
 933      * converted to a string by the method {@link String#valueOf(Object)},
 934      * and the characters of that string were then
 935      * {@link #insert(int,String) inserted} into this character
 936      * sequence at the indicated offset.
 937      * <p>
 938      * The {@code offset} argument must be greater than or equal to
 939      * {@code 0}, and less than or equal to the {@linkplain #length() length}
 940      * of this sequence.
 941      *
 942      * @param      offset   the offset.
 943      * @param      obj      an {@code Object}.
 944      * @return     a reference to this object.
 945      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
 946      */
 947     public AbstractStringBuilder insert(int offset, Object obj) {
 948         return insert(offset, String.valueOf(obj));
 949     }
 950 
 951     /**
 952      * Inserts the string into this character sequence.
 953      * <p>
 954      * The characters of the {@code String} argument are inserted, in
 955      * order, into this sequence at the indicated offset, moving up any
 956      * characters originally above that position and increasing the length
 957      * of this sequence by the length of the argument. If
 958      * {@code str} is {@code null}, then the four characters
 959      * {@code "null"} are inserted into this sequence.
 960      * <p>
 961      * The character at index <i>k</i> in the new character sequence is
 962      * equal to:
 963      * <ul>
 964      * <li>the character at index <i>k</i> in the old character sequence, if
 965      * <i>k</i> is less than {@code offset}
 966      * <li>the character at index <i>k</i>{@code -offset} in the
 967      * argument {@code str}, if <i>k</i> is not less than
 968      * {@code offset} but is less than {@code offset+str.length()}
 969      * <li>the character at index <i>k</i>{@code -str.length()} in the
 970      * old character sequence, if <i>k</i> is not less than
 971      * {@code offset+str.length()}
 972      * </ul><p>
 973      * The {@code offset} argument must be greater than or equal to
 974      * {@code 0}, and less than or equal to the {@linkplain #length() length}
 975      * of this sequence.
 976      *
 977      * @param      offset   the offset.
 978      * @param      str      a string.
 979      * @return     a reference to this object.
 980      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
 981      */
 982     public AbstractStringBuilder insert(int offset, String str) {
 983         if ((offset < 0) || (offset > length()))
 984             throw new StringIndexOutOfBoundsException(offset);
 985         if (str == null)
 986             str = "null";
 987         int len = str.length();
 988         int newCount = count + len;
 989         if (newCount > value.length)
 990             expandCapacity(newCount);
 991         System.arraycopy(value, offset, value, offset + len, count - offset);
 992         str.getChars(value, offset);
 993         count = newCount;
 994         return this;
 995     }
 996 
 997     /**
 998      * Inserts the string representation of the {@code char} array
 999      * argument into this sequence.
1000      * <p>
1001      * The characters of the array argument are inserted into the
1002      * contents of this sequence at the position indicated by
1003      * {@code offset}. The length of this sequence increases by
1004      * the length of the argument.
1005      * <p>
1006      * The overall effect is exactly as if the second argument were
1007      * converted to a string by the method {@link String#valueOf(char[])},
1008      * and the characters of that string were then
1009      * {@link #insert(int,String) inserted} into this character
1010      * sequence at the indicated offset.
1011      * <p>
1012      * The {@code offset} argument must be greater than or equal to
1013      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1014      * of this sequence.
1015      *
1016      * @param      offset   the offset.
1017      * @param      str      a character array.
1018      * @return     a reference to this object.
1019      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1020      */
1021     public AbstractStringBuilder insert(int offset, char[] str) {
1022         if ((offset < 0) || (offset > length()))
1023             throw new StringIndexOutOfBoundsException(offset);
1024         int len = str.length;
1025         int newCount = count + len;
1026         if (newCount > value.length)
1027             expandCapacity(newCount);
1028         System.arraycopy(value, offset, value, offset + len, count - offset);
1029         System.arraycopy(str, 0, value, offset, len);
1030         count = newCount;
1031         return this;
1032     }
1033 
1034     /**
1035      * Inserts the specified {@code CharSequence} into this sequence.
1036      * <p>
1037      * The characters of the {@code CharSequence} argument are inserted,
1038      * in order, into this sequence at the indicated offset, moving up
1039      * any characters originally above that position and increasing the length
1040      * of this sequence by the length of the argument s.
1041      * <p>
1042      * The result of this method is exactly the same as if it were an
1043      * invocation of this object's
1044      * {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length())
1045      * method.
1046      *
1047      * <p>If {@code s} is {@code null}, then the four characters
1048      * {@code "null"} are inserted into this sequence.
1049      *
1050      * @param      dstOffset   the offset.
1051      * @param      s the sequence to be inserted
1052      * @return     a reference to this object.
1053      * @throws     IndexOutOfBoundsException  if the offset is invalid.
1054      */
1055     public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
1056         if (s == null)
1057             s = "null";
1058         if (s instanceof String)
1059             return this.insert(dstOffset, (String)s);
1060         return this.insert(dstOffset, s, 0, s.length());
1061     }
1062 
1063     /**
1064      * Inserts a subsequence of the specified {@code CharSequence} into
1065      * this sequence.
1066      * <p>
1067      * The subsequence of the argument {@code s} specified by
1068      * {@code start} and {@code end} are inserted,
1069      * in order, into this sequence at the specified destination offset, moving
1070      * up any characters originally above that position. The length of this
1071      * sequence is increased by {@code end - start}.
1072      * <p>
1073      * The character at index <i>k</i> in this sequence becomes equal to:
1074      * <ul>
1075      * <li>the character at index <i>k</i> in this sequence, if
1076      * <i>k</i> is less than {@code dstOffset}
1077      * <li>the character at index <i>k</i>{@code +start-dstOffset} in
1078      * the argument {@code s}, if <i>k</i> is greater than or equal to
1079      * {@code dstOffset} but is less than {@code dstOffset+end-start}
1080      * <li>the character at index <i>k</i>{@code -(end-start)} in this
1081      * sequence, if <i>k</i> is greater than or equal to
1082      * {@code dstOffset+end-start}
1083      * </ul><p>
1084      * The {@code dstOffset} argument must be greater than or equal to
1085      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1086      * of this sequence.
1087      * <p>The start argument must be nonnegative, and not greater than
1088      * {@code end}.
1089      * <p>The end argument must be greater than or equal to
1090      * {@code start}, and less than or equal to the length of s.
1091      *
1092      * <p>If {@code s} is {@code null}, then this method inserts
1093      * characters as if the s parameter was a sequence containing the four
1094      * characters {@code "null"}.
1095      *
1096      * @param      dstOffset   the offset in this sequence.
1097      * @param      s       the sequence to be inserted.
1098      * @param      start   the starting index of the subsequence to be inserted.
1099      * @param      end     the end index of the subsequence to be inserted.
1100      * @return     a reference to this object.
1101      * @throws     IndexOutOfBoundsException  if {@code dstOffset}
1102      *             is negative or greater than {@code this.length()}, or
1103      *              {@code start} or {@code end} are negative, or
1104      *              {@code start} is greater than {@code end} or
1105      *              {@code end} is greater than {@code s.length()}
1106      */
1107      public AbstractStringBuilder insert(int dstOffset, CharSequence s,
1108                                          int start, int end) {
1109         if (s == null)
1110             s = "null";
1111         if ((dstOffset < 0) || (dstOffset > this.length()))
1112             throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
1113         if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
1114             throw new IndexOutOfBoundsException(
1115                 "start " + start + ", end " + end + ", s.length() "
1116                 + s.length());
1117         int len = end - start;
1118         if (len == 0)
1119             return this;
1120         int newCount = count + len;
1121         if (newCount > value.length)
1122             expandCapacity(newCount);
1123         System.arraycopy(value, dstOffset, value, dstOffset + len,
1124                          count - dstOffset);
1125         for (int i=start; i<end; i++)
1126             value[dstOffset++] = s.charAt(i);
1127         count = newCount;
1128         return this;
1129     }
1130 
1131     /**
1132      * Inserts the string representation of the {@code boolean}
1133      * argument into this sequence.
1134      * <p>
1135      * The overall effect is exactly as if the second argument were
1136      * converted to a string by the method {@link String#valueOf(boolean)},
1137      * and the characters of that string were then
1138      * {@link #insert(int,String) inserted} into this character
1139      * sequence at the indicated offset.
1140      * <p>
1141      * The {@code offset} argument must be greater than or equal to
1142      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1143      * of this sequence.
1144      *
1145      * @param      offset   the offset.
1146      * @param      b        a {@code boolean}.
1147      * @return     a reference to this object.
1148      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1149      */
1150     public AbstractStringBuilder insert(int offset, boolean b) {
1151         return insert(offset, String.valueOf(b));
1152     }
1153 
1154     /**
1155      * Inserts the string representation of the {@code char}
1156      * argument into this sequence.
1157      * <p>
1158      * The overall effect is exactly as if the second argument were
1159      * converted to a string by the method {@link String#valueOf(char)},
1160      * and the character in that string were then
1161      * {@link #insert(int,String) inserted} into this character
1162      * sequence at the indicated offset.
1163      * <p>
1164      * The {@code offset} argument must be greater than or equal to
1165      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1166      * of this sequence.
1167      *
1168      * @param      offset   the offset.
1169      * @param      c        a {@code char}.
1170      * @return     a reference to this object.
1171      * @throws     IndexOutOfBoundsException  if the offset is invalid.
1172      */
1173     public AbstractStringBuilder insert(int offset, char c) {
1174         int newCount = count + 1;
1175         if (newCount > value.length)
1176             expandCapacity(newCount);
1177         System.arraycopy(value, offset, value, offset + 1, count - offset);
1178         value[offset] = c;
1179         count = newCount;
1180         return this;
1181     }
1182 
1183     /**
1184      * Inserts the string representation of the second {@code int}
1185      * argument into this sequence.
1186      * <p>
1187      * The overall effect is exactly as if the second argument were
1188      * converted to a string by the method {@link String#valueOf(int)},
1189      * and the characters of that string were then
1190      * {@link #insert(int,String) inserted} into this character
1191      * sequence at the indicated offset.
1192      * <p>
1193      * The {@code offset} argument must be greater than or equal to
1194      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1195      * of this sequence.
1196      *
1197      * @param      offset   the offset.
1198      * @param      i        an {@code int}.
1199      * @return     a reference to this object.
1200      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1201      */
1202     public AbstractStringBuilder insert(int offset, int i) {
1203         return insert(offset, String.valueOf(i));
1204     }
1205 
1206     /**
1207      * Inserts the string representation of the {@code long}
1208      * argument into this sequence.
1209      * <p>
1210      * The overall effect is exactly as if the second argument were
1211      * converted to a string by the method {@link String#valueOf(long)},
1212      * and the characters of that string were then
1213      * {@link #insert(int,String) inserted} into this character
1214      * sequence at the indicated offset.
1215      * <p>
1216      * The {@code offset} argument must be greater than or equal to
1217      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1218      * of this sequence.
1219      *
1220      * @param      offset   the offset.
1221      * @param      l        a {@code long}.
1222      * @return     a reference to this object.
1223      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1224      */
1225     public AbstractStringBuilder insert(int offset, long l) {
1226         return insert(offset, String.valueOf(l));
1227     }
1228 
1229     /**
1230      * Inserts the string representation of the {@code float}
1231      * argument into this sequence.
1232      * <p>
1233      * The overall effect is exactly as if the second argument were
1234      * converted to a string by the method {@link String#valueOf(float)},
1235      * and the characters of that string were then
1236      * {@link #insert(int,String) inserted} into this character
1237      * sequence at the indicated offset.
1238      * <p>
1239      * The {@code offset} argument must be greater than or equal to
1240      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1241      * of this sequence.
1242      *
1243      * @param      offset   the offset.
1244      * @param      f        a {@code float}.
1245      * @return     a reference to this object.
1246      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1247      */
1248     public AbstractStringBuilder insert(int offset, float f) {
1249         return insert(offset, String.valueOf(f));
1250     }
1251 
1252     /**
1253      * Inserts the string representation of the {@code double}
1254      * argument into this sequence.
1255      * <p>
1256      * The overall effect is exactly as if the second argument were
1257      * converted to a string by the method {@link String#valueOf(double)},
1258      * and the characters of that string were then
1259      * {@link #insert(int,String) inserted} into this character
1260      * sequence at the indicated offset.
1261      * <p>
1262      * The {@code offset} argument must be greater than or equal to
1263      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1264      * of this sequence.
1265      *
1266      * @param      offset   the offset.
1267      * @param      d        a {@code double}.
1268      * @return     a reference to this object.
1269      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1270      */
1271     public AbstractStringBuilder insert(int offset, double d) {
1272         return insert(offset, String.valueOf(d));
1273     }
1274 
1275     /**
1276      * Returns the index within this string of the first occurrence of the
1277      * specified substring. The integer returned is the smallest value
1278      * <i>k</i> such that:
1279      * <blockquote><pre>
1280      * this.toString().startsWith(str, <i>k</i>)
1281      * </pre></blockquote>
1282      * is <code>true</code>.
1283      *
1284      * @param   str   any string.
1285      * @return  if the string argument occurs as a substring within this
1286      *          object, then the index of the first character of the first
1287      *          such substring is returned; if it does not occur as a
1288      *          substring, <code>-1</code> is returned.
1289      * @throws  java.lang.NullPointerException if <code>str</code> is
1290      *          <code>null</code>.
1291      */
1292     public int indexOf(String str) {
1293         return indexOf(str, 0);
1294     }
1295 
1296     /**
1297      * Returns the index within this string of the first occurrence of the
1298      * specified substring, starting at the specified index.  The integer
1299      * returned is the smallest value <tt>k</tt> for which:
1300      * <blockquote><pre>
1301      *     k >= Math.min(fromIndex, str.length()) &&
1302      *                   this.toString().startsWith(str, k)
1303      * </pre></blockquote>
1304      * If no such value of <i>k</i> exists, then -1 is returned.
1305      *
1306      * @param   str         the substring for which to search.
1307      * @param   fromIndex   the index from which to start the search.
1308      * @return  the index within this string of the first occurrence of the
1309      *          specified substring, starting at the specified index.
1310      * @throws  java.lang.NullPointerException if <code>str</code> is
1311      *            <code>null</code>.
1312      */
1313     public int indexOf(String str, int fromIndex) {
1314         return String.indexOf(value, 0, count,
1315                               str.toCharArray(), 0, str.length(), fromIndex);
1316     }
1317 
1318     /**
1319      * Returns the index within this string of the rightmost occurrence
1320      * of the specified substring.  The rightmost empty string "" is
1321      * considered to occur at the index value <code>this.length()</code>.
1322      * The returned index is the largest value <i>k</i> such that
1323      * <blockquote><pre>
1324      * this.toString().startsWith(str, k)
1325      * </pre></blockquote>
1326      * is true.
1327      *
1328      * @param   str   the substring to search for.
1329      * @return  if the string argument occurs one or more times as a substring
1330      *          within this object, then the index of the first character of
1331      *          the last such substring is returned. If it does not occur as
1332      *          a substring, <code>-1</code> is returned.
1333      * @throws  java.lang.NullPointerException  if <code>str</code> is
1334      *          <code>null</code>.
1335      */
1336     public int lastIndexOf(String str) {
1337         return lastIndexOf(str, count);
1338     }
1339 
1340     /**
1341      * Returns the index within this string of the last occurrence of the
1342      * specified substring. The integer returned is the largest value <i>k</i>
1343      * such that:
1344      * <blockquote><pre>
1345      *     k <= Math.min(fromIndex, str.length()) &&
1346      *                   this.toString().startsWith(str, k)
1347      * </pre></blockquote>
1348      * If no such value of <i>k</i> exists, then -1 is returned.
1349      *
1350      * @param   str         the substring to search for.
1351      * @param   fromIndex   the index to start the search from.
1352      * @return  the index within this sequence of the last occurrence of the
1353      *          specified substring.
1354      * @throws  java.lang.NullPointerException if <code>str</code> is
1355      *          <code>null</code>.
1356      */
1357     public int lastIndexOf(String str, int fromIndex) {
1358         return String.lastIndexOf(value, 0, count,
1359                               str.toCharArray(), 0, str.length(), fromIndex);
1360     }
1361 
1362     /**
1363      * Causes this character sequence to be replaced by the reverse of
1364      * the sequence. If there are any surrogate pairs included in the
1365      * sequence, these are treated as single characters for the
1366      * reverse operation. Thus, the order of the high-low surrogates
1367      * is never reversed.
1368      *
1369      * Let <i>n</i> be the character length of this character sequence
1370      * (not the length in <code>char</code> values) just prior to
1371      * execution of the <code>reverse</code> method. Then the
1372      * character at index <i>k</i> in the new character sequence is
1373      * equal to the character at index <i>n-k-1</i> in the old
1374      * character sequence.
1375      *
1376      * <p>Note that the reverse operation may result in producing
1377      * surrogate pairs that were unpaired low-surrogates and
1378      * high-surrogates before the operation. For example, reversing
1379      * "&#92;uDC00&#92;uD800" produces "&#92;uD800&#92;uDC00" which is
1380      * a valid surrogate pair.
1381      *
1382      * @return  a reference to this object.
1383      */
1384     public AbstractStringBuilder reverse() {
1385         boolean hasSurrogate = false;
1386         int n = count - 1;
1387         for (int j = (n-1) >> 1; j >= 0; --j) {
1388             char temp = value[j];
1389             char temp2 = value[n - j];
1390             if (!hasSurrogate) {
1391                 hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
1392                     || (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
1393             }
1394             value[j] = temp2;
1395             value[n - j] = temp;
1396         }
1397         if (hasSurrogate) {
1398             // Reverse back all valid surrogate pairs
1399             for (int i = 0; i < count - 1; i++) {
1400                 char c2 = value[i];
1401                 if (Character.isLowSurrogate(c2)) {
1402                     char c1 = value[i + 1];
1403                     if (Character.isHighSurrogate(c1)) {
1404                         value[i++] = c1;
1405                         value[i] = c2;
1406                     }
1407                 }
1408             }
1409         }
1410         return this;
1411     }
1412 
1413     /**
1414      * Append to this sequence a composition of the values returned
1415      * by calling {@link String#valueOf(Object)} on each argument and joining them together
1416      * with the delimiter parameter.
1417      * 
1418      * @param delimiter the String appended between each elements.
1419      * @param first the first element to append.
1420      * @param elements  the other Object elements to join together with the first one.
1421      * @return a reference to this object.
1422      * 
1423      * @throws  NullPointerException
1424      *          If <tt>delimiter</tt> or <tt>elements</tt> is <tt>null</tt>
1425      * 
1426      * @since 1.7
1427      */
1428     public AbstractStringBuilder join(String delimiter, Object first, Object... elements) {
1429         if (delimiter == null) {
1430             throw new NullPointerException("delimiter is null");
1431         }
1432         append(first);
1433         for(Object o : elements) {
1434             append(delimiter).append(o);
1435         }
1436         return this;
1437     }
1438 
1439     /**
1440      * Append to this sequence a composition of the values returned
1441      * by calling {@link String#valueOf(Object)} on each array element
1442      * and joining them together with the delimiter parameter.
1443      * 
1444      * @param delimiter the String appended between each elements.
1445      * @param elements an array of Object element to join together.
1446      * @return a reference to this object.
1447      * 
1448      * @throws  NullPointerException
1449      *          If <tt>delimiter</tt> or <tt>elements</tt> is <tt>null</tt>
1450      * 
1451      * @since 1.7
1452      */
1453      public AbstractStringBuilder join(String delimiter, Object[] elements) {
1454         if (delimiter == null) {
1455             throw new NullPointerException("delimiter is null");
1456         }
1457         int length = elements.length;
1458         if (length == 0) {
1459             return this;
1460         }
1461         append(elements[0]);
1462         for(int i=1; i<length; i++) {
1463             append(delimiter).append(elements[i]);
1464         }
1465         return this;
1466      }
1467 
1468     /**
1469      * Append to this sequence a composition of the values returned
1470      * by calling {@link String#valueOf(Object)} on each argument and joining them together
1471      * with the delimiter parameter.
1472      * 
1473      * @param delimiter the String appended between each elements.
1474      * @param elements an Iterable that will have its elements joined together.
1475      * @return a reference to this object.
1476      * 
1477      * @throws  NullPointerException
1478      *          If <tt>delimiter</tt> or <tt>elements</tt> is <tt>null</tt>
1479      * 
1480      * @since 1.7
1481      */
1482     public AbstractStringBuilder join(String delimiter, Iterable<?> elements) {
1483         if (delimiter == null) {
1484             throw new NullPointerException("delimiter is null");
1485         }
1486         Iterator<?> iterator = elements.iterator();
1487         if (!iterator.hasNext()) {
1488             return this;
1489         }
1490         append(iterator.next());
1491         while(iterator.hasNext()) {
1492             append(delimiter).append(iterator.next());
1493         }
1494         return this;
1495     }
1496     
1497     /**
1498      * Returns a string representing the data in this sequence.
1499      * A new <code>String</code> object is allocated and initialized to
1500      * contain the character sequence currently represented by this
1501      * object. This <code>String</code> is then returned. Subsequent
1502      * changes to this sequence do not affect the contents of the
1503      * <code>String</code>.
1504      *
1505      * @return  a string representation of this sequence of characters.
1506      */
1507     public abstract String toString();
1508 
1509     /**
1510      * Needed by <tt>String</tt> for the contentEquals method.
1511      */
1512     final char[] getValue() {
1513         return value;
1514     }
1515 
1516 }