/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

/**
 * Notes: For efficiency we handle String in a specialized way, in fact, a
 * java.lang.String is actually implemented as a native JavaScript String. Then
 * we just load up the prototype of the JavaScript String object with the
 * appropriate instance methods.
 */
package java.lang;

import com.google.gwt.core.client.JavaScriptObject;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Comparator;

/**
 * Intrinsic string class.
 * 
 * TODO(jat): consider whether we want to support the following methods;
 * 
 * <ul>
 * <li>deprecated methods dealing with bytes (I assume not since I can't see
 * much use for them)
 * <ul>
 * <li>String(byte[] ascii, int hibyte)
 * <li>String(byte[] ascii, int hibyte, int offset, int count)
 * <li>getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin)
 * </ul>
 * <li>methods which in JS will essentially do nothing or be the same as other
 * methods
 * <ul>
 * <li>copyValueOf(char[] data)
 * <li>copyValueOf(char[] data, int offset, int count)
 * </ul>
 * <li>methods added in Java 1.6 (the issue is how will it impact users
 * building against Java 1.5)
 * <ul>
 * <li>isEmpty()
 * </ul>
 * <li>other methods which are not straightforward in JS
 * <ul>
 * <li>format(String format, Object... args)
 * </ul>
 * </ul>
 * 
 * Also, in general, we need to improve our support of non-ASCII characters. The
 * problem is that correct support requires large tables, and we don't want to
 * make users who aren't going to use that pay for it. There are two ways to do
 * that:
 * <ol>
 * <li>construct the tables in such a way that if the corresponding method is
 * not called the table will be elided from the output.
 * <li>provide a deferred binding target selecting the level of compatibility
 * required. Those that only need ASCII (or perhaps a different relatively small
 * subset such as Latin1-5) will not pay for large tables, even if they do call
 * toLowercase(), for example.
 * </ol>
 * 
 * Also, if we ever add multi-locale support, there are a number of other
 * methods such as toLowercase(Locale) we will want to consider supporting. This
 * is probably rare, but there will be some apps (such as a translation tool)
 * which cannot be written without this support.
 * 
 * Another category of incomplete support is that we currently just use the JS
 * regex support, which is not exactly the same as Java. We should support Java
 * syntax by mapping it into equivalent JS patterns, or emulating them.
 */
public final class String implements Comparable<String>, CharSequence,
    Serializable {

  static final class HashCache {
    /**
     * The "old" cache; it will be dumped when front is full.
     */
    static JavaScriptObject back = JavaScriptObject.createObject();
    /**
     * Tracks the number of entries in front.
     */
    static int count = 0;
    /**
     * The "new" cache; it will become back when it becomes full.
     */
    static JavaScriptObject front = JavaScriptObject.createObject();
    /**
     * Pulled this number out of thin air.
     */
    static final int MAX_CACHE = 256;

    public static native int getHashCode(String str) /*-{
      // Accesses must to be prefixed with ':' to prevent conflict with built-in
      // JavaScript properties.
      var key = ':' + str;

      // Check the front store.
      var result = @java.lang.String.HashCache::front[key];
      if (result != null) {
        return result;
      }

      // Check the back store.
      result = @java.lang.String.HashCache::back[key];
      if (result == null) {
        // Compute the value.
        result = @java.lang.String.HashCache::compute(Ljava/lang/String;)(str);
      }
      // Increment can trigger the swap/flush; call after checking back but
      // before writing to front.
      @java.lang.String.HashCache::increment()();
      return @java.lang.String.HashCache::front[key] = result;
    }-*/;

    static int compute(String str) {
      int hashCode = 0;
      int n = str.length();
      int nBatch = n - 4;
      int i = 0;

      // Process batches of 4 characters at a time
      while (i < nBatch) {
        // Add the next 4 characters to the hash.
        // After every 4 characters, we force the result to fit into 32 bits
        // by doing a bitwise operation on it.
        hashCode = (str.charAt(i + 3)
            + 31 * (str.charAt(i + 2)
            + 31 * (str.charAt(i + 1)
            + 31 * (str.charAt(i)
            + 31 * hashCode)))) | 0;

        i += 4;
      }

      // Now process the leftovers
      while (i < n) {
        hashCode = hashCode * 31 + str.charAt(i++);
      }
      
      // TODO: make a JSNI call in case JDT gets smart about removing this
      // Do a final fitting to 32 bits
      return hashCode | 0;
    }

    static void increment() {
      if (count == MAX_CACHE) {
        back = front;
        front = JavaScriptObject.createObject();
        count = 0;
      }
      ++count;
    }
  }

  public static final Comparator<String> CASE_INSENSITIVE_ORDER = new Comparator<String>() {
    public int compare(String a, String b) {
      return a.compareToIgnoreCase(b);
    }
  };

  // names for standard character sets that are supported
  private static final String CHARSET_8859_1 = "ISO-8859-1";
  private static final String CHARSET_LATIN1 = "ISO-LATIN-1";
  private static final String CHARSET_UTF8 = "UTF-8";

  public static String copyValueOf(char[] v) {
    return valueOf(v);
  }

  public static String copyValueOf(char[] v, int offset, int count) {
    return valueOf(v, offset, count);
  }

  public static String valueOf(boolean x) {
    return "" + x;
  }

  public static native String valueOf(char x) /*-{
    return String.fromCharCode(x);
  }-*/;

  public static String valueOf(char x[], int offset, int count) {
    int end = offset + count;
    __checkBounds(x.length, offset, end);
    return __valueOf(x, offset, end);
  }

  public static native String valueOf(char[] x) /*-{
    // Trick: fromCharCode is a vararg method, so we can use apply() to pass the
    // entire input in one shot.
    return String.fromCharCode.apply(null, x);
  }-*/;

  public static String valueOf(double x) {
    return "" + x;
  }

  public static String valueOf(float x) {
    return "" + x;
  }

  public static String valueOf(int x) {
    return "" + x;
  }

  public static String valueOf(long x) {
    return "" + x;
  }

  public static String valueOf(Object x) {
    return "" + x;
  }

  // CHECKSTYLE_OFF: This class has special needs.

  /**
   * Checks that bounds are correct.
   * 
   * @param legalCount the end of the legal range
   * @param start must be >= 0
   * @param end must be <= legalCount and must be >= start
   * @throw StringIndexOutOfBoundsException if the range is not legal
   * @skip
   */
  static void __checkBounds(int legalCount, int start, int end) {
    if (start < 0) {
      throw new StringIndexOutOfBoundsException(start);
    }
    if (end < start) {
      throw new StringIndexOutOfBoundsException(end - start);
    }
    if (end > legalCount) {
      throw new StringIndexOutOfBoundsException(end);
    }
  }

  /**
   * @skip
   */
  static String[] __createArray(int numElements) {
    return new String[numElements];
  }

  /**
   * This method converts Java-escaped dollar signs "\$" into JavaScript-escaped
   * dollar signs "$$", and removes all other lone backslashes, which serve as
   * escapes in Java but are passed through literally in JavaScript.
   * 
   * @skip
   */
  static String __translateReplaceString(String replaceStr) {
    int pos = 0;
    while (0 <= (pos = replaceStr.indexOf("\\", pos))) {
      if (replaceStr.charAt(pos + 1) == '$') {
        replaceStr = replaceStr.substring(0, pos) + "$"
            + replaceStr.substring(++pos);
      } else {
        replaceStr = replaceStr.substring(0, pos) + replaceStr.substring(++pos);
      }
    }
    return replaceStr;
  }

  static native String __valueOf(char x[], int start, int end) /*-{
    // Trick: fromCharCode is a vararg method, so we can use apply() to pass the
    // entire input in one shot.
    x = x.slice(start, end);
    return String.fromCharCode.apply(null, x);
  }-*/;

  /**
   * @skip
   */
  static String _String() {
    return "";
  }

  /**
   * @skip
   */
  static String _String(byte[] bytes) {
    return _String(bytes, 0, bytes.length);
  }

  /**
   * @skip
   */
  static String _String(byte[] bytes, int ofs, int len) {
    return utf8ToString(bytes, ofs, len);
  }

  /**
   * @skip
   */
  static String _String(byte[] bytes, int ofs, int len, String charset)
      throws UnsupportedEncodingException {
    if (CHARSET_UTF8.equals(charset)) {
      return utf8ToString(bytes, ofs, len);
    } else if (CHARSET_8859_1.equals(charset) || CHARSET_LATIN1.equals(charset)) {
      return latin1ToString(bytes, ofs, len);
    } else {
      throw new UnsupportedEncodingException("Charset " + charset
          + " not supported");
    }
  }

  /**
   * @skip
   */
  static String _String(byte[] bytes, String charsetName)
      throws UnsupportedEncodingException {
    return _String(bytes, 0, bytes.length, charsetName);
  }

  /**
   * @skip
   */
  static String _String(char value[]) {
    return valueOf(value);
  }

  /**
   * @skip
   */
  static String _String(char value[], int offset, int count) {
    return valueOf(value, offset, count);
  }

  /**
   * @skip
   */
  static String _String(int[] codePoints, int offset, int count) {
    char[] chars = new char[count * 2];
    int charIdx = 0;
    while (count-- > 0) {
      charIdx += Character.toChars(codePoints[offset++], chars, charIdx);
    }
    return valueOf(chars, 0, charIdx);
  }

  /**
   * @skip
   */
  static String _String(String other) {
    return other;
  }

  /**
   * @skip
   */
  static String _String(StringBuffer sb) {
    return valueOf(sb);
  }

  /**
   * @skip
   */
  static String _String(StringBuilder sb) {
    return valueOf(sb);
  }

  private static native boolean __equals(String me, Object other) /*-{
    // Coerce me to a primitive string to force string comparison
    return String(me) == other;
  }-*/;

  // CHECKSTYLE_ON

  private static native int compareTo(String thisStr, String otherStr) /*-{
    // Coerce to a primitive string to force string comparison
    thisStr = String(thisStr);
    if (thisStr == otherStr) {
      return 0;
    }
    return thisStr < otherStr ? -1 : 1;
  }-*/;

  /**
   * Encode a single character in UTF8.
   * 
   * @param bytes byte array to store character in
   * @param ofs offset into byte array to store first byte
   * @param codePoint character to encode
   * @return number of bytes consumed by encoding the character
   * @throws IllegalArgumentException if codepoint >= 2^26
   */
  private static int encodeUtf8(byte[] bytes, int ofs, int codePoint) {
    if (codePoint < (1 << 7)) {
      bytes[ofs] = (byte) (codePoint & 127);
      return 1;
    } else if (codePoint < (1 << 11)) {
      // 110xxxxx 10xxxxxx
      bytes[ofs++] = (byte) (((codePoint >> 6) & 31) | 0xC0);
      bytes[ofs] = (byte) ((codePoint & 63) | 0x80);
      return 2;
    } else if (codePoint < (1 << 16)) {
      // 1110xxxx 10xxxxxx 10xxxxxx
      bytes[ofs++] = (byte) (((codePoint >> 12) & 15) | 0xE0);
      bytes[ofs++] = (byte) (((codePoint >> 6) & 63) | 0x80);
      bytes[ofs] = (byte) ((codePoint & 63) | 0x80);
      return 3;
    } else if (codePoint < (1 << 21)) {
      // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
      bytes[ofs++] = (byte) (((codePoint >> 18) & 7) | 0xF0);
      bytes[ofs++] = (byte) (((codePoint >> 12) & 63) | 0x80);
      bytes[ofs++] = (byte) (((codePoint >> 6) & 63) | 0x80);
      bytes[ofs] = (byte) ((codePoint & 63) | 0x80);
      return 4;
    } else if (codePoint < (1 << 26)) {
      // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
      bytes[ofs++] = (byte) (((codePoint >> 24) & 3) | 0xF8);
      bytes[ofs++] = (byte) (((codePoint >> 18) & 63) | 0x80);
      bytes[ofs++] = (byte) (((codePoint >> 12) & 63) | 0x80);
      bytes[ofs++] = (byte) (((codePoint >> 6) & 63) | 0x80);
      bytes[ofs] = (byte) ((codePoint & 63) | 0x80);
      return 5;
    }
    throw new IllegalArgumentException("Character out of range: " + codePoint);
  }

  private static native String fromCharCode(char ch) /*-{
    return String.fromCharCode(ch);
  }-*/;

  private static String fromCodePoint(int codePoint) {
    if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
      char hiSurrogate = Character.getHighSurrogate(codePoint);
      char loSurrogate = Character.getLowSurrogate(codePoint);
      return String.fromCharCode(hiSurrogate)
          + String.fromCharCode(loSurrogate);
    } else {
      return String.fromCharCode((char) codePoint);
    }
  }

  private static byte[] getBytesLatin1(String str) {
    int n = str.length();
    byte[] bytes = new byte[n];
    for (int i = 0; i < n; ++i) {
      bytes[i] = (byte) (str.charAt(i) & 255);
    }
    return bytes;
  }

  private static byte[] getBytesUtf8(String str) {
    // TODO(jat): consider using unescape(encodeURIComponent(bytes)) instead
    int n = str.length();
    int byteCount = 0;
    for (int i = 0; i < n; ) {
      int ch = str.codePointAt(i);
      i += Character.charCount(ch);
      if (ch < (1 << 7)) {
        byteCount++;
      } else if (ch < (1 << 11)) {
        byteCount += 2;
      } else if (ch < (1 << 16)) {
        byteCount += 3;
      } else if (ch < (1 << 21)) {
        byteCount += 4;
      } else if (ch < (1 << 26)) {
        byteCount += 5;
      }
    }
    byte[] bytes = new byte[byteCount];
    int out = 0;
    for (int i = 0; i < n; ) {
      int ch = str.codePointAt(i);
      i += Character.charCount(ch);
      out += encodeUtf8(bytes, out, ch);
    }
    return bytes;
  }

  private static String latin1ToString(byte[] bytes, int ofs, int len) {
    char[] chars = new char[len];
    for (int i = 0; i < len; ++i) {
      chars[i] = (char) (bytes[ofs + i] & 255);
    }
    return valueOf(chars);
  }

  private static native boolean regionMatches(String thisStr,
      boolean ignoreCase, int toffset, String other, int ooffset, int len) /*-{
    if (toffset < 0 || ooffset < 0 || len <= 0) {
      return false;
    }

    if (toffset + len > thisStr.length || ooffset + len > other.length) {
      return false;
    }

    var left = thisStr.substr(toffset, len);
    var right = other.substr(ooffset, len);

    if (ignoreCase) {
      left = left.toLowerCase();
      right = right.toLowerCase();
    }

    return left == right;
  }-*/;

  private static String utf8ToString(byte[] bytes, int ofs, int len) {
    // TODO(jat): consider using decodeURIComponent(escape(bytes)) instead
    int charCount = 0;
    for (int i = 0; i < len; ) {
      ++charCount;
      byte ch = bytes[ofs + i];
      if ((ch & 0xC0) == 0x80) {
        throw new IllegalArgumentException("Invalid UTF8 sequence");
      } else if ((ch & 0x80) == 0) {
        ++i;
      } else if ((ch & 0xE0) == 0xC0) {
        i += 2;
      } else if ((ch & 0xF0) == 0xE0) {
        i += 3;
      } else if ((ch & 0xF8) == 0xF0) {
        i += 4;
      } else {
        // no 5+ byte sequences since max codepoint is less than 2^21
        throw new IllegalArgumentException("Invalid UTF8 sequence");
      }
      if (i > len) {
        throw new IndexOutOfBoundsException("Invalid UTF8 sequence");
      }
    }
    char[] chars = new char[charCount];
    int outIdx = 0;
    int count = 0;
    for (int i = 0; i < len; ) {
      int ch = bytes[ofs + i++];
      if ((ch & 0x80) == 0) {
        count = 1;
        ch &= 127;
      } else if ((ch & 0xE0) == 0xC0) {
        count = 2;
        ch &= 31;
      } else if ((ch & 0xF0) == 0xE0) {
        count = 3;
        ch &= 15;
      } else if ((ch & 0xF8) == 0xF0) {
        count = 4;
        ch &= 7;
      } else if ((ch & 0xFC) == 0xF8) {
        count = 5;
        ch &= 3;
      }
      while (--count > 0) {
        byte b = bytes[ofs + i++];
        if ((b & 0xC0) != 0x80) {
          throw new IllegalArgumentException("Invalid UTF8 sequence at "
              + (ofs + i - 1) + ", byte=" + Integer.toHexString(b));
        }
        ch = (ch << 6) | (b & 63);
      }
      outIdx += Character.toChars(ch, chars, outIdx);
    }
    return valueOf(chars);
  }

  public String() {
    // magic delegation to _String
    _String();
  }

  public String(byte[] bytes) {
    // magic delegation to _String
    _String(bytes);
  }

  public String(byte[] bytes, int ofs, int len) {
    // magic delegation to _String
    _String(bytes, ofs, len);
  }

  public String(byte[] bytes, int ofs, int len, String charsetName)
      throws UnsupportedEncodingException {
    // magic delegation to _String
    _String(bytes, ofs, len, charsetName);
  }

  public String(byte[] bytes, String charsetName)
      throws UnsupportedEncodingException {
    // magic delegation to _String
    _String(bytes, charsetName);
  }

  public String(char value[]) {
    // magic delegation to _String
    _String(value);
  }

  public String(char value[], int offset, int count) {
    // magic delegation to _String
    _String(value, offset, count);
  }

  public String(int codePoints[], int offset, int count) {
    // magic delegation to _String
    _String(codePoints, offset, count);
  }

  public String(String other) {
    // magic delegation to _String
    _String(other);
  }

  public String(StringBuffer sb) {
    // magic delegation to _String
    _String(sb);
  }

  public String(StringBuilder sb) {
    // magic delegation to _String
    _String(sb);
  }

  public native char charAt(int index) /*-{
    return this.charCodeAt(index);
  }-*/;

  public int codePointAt(int index) {
    return Character.codePointAt(this, index, length());
  }

  public int codePointBefore(int index) {
    return Character.codePointBefore(this, index, 0);
  }

  public int codePointCount(int beginIndex, int endIndex) {
    return Character.codePointCount(this, beginIndex, endIndex);
  }

  public int compareTo(String other) {
    return compareTo(this, other);
  }

  public int compareToIgnoreCase(String other) {
    return compareTo(toLowerCase(), other.toLowerCase());
  }

  public native String concat(String str) /*-{
    return this + str;
  }-*/;

  public boolean contains(CharSequence s) {
    return indexOf(s.toString()) != -1;
  }

  public boolean contentEquals(CharSequence cs) {
    return equals(cs.toString());
  }

  public boolean contentEquals(StringBuffer sb) {
    return equals(sb.toString());
  }

  public native boolean endsWith(String suffix) /*-{
    return (this.lastIndexOf(suffix) != -1) && (this.lastIndexOf(suffix) == (this.length - suffix.length));
  }-*/;

  @Override
  public boolean equals(Object other) {
    if (!(other instanceof String)) {
      return false;
    }
    return __equals(this, other);
  }

  public native boolean equalsIgnoreCase(String other) /*-{
    if (other == null)
      return false;
    return (this == other) || (this.toLowerCase() == other.toLowerCase());
  }-*/;

  public byte[] getBytes() {
    // default character set for GWT is UTF-8
    return getBytesUtf8(this);
  }

  public byte[] getBytes(String charSet) throws UnsupportedEncodingException {
    if (CHARSET_UTF8.equals(charSet)) {
      return getBytesUtf8(this);
    }
    if (CHARSET_8859_1.equals(charSet) || CHARSET_LATIN1.equals(charSet)) {
      return getBytesLatin1(this);
    }
    throw new UnsupportedEncodingException(charSet + " is not supported");
  }

  public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) {
    for (int srcIdx = srcBegin; srcIdx < srcEnd; ++srcIdx) {
      dst[dstBegin++] = charAt(srcIdx);
    }
  }

  @Override
  public int hashCode() {
    return HashCache.getHashCode(this);
  }

  public int indexOf(int codePoint) {
    return indexOf(fromCodePoint(codePoint));
  }

  public int indexOf(int codePoint, int startIndex) {
    return this.indexOf(String.fromCodePoint(codePoint), startIndex);
  }

  public native int indexOf(String str) /*-{
    return this.indexOf(str);
  }-*/;

  public native int indexOf(String str, int startIndex) /*-{
    return this.indexOf(str, startIndex);
  }-*/;

  public native String intern() /*-{
    return String(this);
  }-*/;

  public native boolean isEmpty() /*-{
    return !this.length;
  }-*/;

  public int lastIndexOf(int codePoint) {
    return lastIndexOf(fromCodePoint(codePoint));
  }

  public int lastIndexOf(int codePoint, int startIndex) {
    return lastIndexOf(fromCodePoint(codePoint), startIndex);
  }

  public native int lastIndexOf(String str) /*-{
    return this.lastIndexOf(str);
  }-*/;

  public native int lastIndexOf(String str, int start) /*-{
    return this.lastIndexOf(str, start);
  }-*/;

  public native int length() /*-{
    return this.length;
  }-*/;

  /**
   * Regular expressions vary from the standard implementation. The
   * <code>regex</code> parameter is interpreted by JavaScript as a JavaScript
   * regular expression. For consistency, use only the subset of regular
   * expression syntax common to both Java and JavaScript.
   * 
   * TODO(jat): properly handle Java regex syntax
   */
  public native boolean matches(String regex) /*-{
    var matchObj = new RegExp(regex).exec(this);
    // if there is no match at all, matchObj will be null 
    // matchObj[0] is the entire matched string
    return (matchObj == null) ? false : (this == matchObj[0]);
  }-*/;

  public int offsetByCodePoints(int index, int codePointOffset) {
    return Character.offsetByCodePoints(this, index, codePointOffset);
  }

  public boolean regionMatches(boolean ignoreCase, int toffset, String other,
      int ooffset, int len) {
    if (other == null) {
      throw new NullPointerException();
    }
    return regionMatches(this, ignoreCase, toffset, other, ooffset, len);
  }

  public boolean regionMatches(int toffset, String other, int ooffset, int len) {
    if (other == null) {
      throw new NullPointerException();
    }
    return regionMatches(this, false, toffset, other, ooffset, len);
  }

  public native String replace(char from, char to) /*-{

    // We previously used \\uXXXX, but Safari 2 doesn't match them properly 
// in RegExp
    // See http://bugs.webkit.org/show_bug.cgi?id=8043
    //     http://bugs.webkit.org/show_bug.cgi?id=6257
    //     http://bugs.webkit.org/show_bug.cgi?id=7253
    var regex;
    if (from < 256) {
      regex = @java.lang.Integer::toHexString(I)(from);
      regex = '\\x' + "00".substring(regex.length) + regex;
    } else {
      // this works because characters above 255 can't be regex special chars
      regex = String.fromCharCode(from);
    }
    return this.replace(RegExp(regex, "g"), String.fromCharCode(to));
  }-*/;

  public String replace(CharSequence from, CharSequence to) {
    // Implementation note: This uses a regex replacement instead of
    // a string literal replacement because Safari does not
    // follow the spec for "$$" in the replacement string: it
    // will insert a literal "$$". IE and Firefox, meanwhile,
    // treat "$$" as "$".
    
    // Escape regex special characters from literal replacement string.
    String regex = from.toString().replaceAll("([/\\\\\\.\\*\\+\\?\\|\\(\\)\\[\\]\\{\\}$^])", "\\\\$1");
    // Escape $ since it is for match backrefs and \ since it is used to escape
    // $.
    String replacement = to.toString().replaceAll("\\\\", "\\\\\\\\").replaceAll("\\$", "\\\\$");

    return replaceAll(regex, replacement);
  }

  /**
   * Regular expressions vary from the standard implementation. The
   * <code>regex</code> parameter is interpreted by JavaScript as a JavaScript
   * regular expression. For consistency, use only the subset of regular
   * expression syntax common to both Java and JavaScript.
   * 
   * TODO(jat): properly handle Java regex syntax
   */
  public native String replaceAll(String regex, String replace) /*-{
    replace = @java.lang.String::__translateReplaceString(Ljava/lang/String;)(replace);
    return this.replace(RegExp(regex, "g"), replace);
  }-*/;

  /**
   * Regular expressions vary from the standard implementation. The
   * <code>regex</code> parameter is interpreted by JavaScript as a JavaScript
   * regular expression. For consistency, use only the subset of regular
   * expression syntax common to both Java and JavaScript.
   * 
   * TODO(jat): properly handle Java regex syntax
   */
  public native String replaceFirst(String regex, String replace) /*-{
    replace = @java.lang.String::__translateReplaceString(Ljava/lang/String;)(replace);
    return this.replace(RegExp(regex), replace);
  }-*/;

  /**
   * Regular expressions vary from the standard implementation. The
   * <code>regex</code> parameter is interpreted by JavaScript as a JavaScript
   * regular expression. For consistency, use only the subset of regular
   * expression syntax common to both Java and JavaScript.
   */
  public String[] split(String regex) {
    return split(regex, 0);
  }

  /**
   * Regular expressions vary from the standard implementation. The
   * <code>regex</code> parameter is interpreted by JavaScript as a JavaScript
   * regular expression. For consistency, use only the subset of regular
   * expression syntax common to both Java and JavaScript.
   * 
   * TODO(jat): properly handle Java regex syntax
   */
  public native String[] split(String regex, int maxMatch) /*-{
    // The compiled regular expression created from the string
    var compiled = new RegExp(regex, "g");
    // the Javascipt array to hold the matches prior to conversion
    var out = [];
    // how many matches performed so far
    var count = 0;
    // The current string that is being matched; trimmed as each piece matches
    var trail = this;
    // used to detect repeated zero length matches
    // Must be null to start with because the first match of "" makes no 
    // progress by intention
    var lastTrail = null;
    // We do the split manually to avoid Javascript incompatibility
    while (true) {
      // None of the information in the match returned are useful as we have no 
      // subgroup handling
      var matchObj = compiled.exec(trail);
      if (matchObj == null || trail == "" || (count == (maxMatch - 1) && maxMatch > 0)) {
        out[count] = trail;
        break;
      } else {
        out[count] = trail.substring(0, matchObj.index);
        trail = trail.substring(matchObj.index + matchObj[0].length, trail.length);
        // Force the compiled pattern to reset internal state
        compiled.lastIndex = 0;
        // Only one zero length match per character to ensure termination
        if (lastTrail == trail) {
          out[count] = trail.substring(0, 1);
          trail = trail.substring(1);
        }
        lastTrail = trail;
        count++;
      }
    }
    // all blank delimiters at the end are supposed to disappear if maxMatch == 0;
    // however, if the input string is empty, the output should consist of a
    // single empty string
    if (maxMatch == 0 && this.length > 0) {
      var lastNonEmpty = out.length;
      while (lastNonEmpty > 0 && out[lastNonEmpty - 1] == "") {
        --lastNonEmpty;
      }
      if (lastNonEmpty < out.length) {
        out.splice(lastNonEmpty, out.length - lastNonEmpty);
      }
    }
    var jr = @java.lang.String::__createArray(I)(out.length);
    for ( var i = 0; i < out.length; ++i) {
      jr[i] = out[i];
    }
    return jr;
  }-*/;

  public boolean startsWith(String prefix) {
    return indexOf(prefix) == 0;
  }

  public boolean startsWith(String prefix, int toffset) {
    if (toffset < 0 || toffset >= length()) {
      return false;
    } else {
      return indexOf(prefix, toffset) == toffset;
    }
  }

  public CharSequence subSequence(int beginIndex, int endIndex) {
    return this.substring(beginIndex, endIndex);
  }

  public native String substring(int beginIndex) /*-{
    return this.substr(beginIndex, this.length - beginIndex);
  }-*/;

  public native String substring(int beginIndex, int endIndex) /*-{
    return this.substr(beginIndex, endIndex - beginIndex);
  }-*/;

  public char[] toCharArray() {
    int n = this.length();
    char[] charArr = new char[n];
    getChars(0, n, charArr, 0);
    return charArr;
  }

  public native String toLowerCase() /*-{
    return this.toLowerCase();
  }-*/;

  @Override
  public String toString() {
    /*
     * Magic: this method is only used during compiler optimizations; the generated JS will instead alias
     * this method to the native String.prototype.toString() function.
     */
    return this;
  }

  public native String toUpperCase() /*-{
    return this.toUpperCase();
  }-*/;

  public native String trim() /*-{
    if (this.length == 0 || (this[0] > '\u0020' && this[this.length - 1] > '\u0020')) {
      return this;
    }
    var r1 = this.replace(/^(\s*)/, '');
    var r2 = r1.replace(/\s*$/, '');
    return r2;
  }-*/;
}
