/* String.java -- immutable character sequences; the object of string literals
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.lang;

import gnu.java.lang.CharData;
import gnu.java.lang.CPStringBuilder;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.text.Collator;
import java.util.Comparator;
import java.util.Formatter;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * Strings represent an immutable set of characters.  All String literals
 * are instances of this class, and two string literals with the same contents
 * refer to the same String object.
 *
 * <p>This class also includes a number of methods for manipulating the
 * contents of strings (of course, creating a new object if there are any
 * changes, as String is immutable). Case mapping relies on Unicode 3.0.0
 * standards, where some character sequences have a different number of
 * characters in the uppercase version than the lower case.
 *
 * <p>Strings are special, in that they are the only object with an overloaded
 * operator. When you use '+' with at least one String argument, both
 * arguments have String conversion performed on them, and another String (not
 * guaranteed to be unique) results.
 *
 * <p>String is special-cased when doing data serialization - rather than
 * listing the fields of this class, a String object is converted to a string
 * literal in the object stream.
 *
 * @author Paul N. Fisher
 * @author Eric Blake (ebb9@email.byu.edu)
 * @author Per Bothner (bothner@cygnus.com)
 * @author Tom Tromey (tromey@redhat.com)
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.0
 * @status updated to 1.4; but could use better data sharing via offset field
 */
public final class String
  implements Serializable, Comparable<String>, CharSequence
{
  // WARNING: String is a CORE class in the bootstrap cycle. See the comments
  // in vm/reference/java/lang/Runtime for implications of this fact.

  /**
   * This is probably not necessary because this class is special cased already
   * but it will avoid showing up as a discrepancy when comparing SUIDs.
   */
  private static final long serialVersionUID = -6849794470754667710L;

  /**
   * Stores unicode multi-character uppercase expansion table.
   * @see #toUpperCase(Locale)
   * @see CharData#UPPER_EXPAND
   */
  private static final char[] upperExpand
	= zeroBasedStringValue(CharData.UPPER_EXPAND);

  /**
   * Stores unicode multi-character uppercase special casing table.
   * @see #upperCaseExpansion(char)
   * @see CharData#UPPER_SPECIAL
   */
  private static final char[] upperSpecial
	  = zeroBasedStringValue(CharData.UPPER_SPECIAL);
  
  /**
   * Characters which make up the String.
   * Package access is granted for use by StringBuffer.
   */
  final char[] value;

  /**
   * Holds the number of characters in value.  This number is generally
   * the same as value.length, but can be smaller because substrings and
   * StringBuffers can share arrays. Package visible for use by trusted code.
   */
  final int count;

  /**
   * Caches the result of hashCode().  If this value is zero, the hashcode
   * is considered uncached (even if 0 is the correct hash value).
   */
  private int cachedHashCode;

  /**
   * Holds the starting position for characters in value[].  Since
   * substring()'s are common, the use of offset allows the operation
   * to perform in O(1). Package access is granted for use by StringBuffer.
   */
  final int offset;

  /**
   * An implementation for {@link #CASE_INSENSITIVE_ORDER}.
   * This must be {@link Serializable}. The class name is dictated by
   * compatibility with Sun's JDK.
   */
  private static final class CaseInsensitiveComparator
    implements Comparator<String>, Serializable
  {
    /**
     * Compatible with JDK 1.2.
     */
    private static final long serialVersionUID = 8575799808933029326L;

    /**
     * The default private constructor generates unnecessary overhead.
     */
    CaseInsensitiveComparator() {}

    /**
     * Compares to Strings, using
     * <code>String.compareToIgnoreCase(String)</code>.
     *
     * @param o1 the first string
     * @param o2 the second string
     * @return &lt; 0, 0, or &gt; 0 depending on the case-insensitive
     *         comparison of the two strings.
     * @throws NullPointerException if either argument is null
     * @throws ClassCastException if either argument is not a String
     * @see #compareToIgnoreCase(String)
     */
    public int compare(String o1, String o2)
    {
      return o1.compareToIgnoreCase(o2);
    }
  } // class CaseInsensitiveComparator

  /**
   * A Comparator that uses <code>String.compareToIgnoreCase(String)</code>.
   * This comparator is {@link Serializable}. Note that it ignores Locale,
   * for that, you want a Collator.
   *
   * @see Collator#compare(String, String)
   * @since 1.2
   */
  public static final Comparator<String> CASE_INSENSITIVE_ORDER
    = new CaseInsensitiveComparator();

  /**
   * Creates an empty String (length 0). Unless you really need a new object,
   * consider using <code>""</code> instead.
   */
  public String()
  {
    value = "".value;
    offset = 0;
    count = 0;
  }

  /**
   * Copies the contents of a String to a new String. Since Strings are
   * immutable, only a shallow copy is performed.
   *
   * @param str String to copy
   * @throws NullPointerException if value is null
   */
  public String(String str)
  {
    value = str.value;
    offset = str.offset;
    count = str.count;
    cachedHashCode = str.cachedHashCode;
  }

  /**
   * Creates a new String using the character sequence of the char array.
   * Subsequent changes to data do not affect the String.
   *
   * @param data char array to copy
   * @throws NullPointerException if data is null
   */
  public String(char[] data)
  {
    this(data, 0, data.length, false);
  }

  /**
   * Creates a new String using the character sequence of a subarray of
   * characters. The string starts at offset, and copies count chars.
   * Subsequent changes to data do not affect the String.
   *
   * @param data char array to copy
   * @param offset position (base 0) to start copying out of data
   * @param count the number of characters from data to copy
   * @throws NullPointerException if data is null
   * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
   *         || offset + count &lt; 0 (overflow)
   *         || offset + count &gt; data.length)
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
   */
  public String(char[] data, int offset, int count)
  {
    this(data, offset, count, false);
  }

  /**
   * Creates a new String using an 8-bit array of integer values, starting at
   * an offset, and copying up to the count. Each character c, using
   * corresponding byte b, is created in the new String as if by performing:
   *
   * <pre>
   * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
   * </pre>
   *
   * @param ascii array of integer values
   * @param hibyte top byte of each Unicode character
   * @param offset position (base 0) to start copying out of ascii
   * @param count the number of characters from ascii to copy
   * @throws NullPointerException if ascii is null
   * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
   *         || offset + count &lt; 0 (overflow)
   *         || offset + count &gt; ascii.length)
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
   * @see #String(byte[])
   * @see #String(byte[], String)
   * @see #String(byte[], int, int)
   * @see #String(byte[], int, int, String)
   * @deprecated use {@link #String(byte[], int, int, String)} to perform
   *             correct encoding
   */
  public String(byte[] ascii, int hibyte, int offset, int count)
  {
    if (offset < 0)
      throw new StringIndexOutOfBoundsException("offset: " + offset);
    if (count < 0)
      throw new StringIndexOutOfBoundsException("count: " + count);
    // equivalent to: offset + count < 0 || offset + count > ascii.length
    if (ascii.length - offset < count)
      throw new StringIndexOutOfBoundsException("offset + count: "
						+ (offset + count));
    value = new char[count];
    this.offset = 0;
    this.count = count;
    hibyte <<= 8;
    offset += count;
    while (--count >= 0)
      value[count] = (char) (hibyte | (ascii[--offset] & 0xff));
  }

  /**
   * Creates a new String using an 8-bit array of integer values. Each
   * character c, using corresponding byte b, is created in the new String
   * as if by performing:
   *
   * <pre>
   * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
   * </pre>
   *
   * @param ascii array of integer values
   * @param hibyte top byte of each Unicode character
   * @throws NullPointerException if ascii is null
   * @see #String(byte[])
   * @see #String(byte[], String)
   * @see #String(byte[], int, int)
   * @see #String(byte[], int, int, String)
   * @see #String(byte[], int, int, int)
   * @deprecated use {@link #String(byte[], String)} to perform
   *             correct encoding
   */
  public String(byte[] ascii, int hibyte)
  {
    this(ascii, hibyte, 0, ascii.length);
  }

  /**
   * Creates a new String using the portion of the byte array starting at the
   * offset and ending at offset + count. Uses the specified encoding type
   * to decode the byte array, so the resulting string may be longer or
   * shorter than the byte array. For more decoding control, use
   * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
   * see {@link java.nio.charset.Charset}. The behavior is not specified if
   * the decoder encounters invalid characters; this implementation throws
   * an Error.
   *
   * @param data byte array to copy
   * @param offset the offset to start at
   * @param count the number of bytes in the array to use
   * @param encoding the name of the encoding to use
   * @throws NullPointerException if data or encoding is null
   * @throws IndexOutOfBoundsException if offset or count is incorrect
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
   * @throws UnsupportedEncodingException if encoding is not found
   * @throws Error if the decoding fails
   * @since 1.1
   */
  public String(byte[] data, int offset, int count, final String encoding)
    throws UnsupportedEncodingException
  {
    this(data, offset, count, stringToCharset(encoding));
  }

  /**
   * Wrapper method to convert exceptions resulting from
   * the selection of a {@link java.nio.charset.Charset} based on
   * a String.
   *
   * @throws UnsupportedEncodingException if encoding is not found
   */
  private static final Charset stringToCharset(final String encoding)
    throws UnsupportedEncodingException
  {
    try
      {
	return Charset.forName(encoding);
      }
    catch(IllegalCharsetNameException e)
      {
	throw new UnsupportedEncodingException("Encoding: "+encoding+
					       " not found.");
      }
    catch(UnsupportedCharsetException e)
      {
	throw new UnsupportedEncodingException("Encoding: "+encoding+
					       " not found.");
      }    
  }

  /**
   * Creates a new String using the portion of the byte array starting at the
   * offset and ending at offset + count. Uses the specified encoding type
   * to decode the byte array, so the resulting string may be longer or
   * shorter than the byte array. For more decoding control, use
   * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
   * see {@link java.nio.charset.Charset}. Malformed input and unmappable
   * character sequences are replaced with the default replacement string
   * provided by the {@link java.nio.charset.Charset}.
   *
   * @param data byte array to copy
   * @param offset the offset to start at
   * @param count the number of bytes in the array to use
   * @param encoding the encoding to use
   * @throws NullPointerException if data or encoding is null
   * @throws IndexOutOfBoundsException if offset or count is incorrect
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
   * @since 1.6
   */
  public String(byte[] data, int offset, int count, Charset encoding)
  {
    if (offset < 0)
      throw new StringIndexOutOfBoundsException("offset: " + offset);
    if (count < 0)
      throw new StringIndexOutOfBoundsException("count: " + count);
    // equivalent to: offset + count < 0 || offset + count > data.length
    if (data.length - offset < count)
      throw new StringIndexOutOfBoundsException("offset + count: "
						+ (offset + count));
    try 
      {
        CharsetDecoder csd = encoding.newDecoder();
	csd.onMalformedInput(CodingErrorAction.REPLACE);
	csd.onUnmappableCharacter(CodingErrorAction.REPLACE);
	CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count));
 	if(cbuf.hasArray())
 	  {
 	    value = cbuf.array();
	    this.offset = cbuf.position();
	    this.count = cbuf.remaining();
 	  } else {
	    // Doubt this will happen. But just in case.
	    value = new char[cbuf.remaining()];
	    cbuf.get(value);
	    this.offset = 0;
	    this.count = value.length;
	  }
      } 
    catch(CharacterCodingException e)
      {
	// This shouldn't ever happen.
	throw (InternalError) new InternalError().initCause(e);
      }	  
  }

  /**
   * Creates a new String using the byte array. Uses the specified encoding
   * type to decode the byte array, so the resulting string may be longer or
   * shorter than the byte array. For more decoding control, use
   * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
   * see {@link java.nio.charset.Charset}. The behavior is not specified if
   * the decoder encounters invalid characters; this implementation throws
   * an Error.
   *
   * @param data byte array to copy
   * @param encoding the name of the encoding to use
   * @throws NullPointerException if data or encoding is null
   * @throws UnsupportedEncodingException if encoding is not found
   * @throws Error if the decoding fails
   * @see #String(byte[], int, int, String)
   * @since 1.1
   */
  public String(byte[] data, String encoding)
    throws UnsupportedEncodingException
  {
    this(data, 0, data.length, encoding);
  }

  /**
   * Creates a new String using the byte array. Uses the specified encoding
   * type to decode the byte array, so the resulting string may be longer or
   * shorter than the byte array. For more decoding control, use
   * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
   * see {@link java.nio.charset.Charset}. Malformed input and unmappable
   * character sequences are replaced with the default replacement string
   * provided by the {@link java.nio.charset.Charset}.
   *
   * @param data byte array to copy
   * @param encoding the name of the encoding to use
   * @throws NullPointerException if data or encoding is null
   * @see #String(byte[], int, int, java.nio.Charset)
   * @since 1.6
   */
  public String(byte[] data, Charset encoding)
  {
    this(data, 0, data.length, encoding);
  }

  /**
   * Creates a new String using the portion of the byte array starting at the
   * offset and ending at offset + count. Uses the encoding of the platform's
   * default charset, so the resulting string may be longer or shorter than
   * the byte array. For more decoding control, use
   * {@link java.nio.charset.CharsetDecoder}.  The behavior is not specified
   * if the decoder encounters invalid characters; this implementation throws
   * an Error.
   *
   * @param data byte array to copy
   * @param offset the offset to start at
   * @param count the number of bytes in the array to use
   * @throws NullPointerException if data is null
   * @throws IndexOutOfBoundsException if offset or count is incorrect
   * @throws Error if the decoding fails
   * @see #String(byte[], int, int, String)
   * @since 1.1
   */
  public String(byte[] data, int offset, int count)
  {
    if (offset < 0)
      throw new StringIndexOutOfBoundsException("offset: " + offset);
    if (count < 0)
      throw new StringIndexOutOfBoundsException("count: " + count);
    // equivalent to: offset + count < 0 || offset + count > data.length
    if (data.length - offset < count)
      throw new StringIndexOutOfBoundsException("offset + count: "
						+ (offset + count));
    int o, c;
    char[] v;
    String encoding;
    try 
	{
	  encoding = System.getProperty("file.encoding");
	  CharsetDecoder csd = Charset.forName(encoding).newDecoder();
	  csd.onMalformedInput(CodingErrorAction.REPLACE);
	  csd.onUnmappableCharacter(CodingErrorAction.REPLACE);
	  CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count));
	  if(cbuf.hasArray())
	    {
              v = cbuf.array();
	      o = cbuf.position();
	      c = cbuf.remaining();
	    } else {
	      // Doubt this will happen. But just in case.
	      v = new char[cbuf.remaining()];
	      cbuf.get(v);
	      o = 0;
	      c = v.length;
	    }
	} catch(Exception ex){
	    // If anything goes wrong (System property not set,
	    // NIO provider not available, etc)
	    // Default to the 'safe' encoding ISO8859_1
	    v = new char[count];
	    o = 0;
	    c = count;
	    for (int i=0;i<count;i++)
	      v[i] = (char)data[offset+i];
	}
    this.value = v;
    this.offset = o;
    this.count = c;
  }

  /**
   * Creates a new String using the byte array. Uses the encoding of the
   * platform's default charset, so the resulting string may be longer or
   * shorter than the byte array. For more decoding control, use
   * {@link java.nio.charset.CharsetDecoder}.  The behavior is not specified
   * if the decoder encounters invalid characters; this implementation throws
   * an Error.
   *
   * @param data byte array to copy
   * @throws NullPointerException if data is null
   * @throws Error if the decoding fails
   * @see #String(byte[], int, int)
   * @see #String(byte[], int, int, String)
   * @since 1.1
   */
  public String(byte[] data)
  {
    this(data, 0, data.length);
  }

  /**
   * Creates a new String using the character sequence represented by
   * the StringBuffer. Subsequent changes to buf do not affect the String.
   *
   * @param buffer StringBuffer to copy
   * @throws NullPointerException if buffer is null
   */
  public String(StringBuffer buffer)
  {
    synchronized (buffer)
      {
        offset = 0;
        count = buffer.count;
        // Share unless buffer is 3/4 empty.
        if ((count << 2) < buffer.value.length)
          {
            value = new char[count];
            VMSystem.arraycopy(buffer.value, 0, value, 0, count);
          }
        else
          {
            buffer.shared = true;
            value = buffer.value;
          }
      }
  }

  /**
   * Creates a new String using the character sequence represented by
   * the StringBuilder. Subsequent changes to buf do not affect the String.
   *
   * @param buffer StringBuilder to copy
   * @throws NullPointerException if buffer is null
   */
  public String(StringBuilder buffer)
  {
    this(buffer.value, 0, buffer.count);
  }

  /**
   * Special constructor which can share an array when safe to do so.
   *
   * @param data the characters to copy
   * @param offset the location to start from
   * @param count the number of characters to use
   * @param dont_copy true if the array is trusted, and need not be copied
   * @throws NullPointerException if chars is null
   * @throws StringIndexOutOfBoundsException if bounds check fails
   */
  String(char[] data, int offset, int count, boolean dont_copy)
  {
    if (offset < 0)
      throw new StringIndexOutOfBoundsException("offset: " + offset);
    if (count < 0)
      throw new StringIndexOutOfBoundsException("count: " + count);
    // equivalent to: offset + count < 0 || offset + count > data.length
    if (data.length - offset < count)
      throw new StringIndexOutOfBoundsException("offset + count: "
						+ (offset + count));
    if (dont_copy)
      {
        value = data;
        this.offset = offset;
      }
    else
      {
        value = new char[count];
        VMSystem.arraycopy(data, offset, value, 0, count);
        this.offset = 0;
      }
    this.count = count;
  }

  /**
   * Creates a new String containing the characters represented in the
   * given subarray of Unicode code points.
   * @param codePoints the entire array of code points
   * @param offset the start of the subarray
   * @param count the length of the subarray
   * 
   * @throws IllegalArgumentException if an invalid code point is found
   * in the codePoints array
   * @throws IndexOutOfBoundsException if offset is negative or offset + count
   * is greater than the length of the array.
   */
  public String(int[] codePoints, int offset, int count)
  {
    // FIXME: This implementation appears to give correct internal
    // representation of the String because: 
    //   - length() is correct
    //   - getting a char[] from toCharArray() and testing 
    //     Character.codePointAt() on all the characters in that array gives
    //     the appropriate results
    // however printing the String gives incorrect results.  This may be 
    // due to printing method errors (such as incorrectly looping through
    // the String one char at a time rather than one "character" at a time.
    
    if (offset < 0)
      throw new IndexOutOfBoundsException();
    int end = offset + count;
    int pos = 0;
    // This creates a char array that is long enough for all of the code
    // points to represent supplementary characters.  This is more than likely
    // a waste of storage, so we use it only temporarily and then copy the 
    // used portion into the value array.
    char[] temp = new char[2 * codePoints.length];
    for (int i = offset; i < end; i++)
      {
        pos += Character.toChars(codePoints[i], temp, pos);        
      }
    this.count = pos;
    this.value = new char[pos];
    System.arraycopy(temp, 0, value, 0, pos);
    this.offset = 0;
  }
  
  /**
   * Returns the number of characters contained in this String.
   *
   * @return the length of this String
   */
  public int length()
  {
    return count;
  }

  /**
   * Returns the character located at the specified index within this String.
   *
   * @param index position of character to return (base 0)
   * @return character located at position index
   * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= length()
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
   */
  public char charAt(int index)
  {
    if (index < 0 || index >= count)
      throw new StringIndexOutOfBoundsException(index);
    return value[offset + index];
  }

  /**
   * Get the code point at the specified index.  This is like #charAt(int),
   * but if the character is the start of a surrogate pair, and the
   * following character completes the pair, then the corresponding
   * supplementary code point is returned.
   * @param index the index of the codepoint to get, starting at 0
   * @return the codepoint at the specified index
   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
   * @since 1.5
   */
  public synchronized int codePointAt(int index)
  {
    // Use the CharSequence overload as we get better range checking
    // this way.
    return Character.codePointAt(this, index);
  }

  /**
   * Get the code point before the specified index.  This is like
   * #codePointAt(int), but checks the characters at <code>index-1</code> and
   * <code>index-2</code> to see if they form a supplementary code point.
   * @param index the index just past the codepoint to get, starting at 0
   * @return the codepoint at the specified index
   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
   * @since 1.5
   */
  public synchronized int codePointBefore(int index)
  {
    // Use the CharSequence overload as we get better range checking
    // this way.
    return Character.codePointBefore(this, index);
  }

  /**
   * Copies characters from this String starting at a specified start index,
   * ending at a specified stop index, to a character array starting at
   * a specified destination begin index.
   *
   * @param srcBegin index to begin copying characters from this String
   * @param srcEnd index after the last character to be copied from this String
   * @param dst character array which this String is copied into
   * @param dstBegin index to start writing characters into dst
   * @throws NullPointerException if dst is null
   * @throws IndexOutOfBoundsException if any indices are out of bounds
   *         (while unspecified, source problems cause a
   *         StringIndexOutOfBoundsException, and dst problems cause an
   *         ArrayIndexOutOfBoundsException)
   */
  public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
  {
    if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
      throw new StringIndexOutOfBoundsException();
    VMSystem.arraycopy(value, srcBegin + offset,
                     dst, dstBegin, srcEnd - srcBegin);
  }

  /**
   * Copies the low byte of each character from this String starting at a
   * specified start index, ending at a specified stop index, to a byte array
   * starting at a specified destination begin index.
   *
   * @param srcBegin index to being copying characters from this String
   * @param srcEnd index after the last character to be copied from this String
   * @param dst byte array which each low byte of this String is copied into
   * @param dstBegin index to start writing characters into dst
   * @throws NullPointerException if dst is null and copy length is non-zero
   * @throws IndexOutOfBoundsException if any indices are out of bounds
   *         (while unspecified, source problems cause a
   *         StringIndexOutOfBoundsException, and dst problems cause an
   *         ArrayIndexOutOfBoundsException)
   * @see #getBytes()
   * @see #getBytes(String)
   * @deprecated use {@link #getBytes()}, which uses a char to byte encoder
   */
  public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)
  {
    if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
      throw new StringIndexOutOfBoundsException();
    int i = srcEnd - srcBegin;
    srcBegin += offset;
    while (--i >= 0)
      dst[dstBegin++] = (byte) value[srcBegin++];
  }

  /**
   * Converts the Unicode characters in this String to a byte array. Uses the
   * specified encoding method, so the result may be longer or shorter than
   * the String. For more encoding control, use
   * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
   * see {@link java.nio.charset.Charset}. Unsupported characters get
   * replaced by an encoding specific byte.
   *
   * @param enc encoding name
   * @return the resulting byte array
   * @throws NullPointerException if enc is null
   * @throws UnsupportedEncodingException if encoding is not supported
   * @since 1.1
   */
  public byte[] getBytes(final String enc)
    throws UnsupportedEncodingException
  {
    return getBytes(stringToCharset(enc));
  }

  /**
   * Converts the Unicode characters in this String to a byte array. Uses the
   * specified encoding method, so the result may be longer or shorter than
   * the String. For more encoding control, use
   * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
   * see {@link java.nio.charset.Charset}. Unsupported characters get
   * replaced by the {@link java.nio.charset.Charset}'s default replacement.
   *
   * @param enc encoding name
   * @return the resulting byte array
   * @throws NullPointerException if enc is null
   * @since 1.6
   */
  public byte[] getBytes(Charset enc)
  {
    try 
      {
	CharsetEncoder cse = enc.newEncoder();
	cse.onMalformedInput(CodingErrorAction.REPLACE);
	cse.onUnmappableCharacter(CodingErrorAction.REPLACE);
	ByteBuffer bbuf = cse.encode(CharBuffer.wrap(value, offset, count));
	if(bbuf.hasArray())
	  return bbuf.array();
	
	// Doubt this will happen. But just in case.
	byte[] bytes = new byte[bbuf.remaining()];
	bbuf.get(bytes);
	return bytes;
      } 
    catch(CharacterCodingException e)
      {
	// This shouldn't ever happen.
	throw (InternalError) new InternalError().initCause(e);
      }	  
  }

  /**
   * Converts the Unicode characters in this String to a byte array. Uses the
   * encoding of the platform's default charset, so the result may be longer
   * or shorter than the String. For more encoding control, use
   * {@link java.nio.charset.CharsetEncoder}. Unsupported characters get
   * replaced by an encoding specific byte.
   *
   * @return the resulting byte array, or null on a problem
   * @since 1.1
   */
  public byte[] getBytes()
  { 
      try 
	  {
	      return getBytes(System.getProperty("file.encoding"));
	  } catch(Exception e) {
	      // XXX - Throw an error here? 
	      // For now, default to the 'safe' encoding.
	      byte[] bytes = new byte[count];
	      for(int i=0;i<count;i++)
		  bytes[i] = (byte)((value[offset+i] <= 0xFF)?
				    value[offset+i]:'?');
	      return bytes;
      }
  }

  /**
   * Predicate which compares anObject to this. This is true only for Strings
   * with the same character sequence.
   *
   * @param anObject the object to compare
   * @return true if anObject is semantically equal to this
   * @see #compareTo(String)
   * @see #equalsIgnoreCase(String)
   */
  public boolean equals(Object anObject)
  {
    if (! (anObject instanceof String))
      return false;
    String str2 = (String) anObject;
    if (count != str2.count)
      return false;
    if (value == str2.value && offset == str2.offset)
      return true;
    int i = count;
    int x = offset;
    int y = str2.offset;
    while (--i >= 0)
      if (value[x++] != str2.value[y++])
        return false;
    return true;
  }

  /**
   * Compares the given StringBuffer to this String. This is true if the
   * StringBuffer has the same content as this String at this moment.
   *
   * @param buffer the StringBuffer to compare to
   * @return true if StringBuffer has the same character sequence
   * @throws NullPointerException if the given StringBuffer is null
   * @since 1.4
   */
  public boolean contentEquals(StringBuffer buffer)
  {
    synchronized (buffer)
      {
        if (count != buffer.count)
          return false;
        if (value == buffer.value)
          return true; // Possible if shared.
        int i = count;
        int x = offset + count;
        while (--i >= 0)
          if (value[--x] != buffer.value[i])
            return false;
        return true;
      }
  }

  /**
   * Compares the given CharSequence to this String. This is true if
   * the CharSequence has the same content as this String at this
   * moment.
   *
   * @param seq the CharSequence to compare to
   * @return true if CharSequence has the same character sequence
   * @throws NullPointerException if the given CharSequence is null
   * @since 1.5
   */
  public boolean contentEquals(CharSequence seq)
  {
    if (seq.length() != count)
      return false;
    for (int i = 0; i < count; ++i)
      if (value[offset + i] != seq.charAt(i))
	return false;
    return true;
  }

  /**
   * Compares a String to this String, ignoring case. This does not handle
   * multi-character capitalization exceptions; instead the comparison is
   * made on a character-by-character basis, and is true if:<br><ul>
   * <li><code>c1 == c2</code></li>
   * <li><code>Character.toUpperCase(c1)
   *     == Character.toUpperCase(c2)</code></li>
   * <li><code>Character.toLowerCase(c1)
   *     == Character.toLowerCase(c2)</code></li>
   * </ul>
   *
   * @param anotherString String to compare to this String
   * @return true if anotherString is equal, ignoring case
   * @see #equals(Object)
   * @see Character#toUpperCase(char)
   * @see Character#toLowerCase(char)
   */
  public boolean equalsIgnoreCase(String anotherString)
  {
    if (anotherString == null || count != anotherString.count)
      return false;
    int i = count;
    int x = offset;
    int y = anotherString.offset;
    while (--i >= 0)
      {
        char c1 = value[x++];
        char c2 = anotherString.value[y++];
        // Note that checking c1 != c2 is redundant, but avoids method calls.
        if (c1 != c2
            && Character.toUpperCase(c1) != Character.toUpperCase(c2)
            && Character.toLowerCase(c1) != Character.toLowerCase(c2))
          return false;
      }
    return true;
  }

  /**
   * Compares this String and another String (case sensitive,
   * lexicographically). The result is less than 0 if this string sorts
   * before the other, 0 if they are equal, and greater than 0 otherwise.
   * After any common starting sequence is skipped, the result is
   * <code>this.charAt(k) - anotherString.charAt(k)</code> if both strings
   * have characters remaining, or
   * <code>this.length() - anotherString.length()</code> if one string is
   * a subsequence of the other.
   *
   * @param anotherString the String to compare against
   * @return the comparison
   * @throws NullPointerException if anotherString is null
   */
  public int compareTo(String anotherString)
  {
    int i = Math.min(count, anotherString.count);
    int x = offset;
    int y = anotherString.offset;
    while (--i >= 0)
      {
        int result = value[x++] - anotherString.value[y++];
        if (result != 0)
          return result;
      }
    return count - anotherString.count;
  }

  /**
   * Compares this String and another String (case insensitive). This
   * comparison is <em>similar</em> to equalsIgnoreCase, in that it ignores
   * locale and multi-characater capitalization, and compares characters
   * after performing
   * <code>Character.toLowerCase(Character.toUpperCase(c))</code> on each
   * character of the string. This is unsatisfactory for locale-based
   * comparison, in which case you should use {@link java.text.Collator}.
   *
   * @param str the string to compare against
   * @return the comparison
   * @see Collator#compare(String, String)
   * @since 1.2
   */
  public int compareToIgnoreCase(String str)
  {
    int i = Math.min(count, str.count);
    int x = offset;
    int y = str.offset;
    while (--i >= 0)
      {
        int result = Character.toLowerCase(Character.toUpperCase(value[x++]))
          - Character.toLowerCase(Character.toUpperCase(str.value[y++]));
        if (result != 0)
          return result;
      }
    return count - str.count;
  }  

  /**
   * Predicate which determines if this String matches another String
   * starting at a specified offset for each String and continuing
   * for a specified length. Indices out of bounds are harmless, and give
   * a false result.
   *
   * @param toffset index to start comparison at for this String
   * @param other String to compare region to this String
   * @param ooffset index to start comparison at for other
   * @param len number of characters to compare
   * @return true if regions match (case sensitive)
   * @throws NullPointerException if other is null
   */
  public boolean regionMatches(int toffset, String other, int ooffset, int len)
  {
    return regionMatches(false, toffset, other, ooffset, len);
  }

  /**
   * Predicate which determines if this String matches another String
   * starting at a specified offset for each String and continuing
   * for a specified length, optionally ignoring case. Indices out of bounds
   * are harmless, and give a false result. Case comparisons are based on
   * <code>Character.toLowerCase()</code> and
   * <code>Character.toUpperCase()</code>, not on multi-character
   * capitalization expansions.
   *
   * @param ignoreCase true if case should be ignored in comparision
   * @param toffset index to start comparison at for this String
   * @param other String to compare region to this String
   * @param ooffset index to start comparison at for other
   * @param len number of characters to compare
   * @return true if regions match, false otherwise
   * @throws NullPointerException if other is null
   */
  public boolean regionMatches(boolean ignoreCase, int toffset,
                               String other, int ooffset, int len)
  {
    if (toffset < 0 || ooffset < 0 || toffset + len > count
        || ooffset + len > other.count)
      return false;
    toffset += offset;
    ooffset += other.offset;
    while (--len >= 0)
      {
        char c1 = value[toffset++];
        char c2 = other.value[ooffset++];
        // Note that checking c1 != c2 is redundant when ignoreCase is true,
        // but it avoids method calls.
        if (c1 != c2
            && (! ignoreCase
                || (Character.toLowerCase(c1) != Character.toLowerCase(c2)
                    && (Character.toUpperCase(c1)
                        != Character.toUpperCase(c2)))))
          return false;
      }
    return true;
  }

  /**
   * Predicate which determines if this String contains the given prefix,
   * beginning comparison at toffset. The result is false if toffset is
   * negative or greater than this.length(), otherwise it is the same as
   * <code>this.substring(toffset).startsWith(prefix)</code>.
   *
   * @param prefix String to compare
   * @param toffset offset for this String where comparison starts
   * @return true if this String starts with prefix
   * @throws NullPointerException if prefix is null
   * @see #regionMatches(boolean, int, String, int, int)
   */
  public boolean startsWith(String prefix, int toffset)
  {
    return regionMatches(false, toffset, prefix, 0, prefix.count);
  }

  /**
   * Predicate which determines if this String starts with a given prefix.
   * If the prefix is an empty String, true is returned.
   *
   * @param prefix String to compare
   * @return true if this String starts with the prefix
   * @throws NullPointerException if prefix is null
   * @see #startsWith(String, int)
   */
  public boolean startsWith(String prefix)
  {
    return regionMatches(false, 0, prefix, 0, prefix.count);
  }

  /**
   * Predicate which determines if this String ends with a given suffix.
   * If the suffix is an empty String, true is returned.
   *
   * @param suffix String to compare
   * @return true if this String ends with the suffix
   * @throws NullPointerException if suffix is null
   * @see #regionMatches(boolean, int, String, int, int)
   */
  public boolean endsWith(String suffix)
  {
    return regionMatches(false, count - suffix.count, suffix, 0, suffix.count);
  }

  /**
   * Computes the hashcode for this String. This is done with int arithmetic,
   * where ** represents exponentiation, by this formula:<br>
   * <code>s[0]*31**(n-1) + s[1]*31**(n-2) + ... + s[n-1]</code>.
   *
   * @return hashcode value of this String
   */
  public int hashCode()
  {
    if (cachedHashCode != 0)
      return cachedHashCode;

    // Compute the hash code using a local variable to be reentrant.
    int hashCode = 0;
    int limit = count + offset;
    for (int i = offset; i < limit; i++)
      hashCode = hashCode * 31 + value[i];
    return cachedHashCode = hashCode;
  }

  /**
   * Finds the first instance of a character in this String.
   *
   * @param ch character to find
   * @return location (base 0) of the character, or -1 if not found
   */
  public int indexOf(int ch)
  {
    return indexOf(ch, 0);
  }

  /**
   * Finds the first instance of a character in this String, starting at
   * a given index.  If starting index is less than 0, the search
   * starts at the beginning of this String.  If the starting index
   * is greater than the length of this String, -1 is returned.
   *
   * @param ch character to find
   * @param fromIndex index to start the search
   * @return location (base 0) of the character, or -1 if not found
   */
  public int indexOf(int ch, int fromIndex)
  {
    if ((char) ch != ch)
      return -1;
    if (fromIndex < 0)
      fromIndex = 0;
    int i = fromIndex + offset;
    for ( ; fromIndex < count; fromIndex++)
      if (value[i++] == ch)
        return fromIndex;
    return -1;
  }

  /**
   * Finds the last instance of a character in this String.
   *
   * @param ch character to find
   * @return location (base 0) of the character, or -1 if not found
   */
  public int lastIndexOf(int ch)
  {
    return lastIndexOf(ch, count - 1);
  }

  /**
   * Finds the last instance of a character in this String, starting at
   * a given index.  If starting index is greater than the maximum valid
   * index, then the search begins at the end of this String.  If the
   * starting index is less than zero, -1 is returned.
   *
   * @param ch character to find
   * @param fromIndex index to start the search
   * @return location (base 0) of the character, or -1 if not found
   */
  public int lastIndexOf(int ch, int fromIndex)
  {
    if ((char) ch != ch)
      return -1;
    if (fromIndex >= count)
      fromIndex = count - 1;
    int i = fromIndex + offset;
    for ( ; fromIndex >= 0; fromIndex--)
      if (value[i--] == ch)
        return fromIndex;
    return -1;
  }

  /**
   * Finds the first instance of a String in this String.
   *
   * @param str String to find
   * @return location (base 0) of the String, or -1 if not found
   * @throws NullPointerException if str is null
   */
  public int indexOf(String str)
  {
    return indexOf(str, 0);
  }

  /**
   * Finds the first instance of a String in this String, starting at
   * a given index.  If starting index is less than 0, the search
   * starts at the beginning of this String.  If the starting index
   * is greater than the length of this String, -1 is returned.
   *
   * @param str String to find
   * @param fromIndex index to start the search
   * @return location (base 0) of the String, or -1 if not found
   * @throws NullPointerException if str is null
   */
  public int indexOf(String str, int fromIndex)
  {
    if (fromIndex < 0)
      fromIndex = 0;
    int limit = count - str.count;
    for ( ; fromIndex <= limit; fromIndex++)
      if (regionMatches(fromIndex, str, 0, str.count))
        return fromIndex;
    return -1;
  }

  /**
   * Finds the last instance of a String in this String.
   *
   * @param str String to find
   * @return location (base 0) of the String, or -1 if not found
   * @throws NullPointerException if str is null
   */
  public int lastIndexOf(String str)
  {
    return lastIndexOf(str, count - str.count);
  }

  /**
   * Finds the last instance of a String in this String, starting at
   * a given index.  If starting index is greater than the maximum valid
   * index, then the search begins at the end of this String.  If the
   * starting index is less than zero, -1 is returned.
   *
   * @param str String to find
   * @param fromIndex index to start the search
   * @return location (base 0) of the String, or -1 if not found
   * @throws NullPointerException if str is null
   */
  public int lastIndexOf(String str, int fromIndex)
  {
    fromIndex = Math.min(fromIndex, count - str.count);
    for ( ; fromIndex >= 0; fromIndex--)
      if (regionMatches(fromIndex, str, 0, str.count))
        return fromIndex;
    return -1;
  }

  /**
   * Creates a substring of this String, starting at a specified index
   * and ending at the end of this String.
   *
   * @param begin index to start substring (base 0)
   * @return new String which is a substring of this String
   * @throws IndexOutOfBoundsException if begin &lt; 0 || begin &gt; length()
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
   */
  public String substring(int begin)
  {
    return substring(begin, count);
  }

  /**
   * Creates a substring of this String, starting at a specified index
   * and ending at one character before a specified index.
   *
   * @param beginIndex index to start substring (inclusive, base 0)
   * @param endIndex index to end at (exclusive)
   * @return new String which is a substring of this String
   * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
   *         || begin &gt; end (while unspecified, this is a
   *         StringIndexOutOfBoundsException)
   */
  public String substring(int beginIndex, int endIndex)
  {
    if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
      throw new StringIndexOutOfBoundsException();
    if (beginIndex == 0 && endIndex == count)
      return this;
    int len = endIndex - beginIndex;
    // Package constructor avoids an array copy.
    return new String(value, beginIndex + offset, len,
                      (len << 2) >= value.length);
  }

  /**
   * Creates a substring of this String, starting at a specified index
   * and ending at one character before a specified index. This behaves like
   * <code>substring(begin, end)</code>.
   *
   * @param begin index to start substring (inclusive, base 0)
   * @param end index to end at (exclusive)
   * @return new String which is a substring of this String
   * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
   *         || begin &gt; end
   * @since 1.4
   */
  public CharSequence subSequence(int begin, int end)
  {
    return substring(begin, end);
  }

  /**
   * Concatenates a String to this String. This results in a new string unless
   * one of the two originals is "".
   *
   * @param str String to append to this String
   * @return newly concatenated String
   * @throws NullPointerException if str is null
   */
  public String concat(String str)
  {
    if (str.count == 0)
      return this;
    if (count == 0)
      return str;
    char[] newStr = new char[count + str.count];
    VMSystem.arraycopy(value, offset, newStr, 0, count);
    VMSystem.arraycopy(str.value, str.offset, newStr, count, str.count);
    // Package constructor avoids an array copy.
    return new String(newStr, 0, newStr.length, true);
  }

  /**
   * Replaces every instance of a character in this String with a new
   * character. If no replacements occur, this is returned.
   *
   * @param oldChar the old character to replace
   * @param newChar the new character
   * @return new String with all instances of oldChar replaced with newChar
   */
  public String replace(char oldChar, char newChar)
  {
    if (oldChar == newChar)
      return this;
    int i = count;
    int x = offset - 1;
    while (--i >= 0)
      if (value[++x] == oldChar)
        break;
    if (i < 0)
      return this;
    char[] newStr = toCharArray();
    newStr[x - offset] = newChar;
    while (--i >= 0)
      if (value[++x] == oldChar)
        newStr[x - offset] = newChar;
    // Package constructor avoids an array copy.
    return new String(newStr, 0, count, true);
  }

  /**
   * Test if this String matches a regular expression. This is shorthand for
   * <code>{@link Pattern}.matches(regex, this)</code>.
   *
   * @param regex the pattern to match
   * @return true if the pattern matches
   * @throws NullPointerException if regex is null
   * @throws PatternSyntaxException if regex is invalid
   * @see Pattern#matches(String, CharSequence)
   * @since 1.4
   */
  public boolean matches(String regex)
  {
    return Pattern.matches(regex, this);
  }

  /**
   * Replaces the first substring match of the regular expression with a
   * given replacement. This is shorthand for <code>{@link Pattern}
   *   .compile(regex).matcher(this).replaceFirst(replacement)</code>.
   *
   * @param regex the pattern to match
   * @param replacement the replacement string
   * @return the modified string
   * @throws NullPointerException if regex or replacement is null
   * @throws PatternSyntaxException if regex is invalid
   * @see #replaceAll(String, String)
   * @see Pattern#compile(String)
   * @see Pattern#matcher(CharSequence)
   * @see Matcher#replaceFirst(String)
   * @since 1.4
   */
  public String replaceFirst(String regex, String replacement)
  {
    return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
  }

  /**
   * Replaces all matching substrings of the regular expression with a
   * given replacement. This is shorthand for <code>{@link Pattern}
   *   .compile(regex).matcher(this).replaceAll(replacement)</code>.
   *
   * @param regex the pattern to match
   * @param replacement the replacement string
   * @return the modified string
   * @throws NullPointerException if regex or replacement is null
   * @throws PatternSyntaxException if regex is invalid
   * @see #replaceFirst(String, String)
   * @see Pattern#compile(String)
   * @see Pattern#matcher(CharSequence)
   * @see Matcher#replaceAll(String)
   * @since 1.4
   */
  public String replaceAll(String regex, String replacement)
  {
    return Pattern.compile(regex).matcher(this).replaceAll(replacement);
  }

  /**
   * Split this string around the matches of a regular expression. Each
   * element of the returned array is the largest block of characters not
   * terminated by the regular expression, in the order the matches are found.
   *
   * <p>The limit affects the length of the array. If it is positive, the
   * array will contain at most n elements (n - 1 pattern matches). If
   * negative, the array length is unlimited, but there can be trailing empty
   * entries. if 0, the array length is unlimited, and trailing empty entries
   * are discarded.
   *
   * <p>For example, splitting "boo:and:foo" yields:<br>
   * <table border=0>
   * <th><td>Regex</td> <td>Limit</td> <td>Result</td></th>
   * <tr><td>":"</td>   <td>2</td>  <td>{ "boo", "and:foo" }</td></tr>
   * <tr><td>":"</td>   <td>t</td>  <td>{ "boo", "and", "foo" }</td></tr>
   * <tr><td>":"</td>   <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr>
   * <tr><td>"o"</td>   <td>5</td>  <td>{ "b", "", ":and:f", "", "" }</td></tr>
   * <tr><td>"o"</td>   <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
   * <tr><td>"o"</td>   <td>0</td>  <td>{ "b", "", ":and:f" }</td></tr>
   * </table>
   *
   * <p>This is shorthand for
   * <code>{@link Pattern}.compile(regex).split(this, limit)</code>.
   *
   * @param regex the pattern to match
   * @param limit the limit threshold
   * @return the array of split strings
   * @throws NullPointerException if regex or replacement is null
   * @throws PatternSyntaxException if regex is invalid
   * @see Pattern#compile(String)
   * @see Pattern#split(CharSequence, int)
   * @since 1.4
   */
  public String[] split(String regex, int limit)
  {
    return Pattern.compile(regex).split(this, limit);
  }

  /**
   * Split this string around the matches of a regular expression. Each
   * element of the returned array is the largest block of characters not
   * terminated by the regular expression, in the order the matches are found.
   * The array length is unlimited, and trailing empty entries are discarded,
   * as though calling <code>split(regex, 0)</code>.
   *
   * @param regex the pattern to match
   * @return the array of split strings
   * @throws NullPointerException if regex or replacement is null
   * @throws PatternSyntaxException if regex is invalid
   * @see #split(String, int)
   * @see Pattern#compile(String)
   * @see Pattern#split(CharSequence, int)
   * @since 1.4
   */
  public String[] split(String regex)
  {
    return Pattern.compile(regex).split(this, 0);
  }

  /**
   * Convert string to lower case for a Turkish locale that requires special
   * handling of '\u0049'
   */
  private String toLowerCaseTurkish()
  {
    // First, see if the current string is already lower case.
    int i = count;
    int x = offset - 1;
    while (--i >= 0)
      {
        char ch = value[++x];
        if ((ch == '\u0049') || ch != Character.toLowerCase(ch))
          break;
      }
    if (i < 0)
      return this;

    // Now we perform the conversion. Fortunately, there are no multi-character
    // lowercase expansions in Unicode 3.0.0.
    char[] newStr = new char[count];
    VMSystem.arraycopy(value, offset, newStr, 0, x - offset);
    do
      {
        char ch = value[x];
        // Hardcoded special case.
        if (ch != '\u0049')
          {
            newStr[x - offset] = Character.toLowerCase(ch);
          }
        else
          {
            newStr[x - offset] = '\u0131';
          }
        x++;
      }
    while (--i >= 0);
    // Package constructor avoids an array copy.
    return new String(newStr, 0, count, true);
  }

  /**
   * Lowercases this String according to a particular locale. This uses
   * Unicode's special case mappings, as applied to the given Locale, so the
   * resulting string may be a different length.
   *
   * @param loc locale to use
   * @return new lowercased String, or this if no characters were lowercased
   * @throws NullPointerException if loc is null
   * @see #toUpperCase(Locale)
   * @since 1.1
   */
  public String toLowerCase(Locale loc)
  {
    // First, see if the current string is already lower case.

    // Is loc turkish? String equality test is ok as Locale.language is interned
    if ("tr" == loc.getLanguage())
      {
        return toLowerCaseTurkish();
      }
    else
      {
        int i = count;
        int x = offset - 1;
        while (--i >= 0)
          {
            char ch = value[++x];
            if (ch != Character.toLowerCase(ch))
              break;
          }
        if (i < 0)
          return this;

        // Now we perform the conversion. Fortunately, there are no
        // multi-character lowercase expansions in Unicode 3.0.0.
        char[] newStr = new char[count];
        VMSystem.arraycopy(value, offset, newStr, 0, x - offset);
        do
          {
            char ch = value[x];
            // Hardcoded special case.
            newStr[x - offset] = Character.toLowerCase(ch);
            x++;
          }
        while (--i >= 0);
        // Package constructor avoids an array copy.
        return new String(newStr, 0, count, true);
     }
  }

  /**
   * Lowercases this String. This uses Unicode's special case mappings, as
   * applied to the platform's default Locale, so the resulting string may
   * be a different length.
   *
   * @return new lowercased String, or this if no characters were lowercased
   * @see #toLowerCase(Locale)
   * @see #toUpperCase()
   */
  public String toLowerCase()
  {
    return toLowerCase(Locale.getDefault());
  }

  /**
   * Uppercase this string for a Turkish locale
   */
  private String toUpperCaseTurkish()
  {
    // First, see how many characters we have to grow by, as well as if the
    // current string is already upper case.
    int expand = 0;
    boolean unchanged = true;
    int i = count;
    int x = i + offset;
    while (--i >= 0)
      {
        char ch = value[--x];
        expand += upperCaseExpansion(ch);
        unchanged = (unchanged && expand == 0
                     && ch != '\u0069'
                     && ch == Character.toUpperCase(ch));
      }
    if (unchanged)
      return this;

    // Now we perform the conversion.
    i = count;
    if (expand == 0)
      {
        char[] newStr = new char[count];
        VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
        while (--i >= 0)
          {
            char ch = value[x];
            // Hardcoded special case.
            if (ch != '\u0069')
              {
                newStr[x - offset] = Character.toUpperCase(ch);
              }
            else
              {
                newStr[x - offset] = '\u0130';
              }
            x++;
          }
        // Package constructor avoids an array copy.
        return new String(newStr, 0, count, true);
      }

    // Expansion is necessary.
    char[] newStr = new char[count + expand];
    int j = 0;
    while (--i >= 0)
      {
        char ch = value[x++];
        // Hardcoded special case.
        if (ch == '\u0069')
          {
            newStr[j++] = '\u0130';
            continue;
          }
        expand = upperCaseExpansion(ch);
        if (expand > 0)
          {
            int index = upperCaseIndex(ch);
            while (expand-- >= 0)
              newStr[j++] = upperExpand[index++];
          }
        else
          newStr[j++] = Character.toUpperCase(ch);
      }
    // Package constructor avoids an array copy.
    return new String(newStr, 0, newStr.length, true);
  }

  /**
   * Uppercases this String according to a particular locale. This uses
   * Unicode's special case mappings, as applied to the given Locale, so the
   * resulting string may be a different length.
   *
   * @param loc locale to use
   * @return new uppercased String, or this if no characters were uppercased
   * @throws NullPointerException if loc is null
   * @see #toLowerCase(Locale)
   * @since 1.1
   */
  public String toUpperCase(Locale loc)
  {
    // First, see how many characters we have to grow by, as well as if the
    // current string is already upper case.

    // Is loc turkish? String equality test is ok as Locale.language is interned
    if ("tr" == loc.getLanguage())
      {
        return toUpperCaseTurkish();
      }
    else
      {
        int expand = 0;
        boolean unchanged = true;
        int i = count;
        int x = i + offset;
        while (--i >= 0)
          {
            char ch = value[--x];
            expand += upperCaseExpansion(ch);
            unchanged = (unchanged && expand == 0
                         && ch == Character.toUpperCase(ch));
          }
        if (unchanged)
          return this;

        // Now we perform the conversion.
        i = count;
        if (expand == 0)
          {
            char[] newStr = new char[count];
            VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
            while (--i >= 0)
              {
                char ch = value[x];
                newStr[x - offset] = Character.toUpperCase(ch);
                x++;
              }
            // Package constructor avoids an array copy.
            return new String(newStr, 0, count, true);
          }

        // Expansion is necessary.
        char[] newStr = new char[count + expand];
        int j = 0;
        while (--i >= 0)
          {
            char ch = value[x++];
            expand = upperCaseExpansion(ch);
            if (expand > 0)
              {
                int index = upperCaseIndex(ch);
                while (expand-- >= 0)
                  newStr[j++] = upperExpand[index++];
              }
            else
              newStr[j++] = Character.toUpperCase(ch);
          }
        // Package constructor avoids an array copy.
        return new String(newStr, 0, newStr.length, true);
      }
  }
  /**
   * Uppercases this String. This uses Unicode's special case mappings, as
   * applied to the platform's default Locale, so the resulting string may
   * be a different length.
   *
   * @return new uppercased String, or this if no characters were uppercased
   * @see #toUpperCase(Locale)
   * @see #toLowerCase()
   */
  public String toUpperCase()
  {
    return toUpperCase(Locale.getDefault());
  }

  /**
   * Trims all characters less than or equal to <code>'\u0020'</code>
   * (<code>' '</code>) from the beginning and end of this String. This
   * includes many, but not all, ASCII control characters, and all
   * {@link Character#isWhitespace(char)}.
   *
   * @return new trimmed String, or this if nothing trimmed
   */
  public String trim()
  {
    int limit = count + offset;
    if (count == 0 || (value[offset] > '\u0020'
                       && value[limit - 1] > '\u0020'))
      return this;
    int begin = offset;
    do
      if (begin == limit)
        return "";
    while (value[begin++] <= '\u0020');
    
    int end = limit;
    while (value[--end] <= '\u0020')
      ;
    return substring(begin - offset - 1, end - offset + 1);
  }

  /**
   * Returns this, as it is already a String!
   *
   * @return this
   */
  public String toString()
  {
    return this;
  }

  /**
   * Copies the contents of this String into a character array. Subsequent
   * changes to the array do not affect the String.
   *
   * @return character array copying the String
   */
  public char[] toCharArray()
  {
    char[] copy = new char[count];
    VMSystem.arraycopy(value, offset, copy, 0, count);
    return copy;
  }

  /**
   * Returns a String representation of an Object. This is "null" if the
   * object is null, otherwise it is <code>obj.toString()</code> (which
   * can be null).
   *
   * @param obj the Object
   * @return the string conversion of obj
   */
  public static String valueOf(Object obj)
  {
    return obj == null ? "null" : obj.toString();
  }

  /**
   * Returns a String representation of a character array. Subsequent
   * changes to the array do not affect the String.
   *
   * @param data the character array
   * @return a String containing the same character sequence as data
   * @throws NullPointerException if data is null
   * @see #valueOf(char[], int, int)
   * @see #String(char[])
   */
  public static String valueOf(char[] data)
  {
    return valueOf (data, 0, data.length);
  }

  /**
   * Returns a String representing the character sequence of the char array,
   * starting at the specified offset, and copying chars up to the specified
   * count. Subsequent changes to the array do not affect the String.
   *
   * @param data character array
   * @param offset position (base 0) to start copying out of data
   * @param count the number of characters from data to copy
   * @return String containing the chars from data[offset..offset+count]
   * @throws NullPointerException if data is null
   * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
   *         || offset + count &gt; data.length)
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
   * @see #String(char[], int, int)
   */
  public static String valueOf(char[] data, int offset, int count)
  {
    return new String(data, offset, count, false);
  }

  /**
   * Returns a String representing the character sequence of the char array,
   * starting at the specified offset, and copying chars up to the specified
   * count. Subsequent changes to the array do not affect the String.
   *
   * @param data character array
   * @param offset position (base 0) to start copying out of data
   * @param count the number of characters from data to copy
   * @return String containing the chars from data[offset..offset+count]
   * @throws NullPointerException if data is null
   * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
   *         || offset + count &lt; 0 (overflow)
   *         || offset + count &lt; 0 (overflow)
   *         || offset + count &gt; data.length)
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
   * @see #String(char[], int, int)
   */
  public static String copyValueOf(char[] data, int offset, int count)
  {
    return new String(data, offset, count, false);
  }

  /**
   * Returns a String representation of a character array. Subsequent
   * changes to the array do not affect the String.
   *
   * @param data the character array
   * @return a String containing the same character sequence as data
   * @throws NullPointerException if data is null
   * @see #copyValueOf(char[], int, int)
   * @see #String(char[])
   */
  public static String copyValueOf(char[] data)
  {
    return copyValueOf (data, 0, data.length);
  }

  /**
   * Returns a String representing a boolean.
   *
   * @param b the boolean
   * @return "true" if b is true, else "false"
   */
  public static String valueOf(boolean b)
  {
    return b ? "true" : "false";
  }

  /**
   * Returns a String representing a character.
   *
   * @param c the character
   * @return String containing the single character c
   */
  public static String valueOf(char c)
  {
    // Package constructor avoids an array copy.
    return new String(new char[] { c }, 0, 1, true);
  }

  /**
   * Returns a String representing an integer.
   *
   * @param i the integer
   * @return String containing the integer in base 10
   * @see Integer#toString(int)
   */
  public static String valueOf(int i)
  {
    // See Integer to understand why we call the two-arg variant.
    return Integer.toString(i, 10);
  }

  /**
   * Returns a String representing a long.
   *
   * @param l the long
   * @return String containing the long in base 10
   * @see Long#toString(long)
   */
  public static String valueOf(long l)
  {
    return Long.toString(l);
  }

  /**
   * Returns a String representing a float.
   *
   * @param f the float
   * @return String containing the float
   * @see Float#toString(float)
   */
  public static String valueOf(float f)
  {
    return Float.toString(f);
  }

  /**
   * Returns a String representing a double.
   *
   * @param d the double
   * @return String containing the double
   * @see Double#toString(double)
   */
  public static String valueOf(double d)
  {
    return Double.toString(d);
  }


  /** @since 1.5 */
  public static String format(Locale locale, String format, Object... args)
  {
    Formatter f = new Formatter(locale);
    return f.format(format, args).toString();
  }

  /** @since 1.5 */
  public static String format(String format, Object... args)
  {
    return format(Locale.getDefault(), format, args);
  }

  /**
   * If two Strings are considered equal, by the equals() method, 
   * then intern() will return the same String instance. ie. 
   * if (s1.equals(s2)) then (s1.intern() == s2.intern()). 
   * All string literals and string-valued constant expressions 
   * are already interned.
   *
   * @return the interned String
   */
  public String intern()
  {
    return VMString.intern(this);
  }

  /**
   * Return the number of code points between two indices in the
   * <code>String</code>.  An unpaired surrogate counts as a
   * code point for this purpose.  Characters outside the indicated
   * range are not examined, even if the range ends in the middle of a
   * surrogate pair.
   *
   * @param start the starting index
   * @param end one past the ending index
   * @return the number of code points
   * @since 1.5
   */
  public synchronized int codePointCount(int start, int end)
  {
    if (start < 0 || end > count || start > end)
      throw new StringIndexOutOfBoundsException();

    start += offset;
    end += offset;
    int count = 0;
    while (start < end)
      {
	char base = value[start];
	if (base < Character.MIN_HIGH_SURROGATE
	    || base > Character.MAX_HIGH_SURROGATE
	    || start == end
	    || start == count
	    || value[start + 1] < Character.MIN_LOW_SURROGATE
	    || value[start + 1] > Character.MAX_LOW_SURROGATE)
	  {
	    // Nothing.
	  }
	else
	  {
	    // Surrogate pair.
	    ++start;
	  }
	++start;
	++count;
      }
    return count;
  }

  /**
   * Helper function used to detect which characters have a multi-character
   * uppercase expansion. Note that this is only used in locations which
   * track one-to-many capitalization (java.lang.Character does not do this).
   * As of Unicode 3.0.0, the result is limited in the range 0 to 2, as the
   * longest uppercase expansion is three characters (a growth of 2 from the
   * lowercase character).
   *
   * @param ch the char to check
   * @return the number of characters to add when converting to uppercase
   * @see CharData#DIRECTION
   * @see CharData#UPPER_SPECIAL
   * @see #toUpperCase(Locale)
   */
  private static int upperCaseExpansion(char ch)
  {
    return Character.direction[0][Character.readCodePoint((int)ch) >> 7] & 3;
  }

  /**
   * Helper function used to locate the offset in upperExpand given a
   * character with a multi-character expansion. The binary search is
   * optimized under the assumption that this method will only be called on
   * characters which exist in upperSpecial.
   *
   * @param ch the char to check
   * @return the index where its expansion begins
   * @see CharData#UPPER_SPECIAL
   * @see CharData#UPPER_EXPAND
   * @see #toUpperCase(Locale)
   */
  private static int upperCaseIndex(char ch)
  {
    // Simple binary search for the correct character.
    int low = 0;
    int hi = upperSpecial.length - 2;
    int mid = ((low + hi) >> 2) << 1;
    char c = upperSpecial[mid];
    while (ch != c)
      {
        if (ch < c)
          hi = mid - 2;
        else
          low = mid + 2;
        mid = ((low + hi) >> 2) << 1;
        c = upperSpecial[mid];
      }
    return upperSpecial[mid + 1];
  }

  /**
   * Returns the value array of the given string if it is zero based or a
   * copy of it that is zero based (stripping offset and making length equal
   * to count). Used for accessing the char[]s of gnu.java.lang.CharData.
   * Package private for use in Character.
   */
  static char[] zeroBasedStringValue(String s)
  {
    char[] value;

    if (s.offset == 0 && s.count == s.value.length)
      value = s.value;
    else
      {
	int count = s.count;
	value = new char[count];
	VMSystem.arraycopy(s.value, s.offset, value, 0, count);
      }

    return value;
  }
  
  /**
   * Returns true iff this String contains the sequence of Characters
   * described in s.
   * @param s the CharSequence
   * @return true iff this String contains s
   * 
   * @since 1.5
   */
  public boolean contains (CharSequence s)
  {
    return this.indexOf(s.toString()) != -1;
  }
  
  /**
   * Returns a string that is this string with all instances of the sequence
   * represented by <code>target</code> replaced by the sequence in 
   * <code>replacement</code>.
   * @param target the sequence to be replaced
   * @param replacement the sequence used as the replacement
   * @return the string constructed as above
   */
  public String replace (CharSequence target, CharSequence replacement)
  {
    String targetString = target.toString();
    String replaceString = replacement.toString();
    int targetLength = target.length();
    int replaceLength = replacement.length();
    
    int startPos = this.indexOf(targetString);
    CPStringBuilder result = new CPStringBuilder(this);    
    while (startPos != -1)
      {
        // Replace the target with the replacement
        result.replace(startPos, startPos + targetLength, replaceString);

        // Search for a new occurrence of the target
        startPos = result.indexOf(targetString, startPos + replaceLength);
      }
    return result.toString();
  }
  
  /**
   * Return the index into this String that is offset from the given index by 
   * <code>codePointOffset</code> code points.
   * @param index the index at which to start
   * @param codePointOffset the number of code points to offset
   * @return the index into this String that is <code>codePointOffset</code>
   * code points offset from <code>index</code>.
   * 
   * @throws IndexOutOfBoundsException if index is negative or larger than the
   * length of this string.
   * @throws IndexOutOfBoundsException if codePointOffset is positive and the
   * substring starting with index has fewer than codePointOffset code points.
   * @throws IndexOutOfBoundsException if codePointOffset is negative and the
   * substring ending with index has fewer than (-codePointOffset) code points.
   * @since 1.5
   */
  public int offsetByCodePoints(int index, int codePointOffset)
  {
    if (index < 0 || index > count)
      throw new IndexOutOfBoundsException();
    
    return Character.offsetByCodePoints(value, offset, count, offset + index,
                                        codePointOffset);
  }

  /**
   * Returns true if, and only if, {@link #length()}
   * is <code>0</code>.
   *
   * @return true if the length of the string is zero.
   * @since 1.6
   */
  public boolean isEmpty()
  {
    return count == 0;
  }

}
