Handle null CharSequence in StringBuilder/StringBuffer

Change-Id: I9f5c5681a34d29de8830249602aa0d74a197bb8c
diff --git a/user/super/com/google/gwt/emul/java/lang/AbstractStringBuilder.java b/user/super/com/google/gwt/emul/java/lang/AbstractStringBuilder.java
index 4aec949..dabfd83 100644
--- a/user/super/com/google/gwt/emul/java/lang/AbstractStringBuilder.java
+++ b/user/super/com/google/gwt/emul/java/lang/AbstractStringBuilder.java
@@ -21,14 +21,15 @@
  * Most methods will give expected performance results. Exception is {@link #setCharAt(int, char)},
  * which is O(n), and thus should not be used many times on the same <code>StringBuffer</code>.
  */
-abstract class AbstractStringBuilder {
+abstract class AbstractStringBuilder implements CharSequence, Appendable {
 
   String string;
 
-  public AbstractStringBuilder(String string) {
+  AbstractStringBuilder(String string) {
     this.string = string;
   }
 
+  @Override
   public int length() {
     return string.length();
   }
@@ -56,6 +57,7 @@
     // This implementation does not track capacity
   }
 
+  @Override
   public char charAt(int index) {
     return string.charAt(index);
   }
@@ -72,6 +74,7 @@
     replace0(index, index + 1, String.valueOf(x));
   }
 
+  @Override
   public CharSequence subSequence(int start, int end) {
     return string.substring(start, end);
   }
@@ -105,13 +108,6 @@
     return string;
   }
 
-  void append0(CharSequence x, int start, int end) {
-    if (x == null) {
-      x = "null";
-    }
-    string += x.subSequence(start, end);
-  }
-
   void appendCodePoint0(int x) {
     string += String.valueOf(Character.toChars(x));
   }
diff --git a/user/super/com/google/gwt/emul/java/lang/StringBuffer.java b/user/super/com/google/gwt/emul/java/lang/StringBuffer.java
index 79ee56d..39be45d 100644
--- a/user/super/com/google/gwt/emul/java/lang/StringBuffer.java
+++ b/user/super/com/google/gwt/emul/java/lang/StringBuffer.java
@@ -21,7 +21,7 @@
  * This class is an exact clone of {@link StringBuilder} except for the name.
  * Any change made to one should be mirrored in the other.
  */
-public final class StringBuffer extends AbstractStringBuilder implements CharSequence, Appendable {
+public final class StringBuffer extends AbstractStringBuilder {
 
   public StringBuffer() {
     super("");
@@ -73,7 +73,7 @@
 
   @Override
   public StringBuffer append(CharSequence x, int start, int end) {
-    append0(x, start, end);
+    string += String.valueOf(x).substring(start, end);
     return this;
   }
 
@@ -144,11 +144,11 @@
   }
 
   public StringBuffer insert(int index, CharSequence chars) {
-    return insert(index, chars.toString());
+    return insert(index, String.valueOf(chars));
   }
 
   public StringBuffer insert(int index, CharSequence chars, int start, int end) {
-    return insert(index, chars.subSequence(start, end).toString());
+    return insert(index, String.valueOf(chars).substring(start, end));
   }
 
   public StringBuffer insert(int index, double x) {
diff --git a/user/super/com/google/gwt/emul/java/lang/StringBuilder.java b/user/super/com/google/gwt/emul/java/lang/StringBuilder.java
index 8e70d5b..78bcd03 100644
--- a/user/super/com/google/gwt/emul/java/lang/StringBuilder.java
+++ b/user/super/com/google/gwt/emul/java/lang/StringBuilder.java
@@ -21,7 +21,7 @@
  * This class is an exact clone of {@link StringBuffer} except for the name.
  * Any change made to one should be mirrored in the other.
  */
-public final class StringBuilder extends AbstractStringBuilder implements CharSequence, Appendable {
+public final class StringBuilder extends AbstractStringBuilder {
 
   public StringBuilder() {
     super("");
@@ -73,7 +73,7 @@
 
   @Override
   public StringBuilder append(CharSequence x, int start, int end) {
-    append0(x, start, end);
+    string += String.valueOf(x).substring(start, end);
     return this;
   }
 
@@ -144,11 +144,11 @@
   }
 
   public StringBuilder insert(int index, CharSequence chars) {
-    return insert(index, chars.toString());
+    return insert(index, String.valueOf(chars));
   }
 
   public StringBuilder insert(int index, CharSequence chars, int start, int end) {
-    return insert(index, chars.subSequence(start, end).toString());
+    return insert(index, String.valueOf(chars).substring(start, end));
   }
 
   public StringBuilder insert(int index, double x) {
diff --git a/user/test/com/google/gwt/emultest/java/lang/StringBufferTest.java b/user/test/com/google/gwt/emultest/java/lang/StringBufferTest.java
index a8a7185..1d65b96 100644
--- a/user/test/com/google/gwt/emultest/java/lang/StringBufferTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/StringBufferTest.java
@@ -82,6 +82,14 @@
     x = new StringBuffer("k");
     x.append(new StringBuffer("lm"));
     assertEquals("klm", x.toString());
+
+    final CharSequence nullCharSequence = null;
+    x = new StringBuffer("!");
+    x.append(nullCharSequence);
+    assertEquals("!null", x.toString());
+    x = new StringBuffer("!");
+    x.append(nullCharSequence, 0, 3);
+    assertEquals("!nul", x.toString());
   }
 
   /**
@@ -188,6 +196,14 @@
     x = new StringBuffer("!");
     x.insert(1, C.TRUE_VALUE);
     assertEquals("!" + C.TRUE_STRING, x.toString());
+
+    final CharSequence nullCharSequence = null;
+    x = new StringBuffer("!");
+    x.insert(1, nullCharSequence);
+    assertEquals("!null", x.toString());
+    x = new StringBuffer("!");
+    x.insert(1, nullCharSequence, 0, 3);
+    assertEquals("!nul", x.toString());
   }
 
   /**