Merge "Add dictionary header writing methods."
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 6014646..d7424c0 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -99,112 +99,112 @@
             android:subtypeId="0xc9194f98"
             android:imeSubtypeLocale="en_US"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_en_GB"
             android:subtypeId="0xb045e755"
             android:imeSubtypeLocale="en_GB"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x6f972360"
             android:imeSubtypeLocale="af"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x590dde40"
             android:imeSubtypeLocale="ar"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x70b0f974"
             android:imeSubtypeLocale="az"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x1dc3a859"
             android:imeSubtypeLocale="be"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x0ba9c0e8"
             android:imeSubtypeLocale="bg"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_bulgarian_bds"
             android:subtypeId="0x5f51ba9a"
             android:imeSubtypeLocale="bg"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian_bds"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian_bds,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0xd2e520d5"
             android:imeSubtypeLocale="ca"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x2d3d2ed0"
             android:imeSubtypeLocale="cs"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x2df4605d"
             android:imeSubtypeLocale="da"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x2e2cbe61"
             android:imeSubtypeLocale="de"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x0e7802d3"
             android:imeSubtypeLocale="el"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=greek"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=greek,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x4090554a"
             android:imeSubtypeLocale="eo"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x30a6e00e"
             android:imeSubtypeLocale="es"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_es_US"
             android:subtypeId="0x84d2efc6"
             android:imeSubtypeLocale="es_US"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
     />
     <!--
     <subtype android:icon="@drawable/ic_subtype_keyboard"
@@ -212,7 +212,7 @@
             android:subtypeId="0x623f9286"
             android:imeSubtypeLocale="es_419"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
     />
     -->
     <subtype android:icon="@drawable/ic_subtype_keyboard"
@@ -220,63 +220,63 @@
             android:subtypeId="0xec2d3955"
             android:imeSubtypeLocale="et"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0xbe66c254"
             android:imeSubtypeLocale="fa"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=farsi"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=farsi,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x31cecda3"
             android:imeSubtypeLocale="fi"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x324da12c"
             android:imeSubtypeLocale="fr"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0xeadbb691"
             android:imeSubtypeLocale="fr_CA"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x39753b7f"
             android:imeSubtypeLocale="hi"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=hindi"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=hindi,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x35b7526a"
             android:imeSubtypeLocale="hr"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x35e198ed"
             android:imeSubtypeLocale="hu"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0xe39ac3ca"
             android:imeSubtypeLocale="hy"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=armenian_phonetic"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=armenian_phonetic,EmojiCapable"
     />
     <!-- Java uses the deprecated "in" code instead of the standard "id" code for Indonesian. -->
     <subtype android:icon="@drawable/ic_subtype_keyboard"
@@ -284,21 +284,21 @@
             android:subtypeId="0x7daea460"
             android:imeSubtypeLocale="in"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x7df519e5"
             android:imeSubtypeLocale="is"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x37885a0b"
             android:imeSubtypeLocale="it"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <!-- Java uses the deprecated "iw" code instead of the standard "he" code for Hebrew. -->
     <subtype android:icon="@drawable/ic_subtype_keyboard"
@@ -306,14 +306,14 @@
             android:subtypeId="0x66fb18bd"
             android:imeSubtypeLocale="iw"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x6e119e6a"
             android:imeSubtypeLocale="ka"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=georgian"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=georgian,EmojiCapable"
     />
     <!--
     <subtype android:icon="@drawable/ic_subtype_keyboard"
@@ -321,7 +321,7 @@
             android:subtypeId="0x2d73d2f6"
             android:imeSubtypeLocale="kk"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
     />
     -->
     <subtype android:icon="@drawable/ic_subtype_keyboard"
@@ -329,140 +329,140 @@
             android:subtypeId="0x2e391c04"
             android:imeSubtypeLocale="ky"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x8315772c"
             android:imeSubtypeLocale="lo"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=lao"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=lao,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x8321bb43"
             android:imeSubtypeLocale="lt"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x833dea45"
             android:imeSubtypeLocale="lv"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0xaf50ab7c"
             android:imeSubtypeLocale="mk"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=south_slavic"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=south_slavic,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0xcdcfc3ab"
             android:imeSubtypeLocale="mn"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=mongolian"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=mongolian,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x84c87c61"
             android:imeSubtypeLocale="ms"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x3f12ee14"
             android:imeSubtypeLocale="nb"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0xd80a4cee"
             android:imeSubtypeLocale="ne"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=nepali_romanized"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=nepali_romanized,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_nepali_traditional"
             android:subtypeId="0x5fafea88"
             android:imeSubtypeLocale="ne"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=nepali_traditional"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=nepali_traditional,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x3f9fd91e"
             android:imeSubtypeLocale="nl"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x500ca92c"
             android:imeSubtypeLocale="nl_BE"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=azerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=azerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x43098a5c"
             android:imeSubtypeLocale="pl"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0xcafff4a6"
             android:imeSubtypeLocale="pt_BR"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0xe2fffc5a"
             android:imeSubtypeLocale="pt_PT"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x8d185978"
             android:imeSubtypeLocale="ro"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x763a8752"
             android:imeSubtypeLocale="ru"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x8e94d413"
             android:imeSubtypeLocale="sk"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x8ea2eb94"
             android:imeSubtypeLocale="sl"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x77c5196e"
             android:imeSubtypeLocale="sr"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
     />
     <!-- TODO: Uncomment once we can handle IETF language tag with script name specified.
     <subtype android:icon="@drawable/ic_subtype_keyboard"
@@ -470,14 +470,14 @@
             android:subtypeId="0xXXXXXXXX"
             android:imeSubtypeLocale="sr"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_serbian_latin"
             android:subtypeId="0xXXXXXXXX"
             android:imeSubtypeLocale="sr-Latn"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     -->
     <subtype android:icon="@drawable/ic_subtype_keyboard"
@@ -485,63 +485,63 @@
             android:subtypeId="0x48b4ff43"
             android:imeSubtypeLocale="sv"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x8f3dee1f"
             android:imeSubtypeLocale="sw"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x1f94d5d4"
             android:imeSubtypeLocale="th"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=thai"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=thai,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0xf08285ef"
             android:imeSubtypeLocale="tl"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x4a3179de"
             android:imeSubtypeLocale="tr"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x3e84492c"
             android:imeSubtypeLocale="uk"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x93972eee"
             android:imeSubtypeLocale="vi"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_generic"
             android:subtypeId="0x9b13ab76"
             android:imeSubtypeLocale="zu"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
             android:label="@string/subtype_no_language_qwerty"
             android:subtypeId="0xa239ebad"
             android:imeSubtypeLocale="zz"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable,EmojiCapable"
     />
     <!-- Emoji subtype has to be an addtional subtype added at boot time because ICS doesn't
          support Emoji. -->
@@ -551,7 +551,7 @@
             android:subtypeId="0xc14d88b2"
             android:imeSubtypeLocale="zz"
             android:imeSubtypeMode="keyboard"
-            android:imeSubtypeExtraValue="KeyboardLayoutSet=emoji"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=emoji,EmojiCapable"
     />
     -->
 </input-method>
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
index 702ed20..546fa81 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
@@ -505,10 +505,7 @@
 
     @Override
     public void onKeyClick(final Key key) {
-        // TODO: Save emoticons to recents
-        if (mEmojiCategory.getCurrentCategoryId() != CATEGORY_ID_EMOTICONS) {
-            mEmojiKeyboardAdapter.addRecentKey(key);
-        }
+        mEmojiKeyboardAdapter.addRecentKey(key);
         mEmojiCategory.saveLastTypedCategoryPage();
         final int code = key.getCode();
         if (code == Constants.CODE_OUTPUT_TEXT) {
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 23f037f..bc1383a 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -155,6 +155,15 @@
         return mKeys;
     }
 
+    public Key getKeyFromOutputText(final String outputText) {
+        for (final Key key : getKeys()) {
+            if (outputText.equals(key.getOutputText())) {
+                return key;
+            }
+        }
+        return null;
+    }
+
     public Key getKey(final int code) {
         if (code == Constants.CODE_UNSPECIFIED) {
             return null;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
index f203eb7..2976e23 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
@@ -18,25 +18,27 @@
 
 import android.content.SharedPreferences;
 import android.text.TextUtils;
+import android.util.Log;
 
 import com.android.inputmethod.keyboard.EmojiKeyboardView;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.settings.Settings;
 import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.ArrayDeque;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 /**
  * This is a Keyboard class where you can add keys dynamically shown in a grid layout
  */
 public class DynamicGridKeyboard extends Keyboard {
+    private static final String TAG = DynamicGridKeyboard.class.getSimpleName();
     private static final int TEMPLATE_KEY_CODE_0 = 0x30;
     private static final int TEMPLATE_KEY_CODE_1 = 0x31;
-    // Recent codes are saved as an integer array, so we use comma as a separater.
-    private static final String RECENT_KEY_SEPARATOR = Constants.STRING_COMMA;
 
     private final SharedPreferences mPrefs;
     private final int mLeftPadding;
@@ -84,6 +86,9 @@
     }
 
     private void addKey(final Key usedKey, final boolean addFirst) {
+        if (usedKey == null) {
+            return;
+        }
         synchronized (mGridKeys) {
             mCachedGridKeys = null;
             final GridKey key = new GridKey(usedKey);
@@ -109,27 +114,44 @@
     }
 
     private void saveRecentKeys() {
-        final StringBuilder sb = new StringBuilder();
+        final ArrayList<Object> keys = CollectionUtils.newArrayList();
         for (final Key key : mGridKeys) {
-            sb.append(key.getCode()).append(RECENT_KEY_SEPARATOR);
+            if (key.getOutputText() != null) {
+                keys.add(key.getOutputText());
+            } else {
+                keys.add(key.getCode());
+            }
         }
-        Settings.writeEmojiRecentKeys(mPrefs, sb.toString());
+        final String jsonStr = StringUtils.listToJsonStr(keys);
+        Settings.writeEmojiRecentKeys(mPrefs, jsonStr);
+    }
+
+    private static Key getKey(final Collection<DynamicGridKeyboard> keyboards, final Object o) {
+        for (final DynamicGridKeyboard kbd : keyboards) {
+            if (o instanceof Integer) {
+                final int code = (Integer) o;
+                final Key key = kbd.getKey(code);
+                if (key != null) {
+                    return key;
+                }
+            } else if (o instanceof String) {
+                final String outputText = (String) o;
+                final Key key = kbd.getKeyFromOutputText(outputText);
+                if (key != null) {
+                    return key;
+                }
+            } else {
+                Log.w(TAG, "Invalid object: " + o);
+            }
+        }
+        return null;
     }
 
     public void loadRecentKeys(Collection<DynamicGridKeyboard> keyboards) {
         final String str = Settings.readEmojiRecentKeys(mPrefs);
-        for (String s : str.split(RECENT_KEY_SEPARATOR)) {
-            if (TextUtils.isEmpty(s)) {
-                continue;
-            }
-            final int code = Integer.valueOf(s);
-            for (DynamicGridKeyboard kbd : keyboards) {
-                final Key key = kbd.getKey(code);
-                if (key != null) {
-                    addKeyLast(key);
-                    break;
-                }
-            }
+        final List<Object> keys = StringUtils.jsonStrToList(str);
+        for (final Object o : keys) {
+            addKeyLast(getKey(keyboards, o));
         }
     }
 
diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java
index 029ba02..58cae7d 100644
--- a/java/src/com/android/inputmethod/latin/Constants.java
+++ b/java/src/com/android/inputmethod/latin/Constants.java
@@ -76,6 +76,11 @@
             public static final String ASCII_CAPABLE = "AsciiCapable";
 
             /**
+             * The subtype extra value used to indicate that the subtype keyboard layout is capable
+             * for typing EMOJI characters.
+             */
+            public static final String EMOJI_CAPABLE = "EmojiCapable";
+            /**
              * The subtype extra value used to indicate that the subtype require network connection
              * to work.
              */
@@ -221,7 +226,6 @@
     }
 
     public static final int MAX_INT_BIT_COUNT = 32;
-    public static final String STRING_COMMA = ",";
 
     private Constants() {
         // This utility class is not publicly instantiable.
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index 0889f22..772e252 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -59,16 +59,19 @@
     // Dummy no language QWERTY subtype. See {@link R.xml.method}.
     private static final InputMethodSubtype DUMMY_NO_LANGUAGE_SUBTYPE = new InputMethodSubtype(
             R.string.subtype_no_language_qwerty, R.drawable.ic_subtype_keyboard,
-            SubtypeLocaleUtils.NO_LANGUAGE, "keyboard",
-            "KeyboardLayoutSet=" + SubtypeLocaleUtils.QWERTY
-            + ",AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable",
+            SubtypeLocaleUtils.NO_LANGUAGE, "keyboard", "KeyboardLayoutSet="
+                    + SubtypeLocaleUtils.QWERTY
+                    + "," + Constants.Subtype.ExtraValue.ASCII_CAPABLE
+                    + ",EnabledWhenDefaultIsNotAsciiCapable,"
+                    + Constants.Subtype.ExtraValue.EMOJI_CAPABLE,
             false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */);
     // Caveat: We probably should remove this when we add an Emoji subtype in {@link R.xml.method}.
     // Dummy Emoji subtype. See {@link R.xml.method}.
     private static final InputMethodSubtype DUMMY_EMOJI_SUBTYPE = new InputMethodSubtype(
             R.string.subtype_emoji, R.drawable.ic_subtype_keyboard,
-            SubtypeLocaleUtils.NO_LANGUAGE, "keyboard",
-            "KeyboardLayoutSet=" + SubtypeLocaleUtils.EMOJI,
+            SubtypeLocaleUtils.NO_LANGUAGE, "keyboard", "KeyboardLayoutSet="
+                    + SubtypeLocaleUtils.EMOJI + ","
+                    + Constants.Subtype.ExtraValue.EMOJI_CAPABLE,
             false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */);
 
     static final class NeedsToDisplayLanguage {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
index f333b0d..70931f8 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
@@ -758,8 +758,15 @@
             final FormatOptions formatOptions) {
         int positionOfChildrenPosField = ptNode.mCachedAddressAfterUpdate
                 + getNodeHeaderSize(ptNode, formatOptions);
-        if (ptNode.mFrequency >= 0) {
-            positionOfChildrenPosField += FormatSpec.PTNODE_FREQUENCY_SIZE;
+        if (ptNode.isTerminal()) {
+            // A terminal node has either the terminal id or the frequency.
+            // If positionOfChildrenPosField is incorrect, we may crash when jumping to the children
+            // position.
+            if (formatOptions.mHasTerminalId) {
+                positionOfChildrenPosField += FormatSpec.PTNODE_TERMINAL_ID_SIZE;
+            } else {
+                positionOfChildrenPosField += FormatSpec.PTNODE_FREQUENCY_SIZE;
+            }
         }
         return null == ptNode.mChildren ? FormatSpec.NO_CHILDREN_ADDRESS
                 : ptNode.mChildren.mCachedAddressAfterUpdate - positionOfChildrenPosField;
diff --git a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
index 215faa0..3082bf4 100644
--- a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
@@ -25,6 +25,7 @@
 import android.text.TextUtils;
 import android.view.inputmethod.InputMethodSubtype;
 
+import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
 
 import java.util.ArrayList;
@@ -61,8 +62,9 @@
                         IS_ADDITIONAL_SUBTYPE, layoutDisplayNameExtraValue);
         final int nameId = SubtypeLocaleUtils.getSubtypeNameId(localeString, keyboardLayoutSetName);
         return new InputMethodSubtype(nameId, R.drawable.ic_subtype_keyboard,
-                localeString, KEYBOARD_MODE,
-                layoutExtraValue + "," + additionalSubtypeExtraValue, false, false);
+                localeString, KEYBOARD_MODE, layoutExtraValue + "," + additionalSubtypeExtraValue
+                        + "," + Constants.Subtype.ExtraValue.ASCII_CAPABLE
+                        + "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE, false, false);
     }
 
     public static String getPrefSubtype(final InputMethodSubtype subtype) {
diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
index be41840..121aecf 100644
--- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
@@ -16,16 +16,25 @@
 
 package com.android.inputmethod.latin.utils;
 
-import android.text.TextUtils;
-
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.settings.SettingsValues;
 
+import android.text.TextUtils;
+import android.util.JsonReader;
+import android.util.JsonWriter;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Locale;
 
 public final class StringUtils {
+    private static final String TAG = StringUtils.class.getSimpleName();
     public static final int CAPITALIZE_NONE = 0;  // No caps, or mixed case
     public static final int CAPITALIZE_FIRST = 1; // First only
     public static final int CAPITALIZE_ALL = 2;   // All caps
@@ -390,4 +399,67 @@
         }
         return bytes;
     }
+
+    public static List<Object> jsonStrToList(String s) {
+        final ArrayList<Object> retval = CollectionUtils.newArrayList();
+        final JsonReader reader = new JsonReader(new StringReader(s));
+        try {
+            reader.beginArray();
+            while(reader.hasNext()) {
+                reader.beginObject();
+                while (reader.hasNext()) {
+                    final String name = reader.nextName();
+                    if (name.equals(Integer.class.getSimpleName())) {
+                        retval.add(reader.nextInt());
+                    } else if (name.equals(String.class.getSimpleName())) {
+                        retval.add(reader.nextString());
+                    } else {
+                        Log.w(TAG, "Invalid name: " + name);
+                        reader.skipValue();
+                    }
+                }
+                reader.endObject();
+            }
+            reader.endArray();
+            return retval;
+        } catch (IOException e) {
+        } finally {
+            try {
+                reader.close();
+            } catch (IOException e) {
+            }
+        }
+        return Collections.<Object>emptyList();
+    }
+
+    public static String listToJsonStr(List<Object> list) {
+        if (list == null || list.isEmpty()) {
+            return "";
+        }
+        final StringWriter sw = new StringWriter();
+        final JsonWriter writer = new JsonWriter(sw);
+        try {
+            writer.beginArray();
+            for (final Object o : list) {
+                writer.beginObject();
+                if (o instanceof Integer) {
+                    writer.name(Integer.class.getSimpleName()).value((Integer)o);
+                } else if (o instanceof String) {
+                    writer.name(String.class.getSimpleName()).value((String)o);
+                }
+                writer.endObject();
+            }
+            writer.endArray();
+            return sw.toString();
+        } catch (IOException e) {
+        } finally {
+            try {
+                if (writer != null) {
+                    writer.close();
+                }
+            } catch (IOException e) {
+            }
+        }
+        return "";
+    }
 }
diff --git a/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java
index c6fa943..4e396a1 100644
--- a/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java
@@ -21,6 +21,8 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import java.util.Arrays;
+import java.util.List;
 import java.util.Locale;
 
 @SmallTest
@@ -268,4 +270,14 @@
         final String bytesStr2 = StringUtils.byteArrayToHexString(bytes2);
         assertTrue(bytesStr.equals(bytesStr2));
     }
+
+    public void testJsonStringUtils() {
+        final Object[] objs = new Object[] { 1, "aaa", "bbb", 3 };
+        final List<Object> objArray = Arrays.asList(objs);
+        final String str = StringUtils.listToJsonStr(objArray);
+        final List<Object> newObjArray = StringUtils.jsonStrToList(str);
+        for (int i = 0; i < objs.length; ++i) {
+            assertEquals(objs[i], newObjArray.get(i));
+        }
+    }
 }