Fix various Charset tests, clean up the implementation.

Bug: 10211558
Bug: 10211378
Change-Id: Ib3f97430f62163c0459c53e0c282ae0ca840e0af
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetEncoderTest.java
index e48c4ef..ef219be 100644
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetEncoderTest.java
+++ b/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetEncoderTest.java
@@ -4,9 +4,9 @@
  * The ASF licenses this file to You 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.
@@ -88,16 +88,13 @@
 
 	public void testDefaultValue() {
 		assertEquals(CodingErrorAction.REPORT, encoder.malformedInputAction());
-		assertEquals(CodingErrorAction.REPORT, encoder
-				.unmappableCharacterAction());
+		assertEquals(CodingErrorAction.REPORT, encoder.unmappableCharacterAction());
 		assertSame(encoder, encoder.onMalformedInput(CodingErrorAction.IGNORE));
-		assertSame(encoder, encoder
-				.onUnmappableCharacter(CodingErrorAction.IGNORE));
+		assertSame(encoder, encoder.onUnmappableCharacter(CodingErrorAction.IGNORE));
 		if (encoder instanceof MockCharsetEncoder) {
 			assertTrue(Arrays.equals(encoder.replacement(), defaultReplacement));
 		} else {
-			assertTrue(Arrays.equals(encoder.replacement(),
-					specifiedReplacement));
+			assertTrue(Arrays.equals(encoder.replacement(), specifiedReplacement));
 		}
 
 	}
@@ -309,13 +306,13 @@
 		    // Expected
 		}
 	}
-	
+
 	public void testFlushAfterConstructing() {
 		ByteBuffer out = ByteBuffer.allocate(5);
-		
+
 		//Illegal state: flush after instance created
 		try {
-			encoder.flush(out);			
+			encoder.flush(out);
 			fail("should throw IllegalStateException");
 		} catch (IllegalStateException e) {
 			// Expected
@@ -529,13 +526,34 @@
 		// surrogate char for unicode
 		// 1st byte: d800-dbff
 		// 2nd byte: dc00-dfff
-		assertTrue(encoder.canEncode("\ud800"));
 		// valid surrogate pair
 		assertTrue(encoder.canEncode("\ud800\udc00"));
 		// invalid surrogate pair
 		assertTrue(encoder.canEncode("\ud800\udb00"));
 	}
 
+    public void test_canEncode_char_ICUBug() {
+        // The RI doesn't allow this, but icu4c does.
+        assertTrue(encoder.canEncode('\ud800'));
+    }
+
+    public void test_canEncode_CharSequence_ICUBug() {
+        // The RI doesn't allow this, but icu4c does.
+        assertTrue(encoder.canEncode("\ud800"));
+    }
+
+    public void test_canEncode_empty() throws Exception {
+        assertTrue(encoder.canEncode(""));
+    }
+
+    public void test_canEncode_null() throws Exception {
+        try {
+            encoder.canEncode(null);
+            fail();
+        } catch (NullPointerException e) {
+        }
+    }
+
 	/*
 	 * Class under test for Charset charset()
 	 */
@@ -571,7 +589,7 @@
 		out = encoder.encode(CharBuffer.wrap(unistr));
 		assertEquals(out.position(), 0);
 		assertByteArray(out, addSurrogate(unibytes));
-        
+
         // Regression test for harmony-3378
         Charset cs = Charset.forName("UTF-8");
         CharsetEncoder encoder = cs.newEncoder();
@@ -580,7 +598,7 @@
                 (byte) 0xbd, });
         CharBuffer in = CharBuffer.wrap("\ud800");
         out = encoder.encode(in);
-        assertNotNull(out); 
+        assertNotNull(out);
 	}
 
 	private byte[] addSurrogate(byte[] expected) {
@@ -917,14 +935,19 @@
 	/*
 	 * test isLegalReplacement(byte[])
 	 */
-	public void testIsLegalReplacement() {
+	public void test_isLegalReplacement_null() {
 		try {
 			encoder.isLegalReplacement(null);
 			fail("should throw null pointer exception");
 		} catch (NullPointerException e) {
 		}
-		assertTrue(encoder.isLegalReplacement(specifiedReplacement));
+	}
 
+	public void test_isLegalReplacement_good() {
+		assertTrue(encoder.isLegalReplacement(specifiedReplacement));
+	}
+
+	public void test_isLegalReplacement_bad() {
 		assertTrue(encoder.isLegalReplacement(new byte[200]));
 		byte[] ba = getIllegalByteArray();
 		if (ba != null) {
@@ -932,14 +955,10 @@
 		}
 	}
 
-	public void testIsLegalReplacementEmptyArray() {
+	public void test_isLegalReplacement_empty_array() {
 		// ISO, ASC, GB, UTF8 encoder will throw exception in RI
 		// others will pass
-		// try {
 		assertTrue(encoder.isLegalReplacement(new byte[0]));
-		// fail("should throw ArrayIndexOutOfBoundsException");
-		// } catch (ArrayIndexOutOfBoundsException e) {
-		// }
 	}
 
 	public void testOnMalformedInput() {
@@ -990,7 +1009,7 @@
 		nr = getIllegalByteArray();
 		try {
 			encoder.replaceWith(new byte[100]);
-			fail("should throw null pointer exception");
+			fail();
 		} catch (IllegalArgumentException e) {
 		}
 	}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetTest.java
index 34d84ba..c658c48 100644
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetTest.java
+++ b/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetTest.java
@@ -708,8 +708,7 @@
      */
     public void test_availableCharsets() throws Exception {
         // regression test for Harmony-1051
-        ClassLoader originalClassLoader = Thread.currentThread()
-                .getContextClassLoader();
+        ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
         try {
             Thread.currentThread().setContextClassLoader(null);
             SortedMap<String, Charset> charsets = Charset.availableCharsets();
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetEncoderTest.java
index 3caabde..ab4eeea 100644
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetEncoderTest.java
+++ b/harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetEncoderTest.java
@@ -57,15 +57,12 @@
 	 * Class under test for boolean canEncode(CharSequence)
 	 */
 	public void testCanEncodeCharSequence() {
-		assertTrue(encoder.canEncode(""));
 		// surrogate char
 
 		// valid surrogate pair
 		assertTrue(encoder.canEncode("\ud800\udc00"));
 		// invalid surrogate pair
 		assertFalse(encoder.canEncode("\ud800\udb00"));
-		// The RI doesn't allow this, but we do.
-		//assertFalse(encoder.canEncode("\ud800"));
 	}
 
 	public void testSpecificDefaultValue() {
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetEncoderTest.java
index 7d7bca3..8a84938 100644
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetEncoderTest.java
+++ b/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetEncoderTest.java
@@ -4,9 +4,9 @@
  * The ASF licenses this file to You 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.
@@ -21,6 +21,7 @@
 import java.nio.charset.Charset;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
+import java.nio.charset.MalformedInputException;
 import java.nio.charset.UnmappableCharacterException;
 
 /**
@@ -46,29 +47,19 @@
 		super.tearDown();
 	}
 
-	public void testCanEncodeCharSequence() {
+	@Override public void testCanEncodeCharSequence() {
 		// normal case for isoCS
 		assertTrue(encoder.canEncode("\u0077"));
 		assertFalse(encoder.canEncode("\uc2a3"));
 		assertFalse(encoder.canEncode("\ud800\udc00"));
-		try {
-			encoder.canEncode(null);
-		} catch (NullPointerException e) {
-		}
-		assertTrue(encoder.canEncode(""));
 	}
 
-	public void testCanEncodeICUBug() {
-		assertFalse(encoder.canEncode((char) '\ud800'));
-		assertFalse(encoder.canEncode((String) "\ud800"));
-	}
-
-	public void testCanEncodechar() throws CharacterCodingException {
+	@Override public void testCanEncodechar() throws CharacterCodingException {
 		assertTrue(encoder.canEncode('\u0077'));
 		assertFalse(encoder.canEncode('\uc2a3'));
 	}
 
-	public void testSpecificDefaultValue() {
+	@Override public void testSpecificDefaultValue() {
 		assertEquals(1, encoder.averageBytesPerChar(), 0.001);
 		assertEquals(1, encoder.maxBytesPerChar(), 0.001);
 	}
@@ -98,15 +89,5 @@
 		} catch (UnmappableCharacterException e) {
 		}
 		encoder.reset();
-		ByteBuffer out = ByteBuffer.allocate(10);
-		assertTrue(encoder.encode(CharBuffer.wrap("\ud800"), out, true)
-				.isMalformed());
-		encoder.flush(out);
-		encoder.reset();
-		out = ByteBuffer.allocate(10);
-		assertSame(CoderResult.UNDERFLOW, encoder.encode(CharBuffer
-				.wrap("\ud800"), out, false));
-		assertTrue(encoder.encode(CharBuffer.wrap("\udc00"), out, true)
-				.isMalformed());
 	}
 }
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetEncoderTest.java
index 70a1786..68bd2f5 100644
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetEncoderTest.java
+++ b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetEncoderTest.java
@@ -4,9 +4,9 @@
  * The ASF licenses this file to You 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.
@@ -68,7 +68,6 @@
 		// normal case for utfCS
 		assertTrue(encoder.canEncode("\u0077"));
 		assertTrue(encoder.canEncode("\uc2a3"));
-		assertTrue(encoder.canEncode(""));
 
 		// for non-mapped char
 		assertTrue(encoder.canEncode("\uc2c0"));
@@ -82,10 +81,6 @@
 		assertFalse(encoder.canEncode("\ud800\udb00"));
 	}
 
-	public void testCanEncodeICUBug() {
-		assertFalse(encoder.canEncode("\ud800"));
-	}
-
 	public void testSpecificDefaultValue() {
 		assertEquals(2, encoder.averageBytesPerChar(), 0.001);
 		assertEquals(2, encoder.maxBytesPerChar(), 0.001);
@@ -103,15 +98,8 @@
 		return null;
 	}
 
-	public void testIsLegalReplacementEmptyArray() {
-		assertTrue(encoder.isLegalReplacement(new byte[0]));
-	}
-
 	protected byte[] getIllegalByteArray() {
-		// FIXME: different here
-		// cannot replace by 0xd8d8, but RI can
-		// return new byte[]{(byte)0xd8, (byte)0xd8};
-		return new byte[] { 0 };
+	  return new byte[] { (byte)0xd8, (byte)0x00, (byte)0xdb, (byte)0x00 };
 	}
 
 	protected byte[] getLegalByteArray() {
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetDecoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetDecoderTest.java
index 51daaf6..c5bb408 100644
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetDecoderTest.java
+++ b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetDecoderTest.java
@@ -4,9 +4,9 @@
  * The ASF licenses this file to You 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.
@@ -25,7 +25,7 @@
 import java.nio.charset.CodingErrorAction;
 
 /**
- * 
+ *
  */
 public class UTF16CharsetDecoderTest extends CharsetDecoderTest {
 
@@ -66,49 +66,6 @@
         return ByteBuffer.wrap(bytes);
     }
 
-    public void testMultiStepDecode() throws CharacterCodingException {
-        if (!cs.name().equals("mock")) {
-            decoder.onMalformedInput(CodingErrorAction.REPORT);
-            decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
-            CharBuffer out = CharBuffer.allocate(10);
-            assertTrue(decoder.decode(
-                    ByteBuffer.wrap(new byte[] { -1, -2, 32, 0, 98 }), out,
-                    true).isMalformed());
-
-            decoder.flush(out);
-            decoder.reset();
-            out.clear();
-            assertSame(CoderResult.UNDERFLOW, decoder.decode(ByteBuffer
-                    .wrap(new byte[] { -1, -2, 32, 0 }), out, false));
-            assertTrue(decoder.decode(ByteBuffer.wrap(new byte[] { 98 }), out,
-                    true).isMalformed());
-
-            decoder.flush(out);
-            decoder.reset();
-            out.clear();
-            assertSame(CoderResult.UNDERFLOW, decoder.decode(ByteBuffer
-                    .wrap(new byte[] { -1, -2, 32, 0, 98 }), out, false));
-            assertFalse(decoder.decode(ByteBuffer.wrap(new byte[] {}), out,
-                    true).isMalformed());
-
-            decoder.flush(out);
-            decoder.reset();
-            out.clear();
-            assertFalse(decoder.decode(
-                    ByteBuffer.wrap(new byte[] { -1, -2, 32, 0, 98, 0 }), out,
-                    true).isError());
-
-            decoder.flush(out);
-            decoder.reset();
-            out.clear();
-            assertSame(CoderResult.UNDERFLOW, decoder.decode(ByteBuffer
-                    .wrap(new byte[] { -1, -2, 32, 0, 98 }), out, false));
-            assertTrue(decoder.decode(ByteBuffer.wrap(new byte[] { 0 }), out,
-                    true).isMalformed());
-
-        }
-    }
-
     public void testLittleEndianByteBufferCharBuffer()
             throws CharacterCodingException, UnsupportedEncodingException {
         bigEndian = false;
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetEncoderTest.java
index c113c08..6a42d41 100644
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetEncoderTest.java
+++ b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetEncoderTest.java
@@ -4,9 +4,9 @@
  * The ASF licenses this file to You 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.
@@ -38,7 +38,7 @@
 	 */
 	protected void setUp() throws Exception {
 		cs = CS;
-		specifiedReplacement = new byte[] { -1, -3 };
+		specifiedReplacement = new byte[] { -3, -1 };
 		surrogate = new byte[] { -1, -2 };
 		unibytes = new byte[] { 32, 0, 98, 0, 117, 0, 102, 0, 102, 0, 101, 0,
 				114, 0 };
@@ -71,7 +71,6 @@
 		// normal case for utfCS
 		assertTrue(encoder.canEncode("\u0077"));
 		assertTrue(encoder.canEncode("\uc2a3"));
-		assertTrue(encoder.canEncode(""));
 
 		// for non-mapped char
 		assertTrue(encoder.canEncode("\uc2c0"));
@@ -85,11 +84,6 @@
 		assertFalse(encoder.canEncode("\ud800\udb00"));
 	}
 
-	public void testCanEncodeICUBug() {
-		assertFalse(encoder.canEncode('\ud800'));
-		assertFalse(encoder.canEncode("\ud800"));
-	}
-
 	public void testSpecificDefaultValue() {
 		assertEquals(encoder.averageBytesPerChar(), 2, 0.001);
 		// assertEquals(4, encoder.maxBytesPerChar());
@@ -109,12 +103,8 @@
 		return null;
 	}
 
-	public void testIsLegalReplacementEmptyArray() {
-		assertTrue(encoder.isLegalReplacement(new byte[0]));
-	}
-
 	protected byte[] getIllegalByteArray() {
-		return new byte[] { 0x00 };
+	  return new byte[] { (byte)0xd8, (byte)0x00, (byte)0xdb, (byte)0x00 };
 	}
 
 	protected byte[] getLegalByteArray() {
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetEncoderTest.java
index 26bae5c..1e9187d 100644
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetEncoderTest.java
+++ b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetEncoderTest.java
@@ -4,9 +4,9 @@
  * The ASF licenses this file to You 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.
@@ -68,7 +68,6 @@
 		// normal case for utfCS
 		assertTrue(encoder.canEncode("\u0077"));
 		assertTrue(encoder.canEncode("\uc2a3"));
-		assertTrue(encoder.canEncode(""));
 
 		// for non-mapped char
 		assertTrue(encoder.canEncode("\uc2c0"));
@@ -82,19 +81,11 @@
 		assertFalse(encoder.canEncode("\ud800\udb00"));
 	}
 
-	public void testCanEncodeICUBug() {
-		assertFalse(encoder.canEncode("\ud800"));
-	}
-
 	public void testSpecificDefaultValue() {
 		assertEquals(2, encoder.averageBytesPerChar(), 0.001);
 		assertEquals(2, encoder.maxBytesPerChar(), 0.001);
 	}
 
-	public void testIsLegalReplacementEmptyArray() {
-		assertTrue(encoder.isLegalReplacement(new byte[0]));
-	}
-
 	CharBuffer getMalformedCharBuffer() {
 		return CharBuffer.wrap("\ud800 buffer");
 	}
@@ -108,7 +99,7 @@
 	}
 
 	protected byte[] getIllegalByteArray() {
-		return new byte[] { 0x00 };
+	  return new byte[] { (byte)0x00, (byte)0xd8, (byte)0x00, (byte)0xdb };
 	}
 
 	protected byte[] getLegalByteArray() {
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetEncoderTest.java
index 0096856..798a048 100644
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetEncoderTest.java
+++ b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetEncoderTest.java
@@ -4,9 +4,9 @@
  * The ASF licenses this file to You 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.
@@ -57,7 +57,6 @@
 		// normal case for utfCS
 		assertTrue(encoder.canEncode("\u0077"));
 		assertTrue(encoder.canEncode("\uc2a3"));
-		assertTrue(encoder.canEncode(""));
 
 		// for non-mapped char
 		assertTrue(encoder.canEncode("\uc2c0"));
@@ -71,10 +70,6 @@
 		assertFalse(encoder.canEncode("\ud800\udb00"));
 	}
 
-	public void testCanEncodeICUBug() {
-		assertFalse(encoder.canEncode("\ud800"));
-	}
-
 	public void testSpecificDefaultValue() {
 		assertEquals(1.1, encoder.averageBytesPerChar(), 0.0001);
 		// assertEquals(2, encoder.averageBytesPerChar(), 0.0001);
diff --git a/luni/src/main/java/java/nio/charset/CharsetDecoder.java b/luni/src/main/java/java/nio/charset/CharsetDecoder.java
index 1559db4..7aa546c 100644
--- a/luni/src/main/java/java/nio/charset/CharsetDecoder.java
+++ b/luni/src/main/java/java/nio/charset/CharsetDecoder.java
@@ -303,12 +303,8 @@
      *             method threw an <code>BufferUnderflowException</code> or
      *             <code>BufferOverflowException</code>.
      */
-    public final CoderResult decode(ByteBuffer in, CharBuffer out,
-            boolean endOfInput) {
-        /*
-         * status check
-         */
-        if ((status == FLUSH) || (!endOfInput && status == END)) {
+    public final CoderResult decode(ByteBuffer in, CharBuffer out, boolean endOfInput) {
+        if (status == FLUSH || (!endOfInput && status == END)) {
             throw new IllegalStateException();
         }
 
diff --git a/luni/src/main/java/java/nio/charset/CharsetEncoder.java b/luni/src/main/java/java/nio/charset/CharsetEncoder.java
index 8f02f96..c2d74a1 100644
--- a/luni/src/main/java/java/nio/charset/CharsetEncoder.java
+++ b/luni/src/main/java/java/nio/charset/CharsetEncoder.java
@@ -163,65 +163,27 @@
     }
 
     /**
-     * Checks if the given character can be encoded by this encoder.
-     * <p>
-     * Note that this method can change the internal status of this encoder, so
+     * Tests whether the given character can be encoded by this encoder.
+     *
+     * <p>Note that this method may change the internal status of this encoder, so
      * it should not be called when another encoding process is ongoing,
      * otherwise it will throw an <code>IllegalStateException</code>.
-     * <p>
-     * This method can be overridden for performance improvement.
      *
-     * @param c
-     *            the given encoder.
-     * @return true if given character can be encoded by this encoder.
-     * @throws IllegalStateException
-     *             if another encode process is ongoing so that the current
-     *             internal status is neither RESET or FLUSH.
+     * @throws IllegalStateException if another encode process is ongoing.
      */
     public boolean canEncode(char c) {
-        return implCanEncode(CharBuffer.wrap(new char[] { c }));
-    }
-
-    // implementation of canEncode
-    private boolean implCanEncode(CharBuffer cb) {
-        if (status == FLUSH || status == INIT) {
-            status = READY;
-        }
-        if (status != READY) {
-            throw new IllegalStateException("encoding already in progress");
-        }
-        CodingErrorAction malformBak = malformedInputAction;
-        CodingErrorAction unmapBak = unmappableCharacterAction;
-        onMalformedInput(CodingErrorAction.REPORT);
-        onUnmappableCharacter(CodingErrorAction.REPORT);
-        boolean result = true;
-        try {
-            this.encode(cb);
-        } catch (CharacterCodingException e) {
-            result = false;
-        }
-        onMalformedInput(malformBak);
-        onUnmappableCharacter(unmapBak);
-        reset();
-        return result;
+        return canEncode(CharBuffer.wrap(new char[] { c }));
     }
 
     /**
-     * Checks if a given <code>CharSequence</code> can be encoded by this
+     * Tests whether the given <code>CharSequence</code> can be encoded by this
      * encoder.
      *
-     * Note that this method can change the internal status of this encoder, so
+     * <p>Note that this method may change the internal status of this encoder, so
      * it should not be called when another encode process is ongoing, otherwise
      * it will throw an <code>IllegalStateException</code>.
      *
-     * This method can be overridden for performance improvement.
-     *
-     * @param sequence
-     *            the given <code>CharSequence</code>.
-     * @return true if the given <code>CharSequence</code> can be encoded by
-     *         this encoder.
-     * @throws IllegalStateException
-     *             if current internal status is neither RESET or FLUSH.
+     * @throws IllegalStateException if another encode process is ongoing.
      */
     public boolean canEncode(CharSequence sequence) {
         CharBuffer cb;
@@ -230,7 +192,27 @@
         } else {
             cb = CharBuffer.wrap(sequence);
         }
-        return implCanEncode(cb);
+
+        if (status == FLUSH || status == INIT) {
+            status = READY;
+        }
+        if (status != READY) {
+            throw new IllegalStateException();
+        }
+        CodingErrorAction originalMalformedInputAction = malformedInputAction;
+        CodingErrorAction originalUnmappableCharacterAction = unmappableCharacterAction;
+        onMalformedInput(CodingErrorAction.REPORT);
+        onUnmappableCharacter(CodingErrorAction.REPORT);
+        try {
+            this.encode(cb);
+            return true;
+        } catch (CharacterCodingException e) {
+            return false;
+        } finally {
+            onMalformedInput(originalMalformedInputAction);
+            onUnmappableCharacter(originalUnmappableCharacterAction);
+            reset();
+        }
     }
 
     /**
@@ -272,54 +254,47 @@
      *             if other exception happened during the encode operation.
      */
     public final ByteBuffer encode(CharBuffer in) throws CharacterCodingException {
-        if (in.remaining() == 0) {
-            return ByteBuffer.allocate(0);
-        }
-        reset();
         int length = (int) (in.remaining() * averageBytesPerChar);
-        ByteBuffer output = ByteBuffer.allocate(length);
-        CoderResult result = null;
-        while (true) {
-            result = encode(in, output, false);
-            if (result==CoderResult.UNDERFLOW) {
-                break;
-            } else if (result==CoderResult.OVERFLOW) {
-                output = allocateMore(output);
-                continue;
-            }
-            checkCoderResult(result);
+        ByteBuffer out = ByteBuffer.allocate(length);
+        if (in.hasRemaining() == false) {
+            return out;
         }
-        result = encode(in, output, true);
-        checkCoderResult(result);
 
-        while (true) {
-            result = flush(output);
-            if (result==CoderResult.UNDERFLOW) {
-                output.flip();
+        reset();
+
+        while (in.hasRemaining()) {
+            CoderResult result = encode(in, out, true);
+            if (result == CoderResult.UNDERFLOW) {
                 break;
-            } else if (result==CoderResult.OVERFLOW) {
-                output = allocateMore(output);
+            } else if (result == CoderResult.OVERFLOW) {
+                out = allocateMore(out);
                 continue;
+            } else {
+                checkCoderResult(result);
             }
-            checkCoderResult(result);
-            output.flip();
-            if (result.isMalformed()) {
-                throw new MalformedInputException(result.length());
-            } else if (result.isUnmappable()) {
-                throw new UnmappableCharacterException(result.length());
+
+            result = flush(out);
+            if (result == CoderResult.UNDERFLOW) {
+                break;
+            } else if (result == CoderResult.OVERFLOW) {
+                out = allocateMore(out);
+                continue;
+            } else {
+                checkCoderResult(result);
             }
-            break;
         }
+
+        out.flip();
         status = READY;
         finished = true;
-        return output;
+        return out;
     }
 
     /*
      * checks the result whether it needs to throw CharacterCodingException.
      */
     private void checkCoderResult(CoderResult result) throws CharacterCodingException {
-        if (malformedInputAction == CodingErrorAction.REPORT && result.isMalformed() ) {
+        if (malformedInputAction == CodingErrorAction.REPORT && result.isMalformed()) {
             throw new MalformedInputException(result.length());
         } else if (unmappableCharacterAction == CodingErrorAction.REPORT && result.isUnmappable()) {
             throw new UnmappableCharacterException(result.length());
@@ -405,12 +380,14 @@
         if (status == READY && finished && !endOfInput) {
             throw new IllegalStateException();
         }
-        if ((status == FLUSH) || (!endOfInput && status == END)) {
+        if (status == FLUSH || (!endOfInput && status == END)) {
             throw new IllegalStateException();
         }
 
-        CoderResult result;
+        status = endOfInput ? END : ONGOING;
+
         while (true) {
+            CoderResult result;
             try {
                 result = encodeLoop(in, out);
             } catch (BufferOverflowException e) {
@@ -418,37 +395,25 @@
             } catch (BufferUnderflowException e) {
                 throw new CoderMalfunctionError(e);
             }
-            if (result==CoderResult.UNDERFLOW) {
-                status = endOfInput ? END : ONGOING;
-                if (endOfInput) {
-                    int remaining = in.remaining();
-                    if (remaining > 0) {
-                        result = CoderResult.malformedForLength(remaining);
-                    } else {
-                        return result;
-                    }
+            if (result == CoderResult.UNDERFLOW) {
+                if (endOfInput && in.hasRemaining()) {
+                    result = CoderResult.malformedForLength(in.remaining());
                 } else {
                     return result;
                 }
-            } else if (result==CoderResult.OVERFLOW) {
-                status = endOfInput ? END : ONGOING;
+            } else if (result == CoderResult.OVERFLOW) {
                 return result;
             }
-            CodingErrorAction action = malformedInputAction;
-            if (result.isUnmappable()) {
-                action = unmappableCharacterAction;
+            CodingErrorAction action =
+                    result.isUnmappable() ? unmappableCharacterAction : malformedInputAction;
+            if (action == CodingErrorAction.REPORT) {
+                return result;
             }
-            // If the action is IGNORE or REPLACE, we should continue
-            // encoding.
             if (action == CodingErrorAction.REPLACE) {
                 if (out.remaining() < replacementBytes.length) {
                     return CoderResult.OVERFLOW;
                 }
                 out.put(replacementBytes);
-            } else {
-                if (action != CodingErrorAction.IGNORE) {
-                    return result;
-                }
             }
             in.position(in.position() + result.length());
         }
@@ -467,9 +432,9 @@
      * {@link #encode(CharBuffer, ByteBuffer, boolean) encode}. When an
      * exception is encountered in the encoding operation, most implementations
      * of this method will return a relevant result object to the
-     * {@link #encode(CharBuffer, ByteBuffer, boolean) encode} method, and some
-     * performance optimized implementation may handle the exception and
-     * implement the error action itself.
+     * {@link #encode(CharBuffer, ByteBuffer, boolean) encode} method, and
+     * subclasses may handle the exception and
+     * implement the error action themselves.
      * <p>
      * The buffers are scanned from their current positions, and their positions
      * will be modified accordingly, while their marks and limits will be
@@ -588,18 +553,9 @@
     }
 
     /**
-     * Checks if the given argument is legal as this encoder's replacement byte
-     * array.
-     *
-     * The given byte array is legal if and only if it can be decode into
-     * sixteen bits Unicode characters.
-     *
-     * This method can be overridden for performance improvement.
-     *
-     * @param replacement
-     *            the given byte array to be checked.
-     * @return true if the the given argument is legal as this encoder's
-     *         replacement byte array.
+     * Tests whether the given argument is legal as this encoder's replacement byte
+     * array. The given byte array is legal if and only if it can be decoded into
+     * characters.
      */
     public boolean isLegalReplacement(byte[] replacement) {
         if (decoder == null) {
diff --git a/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java b/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java
index 76807b0..4bc4354 100644
--- a/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java
+++ b/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java
@@ -184,14 +184,6 @@
         }
     }
 
-    public boolean canEncode(char c) {
-        return canEncode((int) c);
-    }
-
-    public boolean canEncode(int codePoint) {
-        return NativeConverter.canEncode(converterHandle, codePoint);
-    }
-
     @Override protected void finalize() throws Throwable {
         try {
             NativeConverter.closeConverter(converterHandle);
diff --git a/luni/src/main/java/java/nio/charset/CoderResult.java b/luni/src/main/java/java/nio/charset/CoderResult.java
index 3cc2673..6c45e26 100644
--- a/luni/src/main/java/java/nio/charset/CoderResult.java
+++ b/luni/src/main/java/java/nio/charset/CoderResult.java
@@ -154,8 +154,6 @@
 
     /**
      * Returns true if this result is an underflow condition.
-     *
-     * @return true if an underflow, otherwise false.
      */
     public boolean isUnderflow() {
         return this.type == TYPE_UNDERFLOW;
@@ -164,19 +162,13 @@
     /**
      * Returns true if this result represents a malformed-input error or an
      * unmappable-character error.
-     *
-     * @return true if this is a malformed-input error or an
-     *         unmappable-character error, otherwise false.
      */
     public boolean isError() {
-        return this.type == TYPE_MALFORMED_INPUT
-                || this.type == TYPE_UNMAPPABLE_CHAR;
+        return this.type == TYPE_MALFORMED_INPUT || this.type == TYPE_UNMAPPABLE_CHAR;
     }
 
     /**
      * Returns true if this result represents a malformed-input error.
-     *
-     * @return true if this is a malformed-input error, otherwise false.
      */
     public boolean isMalformed() {
         return this.type == TYPE_MALFORMED_INPUT;
@@ -184,8 +176,6 @@
 
     /**
      * Returns true if this result is an overflow condition.
-     *
-     * @return true if this is an overflow, otherwise false.
      */
     public boolean isOverflow() {
         return this.type == TYPE_OVERFLOW;
@@ -193,18 +183,15 @@
 
     /**
      * Returns true if this result represents an unmappable-character error.
-     *
-     * @return true if this is an unmappable-character error, otherwise false.
      */
     public boolean isUnmappable() {
         return this.type == TYPE_UNMAPPABLE_CHAR;
     }
 
     /**
-     * Gets the length of the erroneous input. The length is only meaningful to
+     * Returns the length of the erroneous input. The length is only meaningful for
      * a malformed-input error or an unmappable character error.
      *
-     * @return the length, as an integer, of this object's erroneous input.
      * @throws UnsupportedOperationException
      *             if this result is an overflow or underflow.
      */
diff --git a/luni/src/main/java/libcore/icu/NativeConverter.java b/luni/src/main/java/libcore/icu/NativeConverter.java
index 1b8a7e0..17be458 100644
--- a/luni/src/main/java/libcore/icu/NativeConverter.java
+++ b/luni/src/main/java/libcore/icu/NativeConverter.java
@@ -36,8 +36,6 @@
 
     public static native boolean contains(String converterName1, String converterName2);
 
-    public static native boolean canEncode(long converterHandle, int codeUnit);
-
     public static native String[] getAvailableCharsetNames();
     public static native Charset charsetForName(String charsetName);
 
diff --git a/luni/src/main/native/libcore_icu_NativeConverter.cpp b/luni/src/main/native/libcore_icu_NativeConverter.cpp
index 24dfa6f..fae56b7 100644
--- a/luni/src/main/native/libcore_icu_NativeConverter.cpp
+++ b/luni/src/main/native/libcore_icu_NativeConverter.cpp
@@ -230,28 +230,6 @@
     return (cnv != NULL) ? ((ucnv_getMaxCharSize(cnv) + ucnv_getMinCharSize(cnv)) / 2.0) : -1;
 }
 
-static jboolean NativeConverter_canEncode(JNIEnv*, jclass, jlong address, jint codeUnit) {
-    UErrorCode errorCode = U_ZERO_ERROR;
-    UConverter* cnv = toUConverter(address);
-    if (cnv == NULL) {
-        return JNI_FALSE;
-    }
-
-    UChar srcBuffer[3];
-    const UChar* src = &srcBuffer[0];
-    const UChar* srcLimit = (codeUnit < 0x10000) ? &src[1] : &src[2];
-
-    char dstBuffer[5];
-    char* dst = &dstBuffer[0];
-    const char* dstLimit = &dstBuffer[4];
-
-    int i = 0;
-    UTF_APPEND_CHAR(&srcBuffer[0], i, 2, codeUnit);
-
-    ucnv_fromUnicode(cnv, &dst, dstLimit, &src, srcLimit, NULL, TRUE, &errorCode);
-    return U_SUCCESS(errorCode);
-}
-
 /*
  * If a charset listed in the IANA Charset Registry is supported by an implementation
  * of the Java platform then its canonical name must be the name listed in the registry.
@@ -620,7 +598,6 @@
 }
 
 static JNINativeMethod gMethods[] = {
-    NATIVE_METHOD(NativeConverter, canEncode, "(JI)Z"),
     NATIVE_METHOD(NativeConverter, charsetForName, "(Ljava/lang/String;)Ljava/nio/charset/Charset;"),
     NATIVE_METHOD(NativeConverter, closeConverter, "(J)V"),
     NATIVE_METHOD(NativeConverter, contains, "(Ljava/lang/String;Ljava/lang/String;)Z"),