Java 6 changed CollationKey from final to abstract.

I've also taken the opportunity to tidy up our implementation a little,
though my hands are tied by (a) the fact that our concrete classes are
in a separate package from our abstract classes and (b) frameworks/base
actually pokes about with our icu4jni collation code (http://b/2417080).

I've also tidied up a bunch of dead code. In particular, it's silly for
us to check parameters in Java that will be checked in native code (and
that one would assume will be valid most of the time anyway).

Bug: 1635883
Change-Id: I7db3c1ff1f0d23cb85604f9c8eb995e4488d7c0a
diff --git a/libcore/icu/src/main/java/com/ibm/icu4jni/charset/CharsetICU.java b/libcore/icu/src/main/java/com/ibm/icu4jni/charset/CharsetICU.java
index 48deb00..155f966 100644
--- a/libcore/icu/src/main/java/com/ibm/icu4jni/charset/CharsetICU.java
+++ b/libcore/icu/src/main/java/com/ibm/icu4jni/charset/CharsetICU.java
@@ -15,13 +15,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-// BEGIN android-removed
-// import com.ibm.icu4jni.common.ErrorCode;
-// import com.ibm.icu4jni.converters.NativeConverter;
-// END android-removed
-
-
-public final class CharsetICU extends Charset{
+public final class CharsetICU extends Charset {
     private final String icuCanonicalName;
     /**
      * Constructor to create a the CharsetICU object
diff --git a/libcore/icu/src/main/java/com/ibm/icu4jni/text/CollationAttribute.java b/libcore/icu/src/main/java/com/ibm/icu4jni/text/CollationAttribute.java
index b1c6107..eaf626f 100644
--- a/libcore/icu/src/main/java/com/ibm/icu4jni/text/CollationAttribute.java
+++ b/libcore/icu/src/main/java/com/ibm/icu4jni/text/CollationAttribute.java
@@ -10,205 +10,31 @@
 package com.ibm.icu4jni.text;
 
 /**
-* Interface for storing ICU collation equivalent enum values.
-* Constants with the prefix VALUE corresponds to ICU's UColAttributeValues,
-* the rest corresponds to UColAttribute.
-* @author syn wee quek
-* @stable ICU 2.4
-*/
-
-public final class CollationAttribute
-{ 
-  // Collation strength constants ----------------------------------
-  /**
-  * Default value, accepted by most attributes
-  * @stable ICU 2.4
-  */ 
-  public static final int VALUE_DEFAULT = -1;
-  /** 
-  * Primary collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_PRIMARY = 0;
-  /** 
-  * Secondary collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_SECONDARY = 1;
-  /** 
-  * Tertiary collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_TERTIARY = 2;
-  /** 
-  * Default collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_DEFAULT_STRENGTH = VALUE_TERTIARY;
-  /** 
-  * Quaternary collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_QUATERNARY = 3;
-  /** 
-  * Identical collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_IDENTICAL = 15;
-
-  /** 
-   * Turn the feature off - works for FRENCH_COLLATION, CASE_LEVEL, 
-   * HIRAGANA_QUATERNARY_MODE and DECOMPOSITION_MODE
-   * @stable ICU 2.4
-   */
-  public static final int VALUE_OFF = 16;
-  /** @stable ICU 2.4 */
-  public static final int VALUE_ON = 17;
-  
-  /** 
-   * ALTERNATE_HANDLING mode constants
-   * @stable ICU 2.4
-   */
-  public static final int VALUE_SHIFTED = 20;
-  /** @stable ICU 2.4 */
-  public static final int VALUE_NON_IGNORABLE = 21;
-
-  /** 
-   * CASE_FIRST mode constants
-   * @stable ICU 2.4
-   */
-  public static final int VALUE_LOWER_FIRST = 24;
-  /** @stable ICU 2.4 */
-  public static final int VALUE_UPPER_FIRST = 25;
-
-  /** 
-   * NORMALIZATION_MODE mode constants
-   * @deprecated ICU 2.4. Users advised to use VALUE_ON instead.
-   */
-  public static final int VALUE_ON_WITHOUT_HANGUL = 28;
-
-  /** 
-   * Number of attribute value constants
-   * @stable ICU 2.4
-   */
-  public static final int VALUE_ATTRIBUTE_VALUE_COUNT = 29;
-
-  // Collation attribute constants -----------------------------------
-  
-  /** 
-   * Attribute for direction of secondary weights
-   * @stable ICU 2.4
-   */
-  public static final int FRENCH_COLLATION = 0;
-  /** 
-   * Attribute for handling variable elements
-   * @stable ICU 2.4
-   */
-  public static final int ALTERNATE_HANDLING = 1;
-  /** 
-   * Who goes first, lower case or uppercase.
-   * @stable ICU 2.4
-   */
-  public static final int CASE_FIRST = 2;
-  /** 
-   * Do we have an extra case level
-   * @stable ICU 2.4
-   */
-  public static final int CASE_LEVEL = 3;
-  /** 
-   * Attribute for normalization
-   * @stable ICU 2.4
-   */
-  public static final int NORMALIZATION_MODE = 4; 
-  /** 
-   * Attribute for strength 
-   * @stable ICU 2.4
-   */
-  public static final int STRENGTH = 5;
-  /** 
-   * Attribute count
-   * @stable ICU 2.4
-   */
-  public static final int ATTRIBUTE_COUNT = 6;
-  
-  // package methods --------------------------------------------------
-  
-  /**
-  * Checks if argument is a valid collation strength
-  * @param strength potential collation strength
-  * @return true if strength is a valid collation strength, false otherwise
-  */
-  static boolean checkStrength(int strength)
-  {
-    if (strength < VALUE_PRIMARY || 
-        (strength > VALUE_QUATERNARY && strength != VALUE_IDENTICAL))
-      return false;
-    return true;
-  }
-  
-  /**
-  * Checks if argument is a valid collation type
-  * @param type collation type to be checked
-  * @return true if type is a valid collation type, false otherwise
-  */
-  static boolean checkType(int type)
-  {
-    if (type < FRENCH_COLLATION || type > STRENGTH)
-      return false;
-    return true;
-  }
-
-  /**
-  * Checks if argument is a valid normalization type
-  * @param type normalization type to be checked
-  * @return true if type is a valid normalization type, false otherwise
-  */
-  static boolean checkNormalization(int type)
-  {
-    if (type != VALUE_ON && type != VALUE_OFF 
-        && type != VALUE_ON_WITHOUT_HANGUL) {
-        return false;
-    }
-    return true;
-  }
-  
-  /**
-  * Checks if attribute type and corresponding attribute value is valid
-  * @param type attribute type
-  * @param value attribute value
-  * @return true if the pair is valid, false otherwise
-  */
-  static boolean checkAttribute(int type, int value)
-  {
-    if (value == VALUE_DEFAULT) {
-      return true;
-    }
-      
-    switch (type)
-    {
-      case FRENCH_COLLATION :
-                          if (value >= VALUE_OFF && value <= VALUE_ON)
-                            return true;
-                          break;
-      case ALTERNATE_HANDLING :
-                          if (value >= VALUE_SHIFTED && 
-                              value <= VALUE_NON_IGNORABLE)
-                            return true;
-                          break;
-      case CASE_FIRST :
-                          if (value >= VALUE_LOWER_FIRST && 
-                              value <= VALUE_UPPER_FIRST)
-                            return true;
-                          break;
-      case CASE_LEVEL :
-                          return (value == VALUE_ON || 
-                                  value <= VALUE_OFF);
-      case NORMALIZATION_MODE : 
-                          return (value == VALUE_OFF || value == VALUE_ON ||
-                                  value == VALUE_ON_WITHOUT_HANGUL);
-      case STRENGTH :
-                          checkStrength(value);
-    }
-    return false;
-  }
+ * TODO: move these constants into NativeCollation.
+ */
+public final class CollationAttribute {
+    // Values from the native UColAttributeValue enum.
+    public static final int VALUE_DEFAULT = -1;
+    public static final int VALUE_PRIMARY = 0;
+    public static final int VALUE_SECONDARY = 1;
+    public static final int VALUE_TERTIARY = 2;
+    public static final int VALUE_DEFAULT_STRENGTH = VALUE_TERTIARY;
+    public static final int VALUE_QUATERNARY = 3;
+    public static final int VALUE_IDENTICAL = 15;
+    public static final int VALUE_OFF = 16;
+    public static final int VALUE_ON = 17;
+    public static final int VALUE_SHIFTED = 20;
+    public static final int VALUE_NON_IGNORABLE = 21;
+    public static final int VALUE_LOWER_FIRST = 24;
+    public static final int VALUE_UPPER_FIRST = 25;
+    public static final int VALUE_ON_WITHOUT_HANGUL = 28;
+    public static final int VALUE_ATTRIBUTE_VALUE_COUNT = 29;
+    // Values from the UColAttribute enum.
+    public static final int FRENCH_COLLATION = 0;
+    public static final int ALTERNATE_HANDLING = 1;
+    public static final int CASE_FIRST = 2;
+    public static final int CASE_LEVEL = 3;
+    public static final int NORMALIZATION_MODE = 4;
+    public static final int DECOMPOSITION_MODE = NORMALIZATION_MODE;
+    public static final int STRENGTH = 5;
 }
diff --git a/libcore/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java b/libcore/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java
index 9e9401d..dbd714c 100644
--- a/libcore/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java
+++ b/libcore/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java
@@ -11,176 +11,112 @@
 package com.ibm.icu4jni.text;
 
 /**
-* Collation key wrapper, containing the byte array sort key.
-* @author syn wee quek
-* @stable ICU 2.4
-*/
+ * A concrete implementation of the abstract java.text.CollationKey.
+ */
+public final class CollationKey extends java.text.CollationKey {
+    /**
+     * The key.
+     */
+    private final byte[] bytes;
 
-public final class CollationKey implements Comparable
-{ 
-  // public methods -----------------------------------------------
+    /**
+     * Cached hash value.
+     */
+    private int hashCode;
 
-  /**
-  * Bitwise comparison for the collation keys
-  * @param target CollationKey to be compared
-  * @return comparison result from Collator, RESULT_LESS, RESULT_EQUAL, 
-  *         RESULT_GREATER
-  * @stable ICU 2.4    
-  */
-  public int compareTo(CollationKey target)
-  {
-    byte tgtbytes[] = target.m_bytes_;
-    
-    if (m_bytes_ == null || m_bytes_.length == 0) {
-      if (tgtbytes == null || tgtbytes.length == 0) {
-        return Collator.RESULT_EQUAL;
-      }
-      return Collator.RESULT_LESS;
-    }
-    else {
-      if (tgtbytes == null || tgtbytes.length == 0) {
-        return Collator.RESULT_GREATER;
-      }
-    }
-        
-    int count = m_bytes_.length;
-    if (tgtbytes.length < count) {
-      count = tgtbytes.length;
+    CollationKey(String source, byte[] bytes) {
+        super(source);
+        this.bytes = bytes;
     }
 
-    int s,
-        t;
-    for (int i = 0; i < count; i ++)
-    {
-      // unable to use Arrays.equals
-      s = m_bytes_[i] & UNSIGNED_BYTE_MASK_;
-      t = tgtbytes[i] & UNSIGNED_BYTE_MASK_;
-      if (s < t) {
-        return Collator.RESULT_LESS;
-      }
-      if (s > t) {
-        return Collator.RESULT_GREATER;
-      }
+    public int compareTo(java.text.CollationKey other) {
+        // Get the bytes from the other collation key.
+        final byte[] rhsBytes;
+        if (other instanceof CollationKey) {
+            rhsBytes = ((CollationKey) other).bytes;
+        } else {
+            rhsBytes = other.toByteArray();
+        }
+
+        if (bytes == null || bytes.length == 0) {
+            if (rhsBytes == null || rhsBytes.length == 0) {
+                return 0;
+            }
+            return -1;
+        } else {
+            if (rhsBytes == null || rhsBytes.length == 0) {
+                return 1;
+            }
+        }
+
+        int count = Math.min(bytes.length, rhsBytes.length);
+        for (int i = 0; i < count; ++i) {
+            int s = bytes[i] & 0xff;
+            int t = rhsBytes[i] & 0xff;
+            if (s < t) {
+                return -1;
+            }
+            if (s > t) {
+                return 1;
+            }
+        }
+        if (bytes.length < rhsBytes.length) {
+            return -1;
+        }
+        if (bytes.length > rhsBytes.length) {
+            return 1;
+        }
+        return 0;
     }
 
-    if (m_bytes_.length < target.m_bytes_.length) {
-      return Collator.RESULT_LESS;
+    /**
+     * Checks if target object is equal to this object.
+     * Target is first casted to CollationKey and bitwise compared.
+     * @param target comparison object
+     * @return true if both objects are equal, false otherwise
+     * @stable ICU 2.4
+     */
+    public boolean equals(Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (!(object instanceof CollationKey)) {
+            return false;
+        }
+        return compareTo((CollationKey) object) == 0;
     }
-    
-    if (m_bytes_.length > target.m_bytes_.length) {
-      return Collator.RESULT_GREATER;
+
+    /**
+     * Creates a hash code for this CollationKey.
+     * Compute the hash by iterating sparsely over about 32 (up to 63) bytes
+     * spaced evenly through the string.  For each byte, multiply the previous
+     * hash value by a prime number and add the new byte in, like a linear
+     * congruential random number generator, producing a pseudo-random
+     * deterministic value well distributed over the output range.
+     * @return hash value of collation key. Hash value is never 0.
+     * @stable ICU 2.4
+     */
+    public int hashCode() {
+        if (hashCode == 0) {
+            if (bytes != null && bytes.length != 0) {
+                int len = bytes.length;
+                int inc = ((len - 32) / 32) + 1;
+                for (int i = 0; i < len;) {
+                    hashCode = (hashCode * 37) + bytes[i];
+                    i += inc;
+                }
+            }
+            if (hashCode == 0) {
+                hashCode = 1;
+            }
+        }
+        return hashCode;
     }
-    
-    return Collator.RESULT_EQUAL;
-  }
-  
-  /**
-  * Bitwise comparison for the collation keys.
-  * Argument is casted to CollationKey
-  * @param target CollationKey to be compared
-  * @return comparison result from Collator, RESULT_LESS, RESULT_EQUAL, 
-  * RESULT_GREATER
-  * @stable ICU 2.4
-  */
-  public int compareTo(Object target)
-  {
-    return compareTo((CollationKey)target);
-  }
 
-  /**
-  * Checks if target object is equal to this object.
-  * Target is first casted to CollationKey and bitwise compared.
-  * @param target comparison object
-  * @return true if both objects are equal, false otherwise
-  * @stable ICU 2.4
-  */
-  public boolean equals(Object target)
-  {
-    if (this == target) {
-      return true;
+    public byte[] toByteArray() {
+        if (bytes == null || bytes.length == 0) {
+            return null;
+        }
+        return bytes.clone();
     }
-      
-    // checks getClass here since CollationKey is final not subclassable
-    if (target == null || target.getClass() != getClass()) {
-      return false;
-    }
-    
-    return compareTo((CollationKey)target) == Collator.RESULT_EQUAL;
-  }
-
-  /**
-  * Creates a hash code for this CollationKey. 
-  * Compute the hash by iterating sparsely over about 32 (up to 63) bytes 
-  * spaced evenly through the string.  For each byte, multiply the previous 
-  * hash value by a prime number and add the new byte in, like a linear 
-  * congruential random number generator, producing a pseudorandom 
-  * deterministic value well distributed over the output range.
-  * @return hash value of collation key. Hash value is never 0.
-  * @stable ICU 2.4
-  */
-  public int hashCode()
-  {
-    if (m_hash_ == 0)
-    {
-      if (m_bytes_ != null && m_bytes_.length != 0)
-      {                        
-        int len = m_bytes_.length;
-        int inc = ((len - 32) / 32) + 1;  
-        for (int i = 0; i < len;)
-        {
-          m_hash_ = (m_hash_ * 37) + m_bytes_[i];
-          i += inc;                         
-        }                                     
-      }             
-      if (m_hash_ == 0)
-        m_hash_ = 1;
-    }
-    return m_hash_;
-  }
-
-  /**
-  * Create the value of the Collation key in term of bytes
-  * @return value of Collation key in bytes
-  * @stable ICU 2.4
-  */
-  public byte[] toByteArray()
-  {
-    if (m_bytes_ == null || m_bytes_.length == 0)
-      return null;
-      
-    return (byte[])m_bytes_.clone(); 
-  }
-
-  // package constructors ----------------------------------------------
-  
-  /**
-  * Default constructor, for use by the Collator and its subclasses.
-  */
-  CollationKey()
-  {
-    m_hash_ = 0;
-  }
-  
-  /**
-  * Constructor, for use only by the Collator and its subclasses.
-  */
-  CollationKey(byte[] bytes)
-  {
-    m_bytes_ = bytes;
-    m_hash_ = 0;
-  }
-
-  // private data members -----------------------------------------------
-  
-  private byte m_bytes_[];
-  
-  /**
-  * Mask value to retrieve a single unsigned byte
-  */
-  private static final int UNSIGNED_BYTE_MASK_ = 0x00FF;
-  
-  /**
-  * Cached hash value
-  */
-  private int m_hash_;
 }
diff --git a/libcore/icu/src/main/java/com/ibm/icu4jni/text/Collator.java b/libcore/icu/src/main/java/com/ibm/icu4jni/text/Collator.java
index 0963b81..f108737 100644
--- a/libcore/icu/src/main/java/com/ibm/icu4jni/text/Collator.java
+++ b/libcore/icu/src/main/java/com/ibm/icu4jni/text/Collator.java
@@ -16,13 +16,13 @@
 
 /**
 * Abstract class handling locale specific collation via JNI and ICU.
-* Subclasses implement specific collation strategies. One subclass, 
-* com.ibm.icu4jni.text.RuleBasedCollator, is currently provided and is 
-* applicable to a wide set of languages. Other subclasses may be created to 
-* handle more specialized needs. 
-* You can use the static factory method, getInstance(), to obtain the 
-* appropriate Collator object for a given locale. 
-* 
+* Subclasses implement specific collation strategies. One subclass,
+* com.ibm.icu4jni.text.RuleBasedCollator, is currently provided and is
+* applicable to a wide set of languages. Other subclasses may be created to
+* handle more specialized needs.
+* You can use the static factory method, getInstance(), to obtain the
+* appropriate Collator object for a given locale.
+*
 * <pre>
 * // Compare two strings in the default locale
 * Collator myCollator = Collator.getInstance();
@@ -34,18 +34,18 @@
 * }
 * </pre>
 *
-* You can set a Collator's strength property to determine the level of 
-* difference considered significant in comparisons. 
-* Five strengths in CollationAttribute are provided: VALUE_PRIMARY, 
-* VALUE_SECONDARY, VALUE_TERTIARY, VALUE_QUARTENARY and VALUE_IDENTICAL. 
-* The exact assignment of strengths to language features is locale dependant. 
-* For example, in Czech, "e" and "f" are considered primary differences, while 
-* "e" and "?" latin small letter e with circumflex are secondary differences, 
-* "e" and "E" are tertiary differences and "e" and "e" are identical. 
+* You can set a Collator's strength property to determine the level of
+* difference considered significant in comparisons.
+* Five strengths in CollationAttribute are provided: VALUE_PRIMARY,
+* VALUE_SECONDARY, VALUE_TERTIARY, VALUE_QUATERNARY and VALUE_IDENTICAL.
+* The exact assignment of strengths to language features is locale-dependent.
+* For example, in Czech, "e" and "f" are considered primary differences, while
+* "e" and "?" latin small letter e with circumflex are secondary differences,
+* "e" and "E" are tertiary differences and "e" and "e" are identical.
 *
 * <p>
-* The following shows how both case and accents could be ignored for US 
-* English. 
+* The following shows how both case and accents could be ignored for US
+* English.
 * <pre>
 * //Get the Collator for US English and set its strength to PRIMARY
 * Collator usCollator = Collator.getInstance(Locale.US);
@@ -54,15 +54,15 @@
 *   System.out.println("Strings are equivalent");
 * }
 * </pre>
-* For comparing Strings exactly once, the compare method provides the best 
-* performance. 
-* When sorting a list of Strings however, it is generally necessary to compare 
-* each String multiple times. 
-* In this case, com.ibm.icu4jni.text.CollationKey provide better performance. 
-* The CollationKey class converts a String to a series of bits that can be 
-* compared bitwise against other CollationKeys. 
-* A CollationKey is created by a Collator object for a given String. 
-* Note: CollationKeys from different Collators can not be compared. 
+* For comparing Strings exactly once, the compare method provides the best
+* performance.
+* When sorting a list of Strings however, it is generally necessary to compare
+* each String multiple times.
+* In this case, com.ibm.icu4jni.text.CollationKey provide better performance.
+* The CollationKey class converts a String to a series of bits that can be
+* compared bitwise against other CollationKeys.
+* A CollationKey is created by a Collator object for a given String.
+* Note: CollationKeys from different Collators can not be compared.
 * </p>
 *
 * Considerations :
@@ -72,12 +72,9 @@
 * @stable ICU 2.4
 */
 
-public abstract class Collator implements Cloneable
-{ 
-    // public data members ---------------------------------------------------
-        
+public abstract class Collator implements Cloneable {
     /**
-     * Strongest collator strength value. Typically used to denote differences 
+     * Strongest collator strength value. Typically used to denote differences
      * between base characters. See class documentation for more explanation.
      * @see #setStrength
      * @see #getStrength
@@ -86,10 +83,10 @@
     public final static int PRIMARY = CollationAttribute.VALUE_PRIMARY;
 
     /**
-     * Second level collator strength value. 
+     * Second level collator strength value.
      * Accents in the characters are considered secondary differences.
-     * Other differences between letters can also be considered secondary 
-     * differences, depending on the language. 
+     * Other differences between letters can also be considered secondary
+     * differences, depending on the language.
      * See class documentation for more explanation.
      * @see #setStrength
      * @see #getStrength
@@ -98,23 +95,23 @@
     public final static int SECONDARY = CollationAttribute.VALUE_SECONDARY;
 
     /**
-     * Third level collator strength value. 
+     * Third level collator strength value.
      * Upper and lower case differences in characters are distinguished at this
-     * strength level. In addition, a variant of a letter differs from the base 
+     * strength level. In addition, a variant of a letter differs from the base
      * form on the tertiary level.
      * See class documentation for more explanation.
      * @see #setStrength
      * @see #getStrength
      * @stable ICU 2.4
      */
-    public final static int TERTIARY = CollationAttribute.VALUE_TERTIARY;                            
+    public final static int TERTIARY = CollationAttribute.VALUE_TERTIARY;
 
     /**
-     * Fourth level collator strength value. 
-     * When punctuation is ignored 
+     * Fourth level collator strength value.
+     * When punctuation is ignored
      * <a href="http://www-124.ibm.com/icu/userguide/Collate_Concepts.html#Ignoring_Punctuation">
-     * (see Ignoring Punctuations in the user guide)</a> at PRIMARY to TERTIARY 
-     * strength, an additional strength level can 
+     * (see Ignoring Punctuations in the user guide)</a> at PRIMARY to TERTIARY
+     * strength, an additional strength level can
      * be used to distinguish words with and without punctuation.
      * See class documentation for more explanation.
      * @see #setStrength
@@ -125,10 +122,10 @@
 
     /**
      * <p>
-     * Smallest Collator strength value. When all other strengths are equal, 
-     * the IDENTICAL strength is used as a tiebreaker. The Unicode code point 
-     * values of the NFD form of each string are compared, just in case there 
-     * is no difference. 
+     * Smallest Collator strength value. When all other strengths are equal,
+     * the IDENTICAL strength is used as a tiebreaker. The Unicode code point
+     * values of the NFD form of each string are compared, just in case there
+     * is no difference.
      * See class documentation for more explanation.
      * </p>
      * <p>
@@ -148,7 +145,7 @@
      * @see #CANONICAL_DECOMPOSITION
      * @see #getDecomposition
      * @see #setDecomposition
-     * @stable ICU 2.4 
+     * @stable ICU 2.4
      */
     public final static int NO_DECOMPOSITION = CollationAttribute.VALUE_OFF;
 
@@ -164,132 +161,65 @@
      * @see #NO_DECOMPOSITION
      * @see #getDecomposition
      * @see #setDecomposition
-     * @stable ICU 2.4 
-     */
-    public final static int CANONICAL_DECOMPOSITION 
-                                                = CollationAttribute.VALUE_ON;
-  
-    // Collation result constants -----------------------------------
-    // corresponds to ICU's UCollationResult enum balues
-    /** 
-     * string a == string b 
      * @stable ICU 2.4
      */
-    public static final int RESULT_EQUAL = 0;
-    /** 
-     * string a > string b 
-     * @stable ICU 2.4
-     */
-    public static final int RESULT_GREATER = 1;
-    /** 
-     * string a < string b 
-     * @stable ICU 2.4
-     */
-    public static final int RESULT_LESS = -1;
-    /** 
-     * accepted by most attributes 
-     * @stable ICU 2.4
-     */
-    public static final int RESULT_DEFAULT = -1;
-  
-    // public methods -----------------------------------------------
-  
-  /**
-  * Factory method to create an appropriate Collator which uses the default
-  * locale collation rules.
-  * Current implementation createInstance() returns a RuleBasedCollator(Locale) 
-  * instance. The RuleBasedCollator will be created in the following order,
-  * <ul>
-  * <li> Data from argument locale resource bundle if found, otherwise
-  * <li> Data from parent locale resource bundle of arguemtn locale if found,
-  *      otherwise
-  * <li> Data from built-in default collation rules if found, other
-  * <li> null is returned
-  * </ul>
-  * @return an instance of Collator
-  * @stable ICU 2.4
-  */
-  public static Collator getInstance()
-  {
-    return getInstance(null);
-  }
+    public final static int CANONICAL_DECOMPOSITION = CollationAttribute.VALUE_ON;
 
-  /**
-  * Factory method to create an appropriate Collator which uses the argument
-  * locale collation rules.<br>
-  * Current implementation createInstance() returns a RuleBasedCollator(Locale) 
-  * instance. The RuleBasedCollator will be created in the following order,
-  * <ul>
-  * <li> Data from argument locale resource bundle if found, otherwise
-  * <li> Data from parent locale resource bundle of arguemtn locale if found,
-  *      otherwise
-  * <li> Data from built-in default collation rules if found, other
-  * <li> null is returned
-  * </ul>
-  * @param locale to be used for collation
-  * @return an instance of Collator
-  * @stable ICU 2.4
-  */
-  public static Collator getInstance(Locale locale)
-  {
-    RuleBasedCollator result = new RuleBasedCollator(locale);
-    return result;
-  }
+    public static Collator getInstance() {
+        return getInstance(null);
+    }
 
-  /**
-  * Locale dependent equality check for the argument strings.
-  * @param source string
-  * @param target string
-  * @return true if source is equivalent to target, false otherwise 
-  * @stable ICU 2.4
-  */
-  public boolean equals(String source, String target)
-  {
-    return (compare(source, target) == RESULT_EQUAL);
-  }
-  
-  /**
-  * Checks if argument object is equals to this object.
-  * @param target object
-  * @return true if source is equivalent to target, false otherwise 
-  * @stable ICU 2.4
-  */
-  public abstract boolean equals(Object target);
-  
-  /**
-  * Makes a copy of the current object.
-  * @return a copy of this object
-  * @stable ICU 2.4
-  */
-  public abstract Object clone() throws CloneNotSupportedException;
-  
-  /**
-  * The comparison function compares the character data stored in two
-  * different strings. Returns information about whether a string is less 
-  * than, greater than or equal to another string.
-  * <p>Example of use:
-  * <pre>
-  * .  Collator myCollation = Collator.getInstance(Locale::US);
-  * .  myCollation.setStrength(CollationAttribute.VALUE_PRIMARY);
-  * .  // result would be CollationAttribute.VALUE_EQUAL 
-  * .  // ("abc" == "ABC")
-  * .  // (no primary difference between "abc" and "ABC")
-  * .  int result = myCollation.compare("abc", "ABC",3);
-  * .  myCollation.setStrength(CollationAttribute.VALUE_TERTIARY);
-  * .  // result would be Collation.LESS (abc" &lt;&lt;&lt; "ABC")
-  * .  // (with tertiary difference between "abc" and "ABC")
-  * .  int result = myCollation.compare("abc", "ABC",3);
-  * </pre>
-  * @param source source string.
-  * @param target target string.
-  * @return result of the comparison, Collator.RESULT_EQUAL, 
-  *         Collator.RESULT_GREATER or Collator.RESULT_LESS
-  * @stable ICU 2.4
-  */
-  public abstract int compare(String source, String target);
-                                               
     /**
-     * Get the decomposition mode of this Collator. 
+     * Factory method to create an appropriate Collator which uses the given
+     * locale's collation rules.<br>
+     * Current implementation createInstance() returns a RuleBasedCollator(Locale)
+     * instance. The RuleBasedCollator will be created in the following order,
+     * <ul>
+     * <li> Data from argument locale resource bundle if found, otherwise
+     * <li> Data from parent locale resource bundle of given locale if found, otherwise
+     * <li> Data from built-in default collation rules if found, other
+     * <li> null is returned
+     * </ul>
+     * @param locale to be used for collation
+     * @return an instance of Collator
+     * @stable ICU 2.4
+     */
+    public static Collator getInstance(Locale locale) {
+        RuleBasedCollator result = new RuleBasedCollator(locale);
+        return result;
+    }
+
+    public boolean equals(String source, String target) {
+        return (compare(source, target) == 0);
+    }
+
+    public abstract boolean equals(Object target);
+
+    public abstract Object clone() throws CloneNotSupportedException;
+
+    /**
+     * The comparison function compares the character data stored in two
+     * different strings. Returns information about whether a string is less
+     * than, greater than or equal to another string.
+     * <p>Example of use:
+     * <pre>
+     * .  Collator myCollation = Collator.getInstance(Locale::US);
+     * .  myCollation.setStrength(CollationAttribute.VALUE_PRIMARY);
+     * .  // result would be CollationAttribute.VALUE_EQUAL
+     * .  // ("abc" == "ABC")
+     * .  // (no primary difference between "abc" and "ABC")
+     * .  int result = myCollation.compare("abc", "ABC",3);
+     * .  myCollation.setStrength(CollationAttribute.VALUE_TERTIARY);
+     * .  // result would be Collation.LESS (abc" &lt;&lt;&lt; "ABC")
+     * .  // (with tertiary difference between "abc" and "ABC")
+     * .  int result = myCollation.compare("abc", "ABC",3);
+     * </pre>
+     * @stable ICU 2.4
+     */
+    public abstract int compare(String source, String target);
+
+    /**
+     * Get the decomposition mode of this Collator.
      * @return the decomposition mode
      * @see #CANONICAL_DECOMPOSITION
      * @see #NO_DECOMPOSITION
@@ -314,7 +244,7 @@
      * E.g. with strength == SECONDARY, the tertiary difference is ignored
      * </p>
      * <p>
-     * E.g. with strength == PRIMARY, the secondary and tertiary difference 
+     * E.g. with strength == PRIMARY, the secondary and tertiary difference
      * are ignored.
      * </p>
      * @return the current comparison level.
@@ -326,15 +256,15 @@
      * @stable ICU 2.4
      */
     public abstract int getStrength();
-  
-  /**
-  * Gets the attribute to be used in comparison or transformation.
-  * @param type the attribute to be set from CollationAttribute
-  * @return value attribute value from CollationAttribute
-  * @stable ICU 2.4
-  */
-  public abstract int getAttribute(int type);
-  
+
+    /**
+     * Gets the attribute to be used in comparison or transformation.
+     * @param type the attribute to be set from CollationAttribute
+     * @return value attribute value from CollationAttribute
+     * @stable ICU 2.4
+     */
+    public abstract int getAttribute(int type);
+
     /**
      * Sets the minimum strength to be used in comparison or transformation.
      * <p>Example of use:
@@ -343,59 +273,59 @@
      * . myCollation.setStrength(PRIMARY);
      * . // result will be "abc" == "ABC"
      * . // tertiary differences will be ignored
-     * . int result = myCollation->compare("abc", "ABC"); 
+     * . int result = myCollation->compare("abc", "ABC");
      * </pre>
      * @param strength the new comparison level.
      * @see #PRIMARY
      * @see #SECONDARY
      * @see #TERTIARY
-     * @see #QUATERNARY 
+     * @see #QUATERNARY
      * @see #IDENTICAL
      * @stable ICU 2.4
      */
      public abstract void setStrength(int strength);
-  
-  /**
-  * Sets the attribute to be used in comparison or transformation.
-  * <p>Example of use:
-  * <pre>
-  * . Collator myCollation = Collator.createInstance(Locale::US);
-  * . myCollation.setAttribute(CollationAttribute.CASE_LEVEL, 
-  * .                          CollationAttribute.VALUE_ON);
-  * . int result = myCollation->compare("\\u30C3\\u30CF", 
-  * .                                   "\\u30C4\\u30CF");
-  * . // result will be Collator.RESULT_LESS.
-  * </pre>
-  * @param type the attribute to be set from CollationAttribute
-  * @param value attribute value from CollationAttribute
-  * @stable ICU 2.4
-  */
-  public abstract void setAttribute(int type, int value);
-  
-  /**
-  * Get the sort key as an CollationKey object from the argument string.
-  * To retrieve sort key in terms of byte arrays, use the method as below<br>
-  * <code>
-  * Collator collator = Collator.getInstance();
-  * CollationKey collationkey = collator.getCollationKey("string");
-  * byte[] array = collationkey.toByteArray();
-  * </code><br>
-  * Byte array result are zero-terminated and can be compared using 
-  * java.util.Arrays.equals();
-  * @param source string to be processed.
-  * @return the sort key
-  * @stable ICU 2.4
-  */
-  public abstract CollationKey getCollationKey(String source);
-  
-  /**
-  * Returns a hash of this collation object
-  * @return hash of this collation object
-  * @stable ICU 2.4
-  */
-  public abstract int hashCode();
-  
-  public static Locale[] getAvailableLocales() {
-      return Resources.localesFromStrings(NativeCollation.getAvailableLocalesImpl());
-  }
+
+    /**
+     * Sets the attribute to be used in comparison or transformation.
+     * <p>Example of use:
+     * <pre>
+     * . Collator myCollation = Collator.createInstance(Locale::US);
+     * . myCollation.setAttribute(CollationAttribute.CASE_LEVEL,
+     * .                          CollationAttribute.VALUE_ON);
+     * . int result = myCollation->compare("\\u30C3\\u30CF",
+     * .                                   "\\u30C4\\u30CF");
+     * . // result will be -1.
+     * </pre>
+     * @param type the attribute to be set from CollationAttribute
+     * @param value attribute value from CollationAttribute
+     * @stable ICU 2.4
+     */
+    public abstract void setAttribute(int type, int value);
+
+    /**
+     * Get the sort key as an CollationKey object from the argument string.
+     * To retrieve sort key in terms of byte arrays, use the method as below<br>
+     * <code>
+     * Collator collator = Collator.getInstance();
+     * CollationKey collationKey = collator.getCollationKey("string");
+     * byte[] array = collationKey.toByteArray();
+     * </code><br>
+     * Byte array result are zero-terminated and can be compared using
+     * java.util.Arrays.equals();
+     * @param source string to be processed.
+     * @return the sort key
+     * @stable ICU 2.4
+     */
+    public abstract CollationKey getCollationKey(String source);
+
+    /**
+     * Returns a hash of this collation object
+     * @return hash of this collation object
+     * @stable ICU 2.4
+     */
+    public abstract int hashCode();
+
+    public static Locale[] getAvailableLocales() {
+        return Resources.localesFromStrings(NativeCollation.getAvailableLocalesImpl());
+    }
 }
diff --git a/libcore/icu/src/main/java/com/ibm/icu4jni/text/NativeBreakIterator.java b/libcore/icu/src/main/java/com/ibm/icu4jni/text/NativeBreakIterator.java
index 161f542..3f67a64 100644
--- a/libcore/icu/src/main/java/com/ibm/icu4jni/text/NativeBreakIterator.java
+++ b/libcore/icu/src/main/java/com/ibm/icu4jni/text/NativeBreakIterator.java
@@ -49,7 +49,10 @@
 
     @Override
     public boolean equals(Object object) {
-        if (object == null || !(object instanceof NativeBreakIterator)) {
+        if (object == this) {
+            return true;
+        }
+        if (!(object instanceof NativeBreakIterator)) {
             return false;
         }
         // TODO: is this sufficient? shouldn't we be checking the underlying rules?
diff --git a/libcore/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java b/libcore/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java
index c0aca3b..a87c978 100644
--- a/libcore/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java
+++ b/libcore/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java
@@ -13,7 +13,6 @@
 import java.util.Locale;
 import java.text.CharacterIterator;
 import java.text.ParseException;
-import com.ibm.icu4jni.common.ErrorCode;
 
 /**
 * Concrete implementation class for Collation.
@@ -26,28 +25,28 @@
 *    < reset > < text-argument >
 * </pre>
 * <p>
-* <code>RuleBasedCollator</code> has the following restrictions for efficiency 
+* <code>RuleBasedCollator</code> has the following restrictions for efficiency
 * (other subclasses may be used for more complex languages) :
 * <ol>
-* <li> If a French secondary ordering is specified it applies to the whole 
+* <li> If a French secondary ordering is specified it applies to the whole
 *      collator object.
-* <li> All non-mentioned Unicode characters are at the end of the collation 
+* <li> All non-mentioned Unicode characters are at the end of the collation
 *      order.
-* <li> If a character is not located in the RuleBasedCollator, the default 
-*      Unicode Collation Algorithm (UCA) rulebased table is automatically 
+* <li> If a character is not located in the RuleBasedCollator, the default
+*      Unicode Collation Algorithm (UCA) rule-based table is automatically
 *      searched as a backup.
 * </ol>
 *
 * The following demonstrates how to create your own collation rules:
 * <UL Type=disc>
 *    <LI><strong>Text-Argument</strong>: A text-argument is any sequence of
-*        characters, excluding special characters (that is, common whitespace 
-*        characters [0009-000D, 0020] and rule syntax characters [0021-002F, 
-*        003A-0040, 005B-0060, 007B-007E]). If those characters are desired, 
-*        you can put them in single quotes (e.g. ampersand => '&'). Note that 
-*        unquoted white space characters are ignored; e.g. <code>b c</code> is 
+*        characters, excluding special characters (that is, common whitespace
+*        characters [0009-000D, 0020] and rule syntax characters [0021-002F,
+*        003A-0040, 005B-0060, 007B-007E]). If those characters are desired,
+*        you can put them in single quotes (e.g. ampersand => '&'). Note that
+*        unquoted white space characters are ignored; e.g. <code>b c</code> is
 *        treated as <code>bc</code>.
-*    <LI><strong>Modifier</strong>: There is a single modifier which is used 
+*    <LI><strong>Modifier</strong>: There is a single modifier which is used
 *        to specify that all accents (secondary differences) are backwards.
 *        <p>'@' : Indicates that accents are sorted backwards, as in French.
 *    <LI><strong>Relation</strong>: The relations are the following:
@@ -57,8 +56,8 @@
 *            <LI>',' : Greater, as a case difference (tertiary)
 *            <LI>'=' : Equal
 *        </UL>
-*    <LI><strong>Reset</strong>: There is a single reset which is used 
-*        primarily for contractions and expansions, but which can also be used 
+*    <LI><strong>Reset</strong>: There is a single reset which is used
+*        primarily for contractions and expansions, but which can also be used
 *        to add a modification at the end of a set of rules.
 *        <p>'&' : Indicates that the next rule follows the position to where
 *            the reset text-argument would be sorted.
@@ -89,9 +88,9 @@
 * instead, "e" is sorted as if it were expanded to two characters: "a"
 * followed by an "e". This difference appears in natural languages: in
 * traditional Spanish "ch" is treated as though it contracts to a single
-* character (expressed as "c < ch < d"), while in traditional German a-umlaut 
-* is treated as though it expanded to two characters (expressed as "a,A < b,B 
-* ... & ae;? & AE;?"). [? and ? are, of course, the escape sequences for 
+* character (expressed as "c < ch < d"), while in traditional German a-umlaut
+* is treated as though it expanded to two characters (expressed as "a,A < b,B
+* ... & ae;? & AE;?"). [? and ? are, of course, the escape sequences for
 * a-umlaut.]
 * <p>
 * <strong>Ignorable Characters</strong>
@@ -107,16 +106,16 @@
 * <p><strong>Normalization and Accents</strong>
 * <p>
 * <code>RuleBasedCollator</code> automatically processes its rule table to
-* include both pre-composed and combining-character versions of accented 
-* characters. Even if the provided rule string contains only base characters 
-* and separate combining accent characters, the pre-composed accented 
-* characters matching all canonical combinations of characters from the rule 
+* include both pre-composed and combining-character versions of accented
+* characters. Even if the provided rule string contains only base characters
+* and separate combining accent characters, the pre-composed accented
+* characters matching all canonical combinations of characters from the rule
 * string will be entered in the table.
 * <p>
-* This allows you to use a RuleBasedCollator to compare accented strings even 
-* when the collator is set to NO_DECOMPOSITION. However, if the strings to be 
-* collated contain combining sequences that may not be in canonical order, you 
-* should set the collator to CANONICAL_DECOMPOSITION to enable sorting of 
+* This allows you to use a RuleBasedCollator to compare accented strings even
+* when the collator is set to NO_DECOMPOSITION. However, if the strings to be
+* collated contain combining sequences that may not be in canonical order, you
+* should set the collator to CANONICAL_DECOMPOSITION to enable sorting of
 * combining sequences.
 * For more information, see
 * <A HREF="http://www.aw.com/devpress">The Unicode Standard, Version 3.0</A>.)
@@ -130,7 +129,7 @@
 *     <LI>A relation or reset character not followed by a text-argument
 *        (e.g. "a < , b").
 *     <LI>A reset where the text-argument (or an initial substring of the
-*         text-argument) is not already in the sequence or allocated in the 
+*         text-argument) is not already in the sequence or allocated in the
 *         default UCA table.
 *         (e.g. "a < b & e < f")
 * </UL>
@@ -148,7 +147,7 @@
 * <p>
 * Normally, to create a rule-based Collator object, you will use
 * <code>Collator</code>'s factory method <code>getInstance</code>.
-* However, to create a rule-based Collator object with specialized rules 
+* However, to create a rule-based Collator object with specialized rules
 * tailored to your needs, you construct the <code>RuleBasedCollator</code>
 * with the rules contained in a <code>String</code> object. For example:
 * <blockquote>
@@ -230,7 +229,7 @@
 * <blockquote>
 * <pre>
 * // get en_US Collator rules
-* RuleBasedCollator en_USCollator = 
+* RuleBasedCollator en_USCollator =
 *                      (RuleBasedCollator)Collator.getInstance(Locale.US);
 * // add a few Japanese character to sort before English characters
 * // suppose the last character before the first base letter 'a' in
@@ -242,478 +241,365 @@
 * </blockquote>
 * <P>
 * @author syn wee quek
-* @stable ICU 2.4 
+* @stable ICU 2.4
 */
-    
-public final class RuleBasedCollator extends Collator 
-{
-  // public constructors ------------------------------------------
-  
-  /**
-  * RuleBasedCollator constructor. This takes the table rules and builds a 
-  * collation table out of them. Please see RuleBasedCollator class
-  * description for more details on the collation rule syntax.
-  * @param rules the collation rules to build the collation table from.
-  * @exception ParseException thrown if rules are empty or a Runtime error
-  *            if collator can not be created.
-  * @stable ICU 2.4 
-  */
-  public RuleBasedCollator(String rules) throws ParseException
-  {
-    // BEGIN android-changed
-    if (rules == null) {
-      throw new NullPointerException();
-    }
-    // if (rules.length() == 0)
-    //   throw new ParseException("Build rules empty.", 0);
-    // END android-changed
-    m_collator_ = NativeCollation.openCollatorFromRules(rules,
-                              CollationAttribute.VALUE_OFF,
-                              CollationAttribute.VALUE_DEFAULT_STRENGTH);
-  }
+public final class RuleBasedCollator extends Collator {
+    private int m_collator_;
+    private int m_hashcode_ = 0;
 
-  /**
-  * RuleBasedCollator constructor. This takes the table rules and builds a 
-  * collation table out of them. Please see RuleBasedCollator class
-  * description for more details on the collation rule syntax.
-  * @param rules the collation rules to build the collation table from.
-  * @param strength collation strength
-  * @exception ParseException thrown if rules are empty or a Runtime error
-  *            if collator can not be created.
-  * @see #PRIMARY
-  * @see #SECONDARY
-  * @see #TERTIARY
-  * @see #QUATERNARY
-  * @see #IDENTICAL
-  * @stable ICU 2.4
-  */
-  public RuleBasedCollator(String rules, int strength) throws ParseException
-  {
-    // BEGIN android-changed
-    if (rules == null) {
-      throw new NullPointerException();
+    /**
+     * RuleBasedCollator constructor. This takes the table rules and builds a
+     * collation table out of them. Please see RuleBasedCollator class
+     * description for more details on the collation rule syntax.
+     * @param rules the collation rules to build the collation table from.
+     * @exception ParseException thrown if rules are empty or a Runtime error
+     *            if collator can not be created.
+     * @stable ICU 2.4
+     */
+    public RuleBasedCollator(String rules) throws ParseException {
+        if (rules == null) {
+            throw new NullPointerException();
+        }
+        m_collator_ = NativeCollation.openCollatorFromRules(rules,
+                CollationAttribute.VALUE_OFF, CollationAttribute.VALUE_DEFAULT_STRENGTH);
     }
-    // if (rules.length() == 0)
-    //   throw new ParseException("Build rules empty.", 0);
-    // END android-changed
-    if (!CollationAttribute.checkStrength(strength))
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-      
-    m_collator_ = NativeCollation.openCollatorFromRules(rules,
-                                CollationAttribute.VALUE_OFF,
-                                strength);
-  }
 
-  /**
-  * RuleBasedCollator constructor. This takes the table rules and builds a 
-  * collation table out of them. Please see RuleBasedCollator class
-  * description for more details on the collation rule syntax.
-  * <p>Note API change starting from release 2.4. Prior to release 2.4, the 
-  * normalizationmode argument values are from the class 
-  * com.ibm.icu4jni.text.Normalization. In 2.4, 
-  * the valid normalizationmode arguments for this API are 
-  * CollationAttribute.VALUE_ON and CollationAttribute.VALUE_OFF.
-  * </p>
-  * @param rules the collation rules to build the collation table from.
-  * @param strength collation strength
-  * @param normalizationmode normalization mode
-  * @exception IllegalArgumentException thrown when constructor error occurs
-  * @see #PRIMARY
-  * @see #SECONDARY
-  * @see #TERTIARY
-  * @see #QUATERNARY
-  * @see #IDENTICAL
-  * @see #CANONICAL_DECOMPOSITION
-  * @see #NO_DECOMPOSITION
-  * @stable ICU 2.4
-  */
-  public RuleBasedCollator(String rules, int normalizationmode, int strength)
-  {
-    // BEGIN android-added
-    if (rules == null) {
-      throw new NullPointerException();
+    /**
+     * RuleBasedCollator constructor. This takes the table rules and builds a
+     * collation table out of them. Please see RuleBasedCollator class
+     * description for more details on the collation rule syntax.
+     * @param rules the collation rules to build the collation table from.
+     * @param strength collation strength
+     * @exception ParseException thrown if rules are empty or a Runtime error
+     *            if collator can not be created.
+     * @see #PRIMARY
+     * @see #SECONDARY
+     * @see #TERTIARY
+     * @see #QUATERNARY
+     * @see #IDENTICAL
+     * @stable ICU 2.4
+     */
+    public RuleBasedCollator(String rules, int strength) throws ParseException {
+        if (rules == null) {
+            throw new NullPointerException();
+        }
+        m_collator_ = NativeCollation.openCollatorFromRules(rules, CollationAttribute.VALUE_OFF, strength);
     }
-    // END android-added
-    if (!CollationAttribute.checkStrength(strength) || 
-        !CollationAttribute.checkNormalization(normalizationmode)) {
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-    }
-      
-    m_collator_ = NativeCollation.openCollatorFromRules(rules,
-                                          normalizationmode, strength);
-  }
-  
-  // public methods -----------------------------------------------
-  
-  /**
-  * Makes a complete copy of the current object.
-  * @return a copy of this object if data clone is a success, otherwise null
-  * @stable ICU 2.4 
-  */
-  public Object clone() 
-  {
-    RuleBasedCollator result = null;
-    int collatoraddress = NativeCollation.safeClone(m_collator_);
-    result = new RuleBasedCollator(collatoraddress);
-    return (Collator)result;
-  }
-                              
-  /**
-  * The comparison function compares the character data stored in two
-  * different strings. Returns information about whether a string is less 
-  * than, greater than or equal to another string.
-  * <p>Example of use:
-  * <br>
-  * <code>
-  *   Collator myCollation = Collator.createInstance(Locale::US);
-  *   myCollation.setStrength(CollationAttribute.VALUE_PRIMARY);
-  *   // result would be Collator.RESULT_EQUAL ("abc" == "ABC")
-  *   // (no primary difference between "abc" and "ABC")
-  *   int result = myCollation.compare("abc", "ABC",3);
-  *   myCollation.setStrength(CollationAttribute.VALUE_TERTIARY);
-  *   // result would be Collation::LESS (abc" &lt;&lt;&lt; "ABC")
-  *   // (with tertiary difference between "abc" and "ABC")
-  *   int result = myCollation.compare("abc", "ABC",3);
-  * </code>
-  * @param source The source string.
-  * @param target The target string.
-  * @return result of the comparison, Collator.RESULT_EQUAL, 
-  *         Collator.RESULT_GREATER or Collator.RESULT_LESS
-  * @stable ICU 2.4 
-  */
-  public int compare(String source, String target)
-  {
-    return NativeCollation.compare(m_collator_, source, target);
-  }
-                                               
-  /**
-  * Get the normalization mode for this object.
-  * The normalization mode influences how strings are compared.
-  * @see #CANONICAL_DECOMPOSITION
-  * @see #NO_DECOMPOSITION
-  * @stable ICU 2.4
-  */
-  public int getDecomposition()
-  {
-    return NativeCollation.getNormalization(m_collator_);
-  }
 
-  /**
-  * <p>Sets the decomposition mode of the Collator object on or off.
-  * If the decomposition mode is set to on, string would be decomposed into
-  * NFD format where necessary before sorting.</p>
-  * </p>
-  * @param decompositionmode the new decomposition mode
-  * @see #CANONICAL_DECOMPOSITION
-  * @see #NO_DECOMPOSITION
-  * @stable ICU 2.4
-  */
-  public void setDecomposition(int decompositionmode)
-  {
-    if (!CollationAttribute.checkNormalization(decompositionmode)) 
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-    NativeCollation.setAttribute(m_collator_, 
-                                 CollationAttribute.NORMALIZATION_MODE,
-                                 decompositionmode);
-  }
+    /**
+     * RuleBasedCollator constructor. This takes the table rules and builds a
+     * collation table out of them. Please see RuleBasedCollator class
+     * description for more details on the collation rule syntax.
+     * <p>Note API change starting from release 2.4. Prior to release 2.4, the
+     * normalizationMode argument values are from the class
+     * com.ibm.icu4jni.text.Normalization. In 2.4,
+     * the valid normalizationMode arguments for this API are
+     * CollationAttribute.VALUE_ON and CollationAttribute.VALUE_OFF.
+     * </p>
+     * @param rules the collation rules to build the collation table from.
+     * @param strength collation strength
+     * @param normalizationMode normalization mode
+     * @exception IllegalArgumentException thrown when constructor error occurs
+     * @see #PRIMARY
+     * @see #SECONDARY
+     * @see #TERTIARY
+     * @see #QUATERNARY
+     * @see #IDENTICAL
+     * @see #CANONICAL_DECOMPOSITION
+     * @see #NO_DECOMPOSITION
+     * @stable ICU 2.4
+     */
+    public RuleBasedCollator(String rules, int normalizationMode, int strength) {
+        if (rules == null) {
+            throw new NullPointerException();
+        }
+        m_collator_ = NativeCollation.openCollatorFromRules(rules, normalizationMode, strength);
+    }
 
-  /**
-  * Determines the minimum strength that will be use in comparison or
-  * transformation.
-  * <p>
-  * E.g. with strength == CollationAttribute.VALUE_SECONDARY, the tertiary difference 
-  * is ignored
-  * </p>
-  * <p>
-  * E.g. with strength == PRIMARY, the secondary and tertiary difference are 
-  * ignored.
-  * </p>
-  * @return the current comparison level.
-  * @see #PRIMARY
-  * @see #SECONDARY
-  * @see #TERTIARY
-  * @see #QUATERNARY
-  * @see #IDENTICAL
-  * @stable ICU 2.4
-  */
-  public int getStrength()
-  {
-    return NativeCollation.getAttribute(m_collator_, 
-                                        CollationAttribute.STRENGTH);
-  }
-  
-  /**
-  * Sets the minimum strength to be used in comparison or transformation.
-  * <p>Example of use:
-  * <br>
-  * <code>
-  * Collator myCollation = Collator.createInstance(Locale::US);
-  * myCollation.setStrength(PRIMARY);
-  * // result will be "abc" == "ABC"
-  * // tertiary differences will be ignored
-  * int result = myCollation->compare("abc", "ABC");
-  * </code>
-  * @param strength the new comparison level.
-  * @exception IllegalArgumentException when argument does not belong to any collation strength 
-  *            mode or error occurs while setting data.
-  * @see #PRIMARY
-  * @see #SECONDARY
-  * @see #TERTIARY
-  * @see #QUATERNARY
-  * @see #IDENTICAL
-  * @stable ICU 2.4
-  */
-  public void setStrength(int strength)
-  {
-    if (!CollationAttribute.checkStrength(strength)) 
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-    NativeCollation.setAttribute(m_collator_, CollationAttribute.STRENGTH, 
-                                 strength);
-  }
-  
-  /**
-  * Sets the attribute to be used in comparison or transformation.
-  * <p>Example of use:
-  * <br>
-  * <code>
-  *  Collator myCollation = Collator.createInstance(Locale::US);
-  *  myCollation.setAttribute(CollationAttribute.CASE_LEVEL, 
-  *                           CollationAttribute.VALUE_ON);
-  *  int result = myCollation->compare("\\u30C3\\u30CF", 
-  *                                    "\\u30C4\\u30CF");
-  * // result will be Collator.RESULT_LESS.
-  * </code>
-  * @param type the attribute to be set from CollationAttribute
-  * @param value attribute value from CollationAttribute
-  * @stable ICU 2.4
-  */
-  public void setAttribute(int type, int value)
-  {
-    if (!CollationAttribute.checkAttribute(type, value))
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-    NativeCollation.setAttribute(m_collator_, type, value);
-  }
-  
-  /**
-  * Gets the attribute to be used in comparison or transformation.
-  * @param type the attribute to be set from CollationAttribute
-  * @return value attribute value from CollationAttribute
-  * @stable ICU 2.4 
-  */
-  public int getAttribute(int type)
-  {
-    if (!CollationAttribute.checkType(type))
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-    return NativeCollation.getAttribute(m_collator_, type);
-  }
-  
-  /**
-  * Get the sort key as an CollationKey object from the argument string.
-  * To retrieve sort key in terms of byte arrays, use the method as below<br>
-  * <br>
-  * <code>
-  * Collator collator = Collator.getInstance();
-  * byte[] array = collator.getSortKey(source);
-  * </code><br>
-  * Byte array result are zero-terminated and can be compared using 
-  * java.util.Arrays.equals();
-  * @param source string to be processed.
-  * @return the sort key
-  * @stable ICU 2.4 
-  */
-  public CollationKey getCollationKey(String source)
-  {
-    // BEGIN android-removed
-    // return new CollationKey(NativeCollation.getSortKey(m_collator_, source));
-    // END android-removed
-    // BEGIN android-added
-    if(source == null) {
-        return null;
+    /**
+     * Makes a complete copy of the current object.
+     * @return a copy of this object if data clone is a success, otherwise null
+     * @stable ICU 2.4
+     */
+    public Object clone() {
+        RuleBasedCollator result = null;
+        int collatoraddress = NativeCollation.safeClone(m_collator_);
+        result = new RuleBasedCollator(collatoraddress);
+        return (Collator)result;
     }
-    byte[] key = NativeCollation.getSortKey(m_collator_, source);
-    if(key == null) {
-      return null;
-    }
-    return new CollationKey(key);
-    // END android-added
-  }
-  
-  /**
-  * Get a sort key for the argument string
-  * Sort keys may be compared using java.util.Arrays.equals
-  * @param source string for key to be generated
-  * @return sort key
-  * @stable ICU 2.4 
-  */
-  public byte[] getSortKey(String source)
-  {
-    return NativeCollation.getSortKey(m_collator_, source);
-  }
-  
-  /**
-  * Get the collation rules of this Collation object
-  * The rules will follow the rule syntax.
-  * @return collation rules.
-  * @stable ICU 2.4 
-  */
-  public String getRules()
-  {
-    return NativeCollation.getRules(m_collator_);
-  }
-  
-  /** 
-  * Create a CollationElementIterator object that will iterator over the 
-  * elements in a string, using the collation rules defined in this 
-  * RuleBasedCollator
-  * @param source string to iterate over
-  * @return address of C collationelement
-  * @exception IllegalArgumentException thrown when error occurs
-  * @stable ICU 2.4 
-  */
-  public CollationElementIterator getCollationElementIterator(String source)
-  {
-    CollationElementIterator result = new CollationElementIterator(
-         NativeCollation.getCollationElementIterator(m_collator_, source));
-    // result.setOwnCollationElementIterator(true);
-    return result;
-  }
-  
-  // BEGIN android-added
-  /** 
-  * Create a CollationElementIterator object that will iterator over the 
-  * elements in a string, using the collation rules defined in this 
-  * RuleBasedCollator
-  * @param source string to iterate over
-  * @return address of C collationelement
-  * @exception IllegalArgumentException thrown when error occurs
-  * @stable ICU 2.4 
-  */
-  public CollationElementIterator getCollationElementIterator(
-          CharacterIterator source)
-  {
-    CollationElementIterator result = new CollationElementIterator(
-         NativeCollation.getCollationElementIterator(m_collator_, 
-                 source.toString()));
-    // result.setOwnCollationElementIterator(true);
-    return result;
-  }
-  // END android-added
-  
-  /**
-  * Returns a hash of this collation object
-  * Note this method is not complete, it only returns 0 at the moment.
-  * @return hash of this collation object
-  * @stable ICU 2.4 
-  */
-  public int hashCode()
-  {
-    // since rules do not change once it is created, we can cache the hash
-    if (m_hashcode_ == 0) {
-      m_hashcode_ = NativeCollation.hashCode(m_collator_);
-      if (m_hashcode_ == 0)
-        m_hashcode_ = 1;
-    }
-    return m_hashcode_;
-  }
-  
-  /**
-  * Checks if argument object is equals to this object.
-  * @param target object
-  * @return true if source is equivalent to target, false otherwise 
-  * @stable ICU 2.4 
-  */
-  public boolean equals(Object target)
-  {
-    if (this == target) 
-      return true;
-    if (target == null) 
-      return false;
-    if (getClass() != target.getClass()) 
-      return false;
-    
-    RuleBasedCollator tgtcoll = (RuleBasedCollator)target;
-    return getRules().equals(tgtcoll.getRules()) && 
-           getStrength() == tgtcoll.getStrength() && 
-           getDecomposition() == tgtcoll.getDecomposition();
-  }
-  
-  // package constructor ----------------------------------------
-  
-  /**
-  * RuleBasedCollator default constructor. This constructor takes the default 
-  * locale. The only caller of this class should be Collator.getInstance(). 
-  * Current implementation createInstance() returns a RuleBasedCollator(Locale) 
-  * instance. The RuleBasedCollator will be created in the following order,
-  * <ul>
-  * <li> Data from argument locale resource bundle if found, otherwise
-  * <li> Data from parent locale resource bundle of arguemtn locale if found,
-  *      otherwise
-  * <li> Data from built-in default collation rules if found, other
-  * <li> null is returned
-  * </ul>
-  */
-  RuleBasedCollator()
-  {
-    m_collator_ = NativeCollation.openCollator();
-  }
 
-  /**
-  * RuleBasedCollator constructor. This constructor takes a locale. The 
-  * only caller of this class should be Collator.createInstance(). 
-  * Current implementation createInstance() returns a RuleBasedCollator(Locale) 
-  * instance. The RuleBasedCollator will be created in the following order,
-  * <ul>
-  * <li> Data from argument locale resource bundle if found, otherwise
-  * <li> Data from parent locale resource bundle of arguemtn locale if found,
-  *      otherwise
-  * <li> Data from built-in default collation rules if found, other
-  * <li> null is returned
-  * </ul>
-  * @param locale locale used
-  */
-  RuleBasedCollator(Locale locale)
-  {
-    if (locale == null) {
-      m_collator_ = NativeCollation.openCollator();
+    /**
+     * The comparison function compares the character data stored in two
+     * different strings. Returns information about whether a string is less
+     * than, greater than or equal to another string.
+     * <p>Example of use:
+     * <br>
+     * <code>
+     *   Collator myCollation = Collator.createInstance(Locale::US);
+     *   myCollation.setStrength(CollationAttribute.VALUE_PRIMARY);
+     *   // result would be 0 ("abc" == "ABC")
+     *   // (no primary difference between "abc" and "ABC")
+     *   int result = myCollation.compare("abc", "ABC",3);
+     *   myCollation.setStrength(CollationAttribute.VALUE_TERTIARY);
+     *   // result would be -1 (abc" &lt;&lt;&lt; "ABC")
+     *   // (with tertiary difference between "abc" and "ABC")
+     *   int result = myCollation.compare("abc", "ABC",3);
+     * </code>
+     */
+    public int compare(String source, String target) {
+        return NativeCollation.compare(m_collator_, source, target);
     }
-    else {
-      m_collator_ = NativeCollation.openCollator(locale.toString());
+
+    /**
+     * Get the normalization mode for this object.
+     * The normalization mode influences how strings are compared.
+     * @see #CANONICAL_DECOMPOSITION
+     * @see #NO_DECOMPOSITION
+     * @stable ICU 2.4
+     */
+    public int getDecomposition() {
+        return NativeCollation.getNormalization(m_collator_);
     }
-  }
-  
-  // protected methods --------------------------------------------
-  
-  /**
-  * Garbage collection.
-  * Close C collator and reclaim memory.
-  */
-  protected void finalize()
-  {
-    NativeCollation.closeCollator(m_collator_);
-  }
-  
-  // private data members -----------------------------------------
-  
-  /**
-  * C collator
-  */
-  private int m_collator_;
-  
-  /**
-  * Hash code for rules
-  */
-  private int m_hashcode_ = 0;
-  
-  // private constructor -----------------------------------------
-  
-  /**
-  * Private use constructor.
-  * Does not create any instance of the C collator. Accepts argument as the
-  * C collator for new instance.
-  * @param collatoraddress address of C collator
-  */
-  private RuleBasedCollator(int collatoraddress)
-  {
-    m_collator_ = collatoraddress;
-  }
+
+    /**
+     * <p>Sets the decomposition mode of the Collator object on or off.
+     * If the decomposition mode is set to on, string would be decomposed into
+     * NFD format where necessary before sorting.</p>
+     * </p>
+     * @param decompositionmode the new decomposition mode
+     * @see #CANONICAL_DECOMPOSITION
+     * @see #NO_DECOMPOSITION
+     * @stable ICU 2.4
+     */
+    public void setDecomposition(int decompositionmode) {
+        NativeCollation.setAttribute(m_collator_,
+                CollationAttribute.NORMALIZATION_MODE, decompositionmode);
+    }
+
+    /**
+     * Determines the minimum strength that will be use in comparison or
+     * transformation.
+     * <p>
+     * E.g. with strength == CollationAttribute.VALUE_SECONDARY, the tertiary difference
+     * is ignored
+     * </p>
+     * <p>
+     * E.g. with strength == PRIMARY, the secondary and tertiary difference are
+     * ignored.
+     * </p>
+     * @return the current comparison level.
+     * @see #PRIMARY
+     * @see #SECONDARY
+     * @see #TERTIARY
+     * @see #QUATERNARY
+     * @see #IDENTICAL
+     * @stable ICU 2.4
+     */
+    public int getStrength() {
+        return NativeCollation.getAttribute(m_collator_, CollationAttribute.STRENGTH);
+    }
+
+    /**
+     * Sets the minimum strength to be used in comparison or transformation.
+     * <p>Example of use:
+     * <br>
+     * <code>
+     * Collator myCollation = Collator.createInstance(Locale::US);
+     * myCollation.setStrength(PRIMARY);
+     * // result will be "abc" == "ABC"
+     * // tertiary differences will be ignored
+     * int result = myCollation->compare("abc", "ABC");
+     * </code>
+     * @param strength the new comparison level.
+     * @exception IllegalArgumentException when argument does not belong to any collation strength
+     *            mode or error occurs while setting data.
+     * @see #PRIMARY
+     * @see #SECONDARY
+     * @see #TERTIARY
+     * @see #QUATERNARY
+     * @see #IDENTICAL
+     * @stable ICU 2.4
+     */
+    public void setStrength(int strength) {
+        NativeCollation.setAttribute(m_collator_, CollationAttribute.STRENGTH, strength);
+    }
+
+    /**
+     * Sets the attribute to be used in comparison or transformation.
+     * <p>Example of use:
+     * <br>
+     * <code>
+     *  Collator myCollation = Collator.createInstance(Locale::US);
+     *  myCollation.setAttribute(CollationAttribute.CASE_LEVEL,
+     *                           CollationAttribute.VALUE_ON);
+     *  int result = myCollation->compare("\\u30C3\\u30CF",
+     *                                    "\\u30C4\\u30CF");
+     * // result will be -1
+     * </code>
+     * @param type the attribute to be set from CollationAttribute
+     * @param value attribute value from CollationAttribute
+     * @stable ICU 2.4
+     */
+    public void setAttribute(int type, int value) {
+        NativeCollation.setAttribute(m_collator_, type, value);
+    }
+
+    /**
+     * Gets the attribute to be used in comparison or transformation.
+     * @param type the attribute to be set from CollationAttribute
+     * @return value attribute value from CollationAttribute
+     * @stable ICU 2.4
+     */
+    public int getAttribute(int type) {
+        return NativeCollation.getAttribute(m_collator_, type);
+    }
+
+    /**
+     * Get the sort key as an CollationKey object from the argument string.
+     * To retrieve sort key in terms of byte arrays, use the method as below<br>
+     * <br>
+     * <code>
+     * Collator collator = Collator.getInstance();
+     * byte[] array = collator.getSortKey(source);
+     * </code><br>
+     * Byte array result are zero-terminated and can be compared using
+     * java.util.Arrays.equals();
+     * @param source string to be processed.
+     * @return the sort key
+     * @stable ICU 2.4
+     */
+    public CollationKey getCollationKey(String source) {
+        if (source == null) {
+            return null;
+        }
+        byte[] key = NativeCollation.getSortKey(m_collator_, source);
+        if (key == null) {
+            return null;
+        }
+        return new CollationKey(source, key);
+    }
+
+    /**
+     * Get a sort key for the argument string
+     * Sort keys may be compared using java.util.Arrays.equals
+     * @param source string for key to be generated
+     * @return sort key
+     * @stable ICU 2.4
+     */
+    public byte[] getSortKey(String source) {
+        return NativeCollation.getSortKey(m_collator_, source);
+    }
+
+    /**
+     * Get the collation rules of this Collation object
+     * The rules will follow the rule syntax.
+     * @return collation rules.
+     * @stable ICU 2.4
+     */
+    public String getRules() {
+        return NativeCollation.getRules(m_collator_);
+    }
+
+    /**
+     * Create a CollationElementIterator object that will iterator over the
+     * elements in a string, using the collation rules defined in this
+     * RuleBasedCollator
+     * @param source string to iterate over
+     * @return address of C collationelement
+     * @exception IllegalArgumentException thrown when error occurs
+     * @stable ICU 2.4
+     */
+    public CollationElementIterator getCollationElementIterator(String source) {
+        CollationElementIterator result = new CollationElementIterator(
+                NativeCollation.getCollationElementIterator(m_collator_, source));
+        // result.setOwnCollationElementIterator(true);
+        return result;
+    }
+
+    public CollationElementIterator getCollationElementIterator(CharacterIterator source) {
+        return getCollationElementIterator(source.toString());
+    }
+
+    /**
+     * Returns a hash of this collation object
+     * Note this method is not complete, it only returns 0 at the moment.
+     * @return hash of this collation object
+     * @stable ICU 2.4
+     */
+    public int hashCode() {
+        // since rules do not change once it is created, we can cache the hash
+        if (m_hashcode_ == 0) {
+            m_hashcode_ = NativeCollation.hashCode(m_collator_);
+            if (m_hashcode_ == 0) {
+                m_hashcode_ = 1;
+            }
+        }
+        return m_hashcode_;
+    }
+
+    /**
+     * Checks if argument object is equals to this object.
+     * @param target object
+     * @return true if source is equivalent to target, false otherwise
+     * @stable ICU 2.4
+     */
+    public boolean equals(Object object) {
+        if (object ==  this) {
+            return true;
+        }
+        if (!(object instanceof RuleBasedCollator)) {
+            return false;
+        }
+        RuleBasedCollator rhs = (RuleBasedCollator) object;
+        return getRules().equals(rhs.getRules()) &&
+                getStrength() == rhs.getStrength() &&
+                getDecomposition() == rhs.getDecomposition();
+    }
+
+    /**
+     * RuleBasedCollator default constructor. This constructor takes the default
+     * locale. The only caller of this class should be Collator.getInstance().
+     * Current implementation createInstance() returns a RuleBasedCollator(Locale)
+     * instance. The RuleBasedCollator will be created in the following order,
+     * <ul>
+     * <li> Data from argument locale resource bundle if found, otherwise
+     * <li> Data from parent locale resource bundle of arguemtn locale if found,
+     *      otherwise
+     * <li> Data from built-in default collation rules if found, other
+     * <li> null is returned
+     * </ul>
+     */
+    RuleBasedCollator() {
+        m_collator_ = NativeCollation.openCollator();
+    }
+
+    /**
+     * RuleBasedCollator constructor. This constructor takes a locale. The
+     * only caller of this class should be Collator.createInstance().
+     * Current implementation createInstance() returns a RuleBasedCollator(Locale)
+     * instance. The RuleBasedCollator will be created in the following order,
+     * <ul>
+     * <li> Data from argument locale resource bundle if found, otherwise
+     * <li> Data from parent locale resource bundle of arguemtn locale if found,
+     *      otherwise
+     * <li> Data from built-in default collation rules if found, other
+     * <li> null is returned
+     * </ul>
+     * @param locale locale used
+     */
+    RuleBasedCollator(Locale locale) {
+        if (locale == null) {
+            m_collator_ = NativeCollation.openCollator();
+        } else {
+            m_collator_ = NativeCollation.openCollator(locale.toString());
+        }
+    }
+
+    protected void finalize() {
+        NativeCollation.closeCollator(m_collator_);
+    }
+
+    private RuleBasedCollator(int collatoraddress) {
+        m_collator_ = collatoraddress;
+    }
 }
diff --git a/libcore/icu/src/main/native/NativeCollation.cpp b/libcore/icu/src/main/native/NativeCollation.cpp
index 52c1c7c..09f192b 100644
--- a/libcore/icu/src/main/native/NativeCollation.cpp
+++ b/libcore/icu/src/main/native/NativeCollation.cpp
@@ -84,31 +84,16 @@
     return result;
 }
 
-/**
-* Universal attribute getter
-* @param env JNI environment
-* @param obj RuleBasedCollatorJNI object
-* @param address address of the C collator
-* @param type type of attribute to be set
-* @return attribute value
-* @exception thrown when error occurs while getting attribute value
-*/
-static jint getAttribute(JNIEnv *env, jclass obj, jint address,
-        jint type) {
-
+static jint getAttribute(JNIEnv *env, jclass, jint address, jint type) {
     const UCollator *collator = (const UCollator *)(int)address;
-    UErrorCode status = U_ZERO_ERROR;
-    if(collator){
-        jint result = (jint)ucol_getAttribute(collator, (UColAttribute)type, 
-                                            &status);
-        if (icu4jni_error(env, status) != FALSE){
-            return (jint)UCOL_DEFAULT;
-        }
-        return result;
-    }else{
-        icu4jni_error(env,U_ILLEGAL_ARGUMENT_ERROR);
+    if (!collator) {
+        icu4jni_error(env, U_ILLEGAL_ARGUMENT_ERROR);
+        return 0;
     }
-    return (jint)UCOL_DEFAULT;
+    UErrorCode status = U_ZERO_ERROR;
+    jint result = (jint)ucol_getAttribute(collator, (UColAttribute)type, &status);
+    icu4jni_error(env, status);
+    return result;
 }
 
 /** 
@@ -463,23 +448,11 @@
   return result;
 }
 
-/**
-* Universal attribute setter.
-* @param env JNI environment
-* @param obj RuleBasedCollatorJNI object
-* @param address address of the C collator
-* @param type type of attribute to be set
-* @param value attribute value
-* @exception thrown when error occurs while setting attribute value
-*/
-static void setAttribute(JNIEnv *env, jclass obj, jint address,
-        jint type, jint value) {
-
-  UCollator *collator = (UCollator *)(int)address;
-  UErrorCode status = U_ZERO_ERROR;
-  ucol_setAttribute(collator, (UColAttribute)type, (UColAttributeValue)value, 
-                    &status);
-   icu4jni_error(env, status);
+static void setAttribute(JNIEnv *env, jclass, jint address, jint type, jint value) {
+    UCollator *collator = (UCollator *)(int)address;
+    UErrorCode status = U_ZERO_ERROR;
+    ucol_setAttribute(collator, (UColAttribute)type, (UColAttributeValue)value, &status);
+    icu4jni_error(env, status);
 }
 
 /**
diff --git a/libcore/text/src/main/java/java/text/CollationKey.java b/libcore/text/src/main/java/java/text/CollationKey.java
index a994fe2..946f462 100644
--- a/libcore/text/src/main/java/java/text/CollationKey.java
+++ b/libcore/text/src/main/java/java/text/CollationKey.java
@@ -15,11 +15,8 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// The icu implementation used was changed from icu4j to icu4jni.
-// END android-note
-
 package java.text;
+
 /**
  * Represents a string under the rules of a specific {@code Collator} object.
  * Comparing two {@code CollationKey} instances returns the relative order of
@@ -81,51 +78,21 @@
  * @see Collator
  * @see RuleBasedCollator
  */
-public final class CollationKey implements Comparable<CollationKey> {
+public abstract class CollationKey implements Comparable<CollationKey> {
+    private final String source;
 
-    private String source;
-
-    private com.ibm.icu4jni.text.CollationKey icuKey;
-
-    CollationKey(String source, com.ibm.icu4jni.text.CollationKey key) {
+    protected CollationKey(String source) {
         this.source = source;
-        this.icuKey = key;
     }
 
     /**
-     * Compares this object to the specified collation key object to determine
-     * their relative order.
+     * Compares this collation key to the given collation key.
      * 
-     * @param value
-     *            the collation key object to compare this object to.
-     * @return a negative value if this {@code CollationKey} is less than the
-     *         specified {@code CollationKey}, 0 if they are equal and a
-     *         positive value if this {@code CollationKey} is greater.
+     * @param value the other collation key.
+     * @return a negative value if this key is less than {@code value},
+     *         0 if they are equal, and a positive value if this key is greater.
      */
-    public int compareTo(CollationKey value) {
-        return icuKey.compareTo(value.icuKey);
-    }
-
-    /**
-     * Compares the specified object to this {@code CollationKey} and indicates
-     * if they are equal. The object must be an instance of {@code CollationKey}
-     * and have the same source string and collation key. Both instances of
-     * {@code CollationKey} must have been created by the same {@code Collator}.
-     * 
-     * @param object
-     *            the object to compare to this object.
-     * @return {@code true} if {@code object} is equal to this collation key;
-     *         {@code false} otherwise.
-     * @see #hashCode
-     */
-    @Override
-    public boolean equals(Object object) {
-        if (!(object instanceof CollationKey)) {
-            return false;
-        }
-        CollationKey collationKey = (CollationKey) object;
-        return icuKey.equals(collationKey.icuKey);
-    }
+    public abstract int compareTo(CollationKey value);
 
     /**
      * Returns the string from which this collation key was created.
@@ -133,28 +100,13 @@
      * @return the source string of this collation key.
      */
     public String getSourceString() {
-        return this.source;
+        return source;
     }
 
     /**
-     * Returns an integer hash code for the receiver. Objects which are equal
-     * return the same value for this method.
-     * 
-     * @return the receiver's hash.
-     * 
-     * @see #equals
-     */
-    @Override
-    public int hashCode() {
-        return icuKey.hashCode();
-    }
-
-    /**
-     * Returns the collation key as a byte array.
+     * Returns this collation key as a byte array.
      * 
      * @return an array of bytes.
      */
-    public byte[] toByteArray() {
-        return icuKey.toByteArray();
-    }
+    public abstract byte[] toByteArray();
 }
diff --git a/libcore/text/src/main/java/java/text/Collator.java b/libcore/text/src/main/java/java/text/Collator.java
index 1064459..bbfc76d 100644
--- a/libcore/text/src/main/java/java/text/Collator.java
+++ b/libcore/text/src/main/java/java/text/Collator.java
@@ -114,13 +114,6 @@
  * @see CollationKey
  */
 public abstract class Collator implements Comparator<Object>, Cloneable {
-
-    static final int EQUAL = 0;
-
-    static final int GREATER = 1;
-
-    static final int LESS = -1;
-
     /**
      * Constant used to specify the decomposition rule.
      */
@@ -362,16 +355,13 @@
     }
 
     private int decompositionMode_Java_ICU(int mode) {
-        int icuDecomp = mode;
         switch (mode) {
-            case Collator.CANONICAL_DECOMPOSITION:
-                icuDecomp = com.ibm.icu4jni.text.Collator.CANONICAL_DECOMPOSITION;
-                break;
-            case Collator.NO_DECOMPOSITION:
-                icuDecomp = com.ibm.icu4jni.text.Collator.NO_DECOMPOSITION;
-                break;
+        case Collator.CANONICAL_DECOMPOSITION:
+            return com.ibm.icu4jni.text.Collator.CANONICAL_DECOMPOSITION;
+        case Collator.NO_DECOMPOSITION:
+            return com.ibm.icu4jni.text.Collator.NO_DECOMPOSITION;
         }
-        return icuDecomp;
+        throw new IllegalArgumentException();
     }
 
     private int decompositionMode_ICU_Java(int mode) {
@@ -388,23 +378,17 @@
     }
 
     private int strength_Java_ICU(int value) {
-        int icuValue = value;
         switch (value) {
-            case Collator.PRIMARY:
-                icuValue = com.ibm.icu4jni.text.Collator.PRIMARY;
-                break;
-            case Collator.SECONDARY:
-                icuValue = com.ibm.icu4jni.text.Collator.SECONDARY;
-                break;
-            case Collator.TERTIARY:
-                icuValue = com.ibm.icu4jni.text.Collator.TERTIARY;
-                break;
-            case Collator.IDENTICAL:
-                icuValue = com.ibm.icu4jni.text.Collator.IDENTICAL;
-                break;
+        case Collator.PRIMARY:
+            return com.ibm.icu4jni.text.Collator.PRIMARY;
+        case Collator.SECONDARY:
+            return com.ibm.icu4jni.text.Collator.SECONDARY;
+        case Collator.TERTIARY:
+            return com.ibm.icu4jni.text.Collator.TERTIARY;
+        case Collator.IDENTICAL:
+            return com.ibm.icu4jni.text.Collator.IDENTICAL;
         }
-        return icuValue;
-
+        throw new IllegalArgumentException();
     }
 
     private int strength_ICU_Java(int value) {
diff --git a/libcore/text/src/main/java/java/text/RuleBasedCollator.java b/libcore/text/src/main/java/java/text/RuleBasedCollator.java
index 6a95473..77b3ffc 100644
--- a/libcore/text/src/main/java/java/text/RuleBasedCollator.java
+++ b/libcore/text/src/main/java/java/text/RuleBasedCollator.java
@@ -420,18 +420,12 @@
      */
     @Override
     public CollationKey getCollationKey(String source) {
-        com.ibm.icu4jni.text.CollationKey icuKey = this.icuColl
-                .getCollationKey(source);
-        if (icuKey == null) {
-            return null;
-        }
-        return new CollationKey(source, icuKey);
+        return icuColl.getCollationKey(source);
     }
 
     @Override
     public int hashCode() {
-        return ((com.ibm.icu4jni.text.RuleBasedCollator) this.icuColl).getRules()
-                .hashCode();
+        return ((com.ibm.icu4jni.text.RuleBasedCollator) this.icuColl).getRules().hashCode();
     }
 
     /**