Fix String.regionMatches.

String.regionMatches does not comply with the behaviour defined in its
documentation.

Change-Id: If75835a5334c539cb0c6624ab300c70d23dc8baa
diff --git a/user/super/com/google/gwt/emul/java/lang/String.java b/user/super/com/google/gwt/emul/java/lang/String.java
index 959f9e5..0b58db7 100644
--- a/user/super/com/google/gwt/emul/java/lang/String.java
+++ b/user/super/com/google/gwt/emul/java/lang/String.java
@@ -523,12 +523,15 @@
   public boolean regionMatches(boolean ignoreCase, int toffset, String other,
       int ooffset, int len) {
     checkNotNull(other);
-    if (toffset < 0 || ooffset < 0 || len <= 0) {
+    if (toffset < 0 || ooffset < 0) {
       return false;
     }
     if (toffset + len > length() || ooffset + len > other.length()) {
       return false;
     }
+    if (len <= 0) {
+      return true;
+    }
 
     String left = asNativeString().substr(toffset, len);
     String right = other.asNativeString().substr(ooffset, len);
diff --git a/user/test/com/google/gwt/emultest/java/lang/StringTest.java b/user/test/com/google/gwt/emultest/java/lang/StringTest.java
index 5265d62..05c1d00 100644
--- a/user/test/com/google/gwt/emultest/java/lang/StringTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/StringTest.java
@@ -670,6 +670,17 @@
     assertFalse(test.regionMatches(true, 1, "bCdx", 1, 3));
     assertTrue(test.regionMatches(true, 0, "xaBcd", 1, 4));
 
+    String empty = String.valueOf(new char[] {});
+    assertTrue(empty.regionMatches(true, 0, "", 0, 0));
+    assertTrue(empty.regionMatches(true, 0, " ", 0, 0));
+    assertFalse(empty.regionMatches(true, 0, " ", 0, 1));
+
+    assertTrue(test.regionMatches(true, 0, "xx", 0, -1));
+    assertFalse(test.regionMatches(true, -1, "xx", 0, 0));
+    assertFalse(test.regionMatches(true, 0, "xx", -1, 0));
+    assertFalse(test.regionMatches(true, -1, "F", 0, 1));
+    assertFalse(test.regionMatches(true, -1, "A", 0, 1));
+
     try {
       test.regionMatches(-1, null, -1, -1);
       fail();