am 6aad318b: am 79eae0ad: Merge "Update active key backgrounds" into lmp-dev

* commit '6aad318bd20fc55a2cd356699a1797db33ba236b':
diff --git a/java/res/drawable-hdpi/ic_launcher_keyboard.png b/java/res/drawable-hdpi/ic_launcher_keyboard.png
index 7ae00ed..3a01e61 100644
--- a/java/res/drawable-hdpi/ic_launcher_keyboard.png
+++ b/java/res/drawable-hdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_launcher_keyboard.png b/java/res/drawable-mdpi/ic_launcher_keyboard.png
index cc73f3b..574da25 100644
--- a/java/res/drawable-mdpi/ic_launcher_keyboard.png
+++ b/java/res/drawable-mdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_launcher_keyboard.png b/java/res/drawable-xhdpi/ic_launcher_keyboard.png
index f2ac50d..1769501 100644
--- a/java/res/drawable-xhdpi/ic_launcher_keyboard.png
+++ b/java/res/drawable-xhdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_launcher_keyboard.png b/java/res/drawable-xxhdpi/ic_launcher_keyboard.png
index df386e8..624c82e 100644
--- a/java/res/drawable-xxhdpi/ic_launcher_keyboard.png
+++ b/java/res/drawable-xxhdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_dark.9.png
new file mode 100644
index 0000000..eac4475
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_light.9.png
new file mode 100644
index 0000000..16d1f68
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
new file mode 100644
index 0000000..78923a8
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
new file mode 100644
index 0000000..e57e80d
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
new file mode 100644
index 0000000..0b3d796
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_light.9.png
new file mode 100644
index 0000000..6edd4e3
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
new file mode 100644
index 0000000..61a5efc
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_light.9.png
new file mode 100644
index 0000000..c60a235
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_dark.9.png
new file mode 100644
index 0000000..842c685
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_light.9.png
new file mode 100644
index 0000000..6b03306
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
new file mode 100644
index 0000000..276065e
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_light.9.png
new file mode 100644
index 0000000..e64147f
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
new file mode 100644
index 0000000..c130014
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_light.9.png
new file mode 100644
index 0000000..e433f56
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
new file mode 100644
index 0000000..ee4d16b
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
new file mode 100644
index 0000000..14cba3c
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
new file mode 100644
index 0000000..671c31f
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
new file mode 100644
index 0000000..8a6f32a
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_add_circle_white_24dp.png b/java/res/drawable-xxxhdpi/ic_add_circle_white_24dp.png
new file mode 100644
index 0000000..a0116fa
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_add_circle_white_24dp.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_dark.png
new file mode 100644
index 0000000..0198bce
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_light.png
new file mode 100644
index 0000000..f530ba1
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_dark.png
new file mode 100644
index 0000000..d9022bb
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_light.png
new file mode 100644
index 0000000..89dc4cd
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_dark.png
new file mode 100644
index 0000000..efbf51c
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_light.png
new file mode 100644
index 0000000..95355c6
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_dark.png
new file mode 100644
index 0000000..f5531ea
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_light.png
new file mode 100644
index 0000000..b5085cb
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_dark.png
new file mode 100644
index 0000000..730f75d
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_light.png
new file mode 100644
index 0000000..f4a250d
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_dark.png
new file mode 100644
index 0000000..4658cea
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_light.png
new file mode 100644
index 0000000..7b27829
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_dark.png
new file mode 100644
index 0000000..b70f07a
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_light.png
new file mode 100644
index 0000000..7e05208
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_dark.png
new file mode 100644
index 0000000..c960d15
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_light.png
new file mode 100644
index 0000000..44325cf
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_dark.png
new file mode 100644
index 0000000..bca6bba
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_light.png
new file mode 100644
index 0000000..8f340d2
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_dark.png
new file mode 100644
index 0000000..a06e1d8
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_light.png
new file mode 100644
index 0000000..b247768
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_dark.png
new file mode 100644
index 0000000..3508374
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_light.png
new file mode 100644
index 0000000..82a029e
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_dark.png
new file mode 100644
index 0000000..6797d7b
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_light.png
new file mode 100644
index 0000000..6b622ac
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_dark.png
new file mode 100644
index 0000000..51336e9
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_light.png
new file mode 100644
index 0000000..2ab8fa6
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_dark.png
new file mode 100644
index 0000000..e02ad61
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_light.png
new file mode 100644
index 0000000..b17f066
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_launcher_keyboard.png b/java/res/drawable-xxxhdpi/ic_launcher_keyboard.png
new file mode 100644
index 0000000..39636a1
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_background_lxx_dark.9.png b/java/res/drawable-xxxhdpi/keyboard_background_lxx_dark.9.png
new file mode 100644
index 0000000..a7dd537
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_background_lxx_light.9.png b/java/res/drawable-xxxhdpi/keyboard_background_lxx_light.9.png
new file mode 100644
index 0000000..ef7ab20
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_dark.9.png b/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_dark.9.png
new file mode 100644
index 0000000..b68d3e8
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_light.9.png b/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_light.9.png
new file mode 100644
index 0000000..0da475b
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png b/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
new file mode 100644
index 0000000..fa86340
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_light.9.png b/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_light.9.png
new file mode 100644
index 0000000..e3ff4d4
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_dark.9.png b/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_dark.9.png
new file mode 100644
index 0000000..3489a9c
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_light.9.png b/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_light.9.png
new file mode 100644
index 0000000..2e37972
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_dark.9.png b/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_dark.9.png
new file mode 100644
index 0000000..098fa06
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_light.9.png b/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_light.9.png
new file mode 100644
index 0000000..c1c48c9
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_dark.png b/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_dark.png
new file mode 100644
index 0000000..0dc783d
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_light.png b/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_light.png
new file mode 100644
index 0000000..f3162e4
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_dark.png
new file mode 100644
index 0000000..c8a064d
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_light.png
new file mode 100644
index 0000000..2d2e6e1
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_dark.png
new file mode 100644
index 0000000..27426da
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_light.png
new file mode 100644
index 0000000..4b1a69f
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_dark.png
new file mode 100644
index 0000000..79d3eef
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_light.png
new file mode 100644
index 0000000..a87e240
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_dark.png
new file mode 100644
index 0000000..26f3615
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_light.png
new file mode 100644
index 0000000..93efb37
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_dark.png
new file mode 100644
index 0000000..27bf689
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_light.png
new file mode 100644
index 0000000..c624104
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_dark.png
new file mode 100644
index 0000000..50e0a31
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_light.png
new file mode 100644
index 0000000..3f44249
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_dark.png
new file mode 100644
index 0000000..c101071
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_light.png
new file mode 100644
index 0000000..54e7fb0
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_dark.png
new file mode 100644
index 0000000..8f7dfce
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_light.png
new file mode 100644
index 0000000..07d5551
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_dark.png
new file mode 100644
index 0000000..9c12ec2
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_light.png
new file mode 100644
index 0000000..fc68828
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_dark.png
new file mode 100644
index 0000000..d728b83
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_light.png
new file mode 100644
index 0000000..1351710
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_dark.png
new file mode 100644
index 0000000..e75d556
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_light.png
new file mode 100644
index 0000000..00521bf
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_dark.png
new file mode 100644
index 0000000..f47bf66
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_light.png
new file mode 100644
index 0000000..fdb6cd7
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_dark.png
new file mode 100644
index 0000000..26fd4e7
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_light.png
new file mode 100644
index 0000000..7b0467a
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_dark.png
new file mode 100644
index 0000000..1f6c92d
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_light.png
new file mode 100644
index 0000000..656cf99
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_dark.png
new file mode 100644
index 0000000..8988469
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_light.png
new file mode 100644
index 0000000..aeedba6
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_dark.png
new file mode 100644
index 0000000..9d5b733
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_light.png
new file mode 100644
index 0000000..9db910d
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_dark.png
new file mode 100644
index 0000000..e233d09
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_light.png
new file mode 100644
index 0000000..7e0a964
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_dark.png
new file mode 100644
index 0000000..94de916
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_light.png
new file mode 100644
index 0000000..2b13ba7
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_dark.png
new file mode 100644
index 0000000..134bca6
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_light.png
new file mode 100644
index 0000000..31cf75b
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_light.png
Binary files differ
diff --git a/java/res/drawable/btn_keyboard_key_popup_action_lxx_dark.xml b/java/res/drawable/btn_keyboard_key_popup_action_lxx_dark.xml
new file mode 100644
index 0000000..8b637f2
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_popup_action_lxx_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+          android:drawable="@drawable/btn_keyboard_key_active_pressed_lxx_dark" />
+    <item android:drawable="@drawable/btn_keyboard_key_active_lxx_dark" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_key_popup_action_lxx_light.xml b/java/res/drawable/btn_keyboard_key_popup_action_lxx_light.xml
new file mode 100644
index 0000000..67fc521
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_popup_action_lxx_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+          android:drawable="@drawable/btn_keyboard_key_active_pressed_lxx_light" />
+    <item android:drawable="@drawable/btn_keyboard_key_active_lxx_light" />
+</selector>
diff --git a/java/res/layout/more_keys_keyboard.xml b/java/res/layout/more_keys_keyboard.xml
index f3795af..449c00f 100644
--- a/java/res/layout/more_keys_keyboard.xml
+++ b/java/res/layout/more_keys_keyboard.xml
@@ -27,5 +27,6 @@
     <com.android.inputmethod.keyboard.MoreKeysKeyboardView
         android:id="@+id/more_keys_keyboard_view"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content" />
+        android:layout_height="wrap_content"
+        style="?attr/moreKeysKeyboardViewStyle" />
 </LinearLayout>
diff --git a/java/res/layout/more_keys_keyboard_for_action_lxx.xml b/java/res/layout/more_keys_keyboard_for_action_lxx.xml
new file mode 100644
index 0000000..d23faa4
--- /dev/null
+++ b/java/res/layout/more_keys_keyboard_for_action_lxx.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+>
+    <com.android.inputmethod.keyboard.MoreKeysKeyboardView
+        android:id="@+id/more_keys_keyboard_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        style="?attr/moreKeysKeyboardViewForActionStyle" />
+</LinearLayout>
diff --git a/java/res/values-az-rAZ/bools.xml b/java/res/values-az-rAZ/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-az-rAZ/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-bn-rIN/bools.xml b/java/res/values-bn-rIN/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-bn-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-eu-rES/bools.xml b/java/res/values-eu-rES/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-eu-rES/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-gl-rES/bools.xml b/java/res/values-gl-rES/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-gl-rES/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-hy-rAM/bools.xml b/java/res/values-hy-rAM/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-hy-rAM/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-is-rIS/bools.xml b/java/res/values-is-rIS/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-is-rIS/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-kk-rKZ/bools.xml b/java/res/values-kk-rKZ/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-kk-rKZ/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-km-rKH/bools.xml b/java/res/values-km-rKH/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-km-rKH/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-kn-rIN/bools.xml b/java/res/values-kn-rIN/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-kn-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-ky-rKG/bools.xml b/java/res/values-ky-rKG/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-ky-rKG/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-lo-rLA/bools.xml b/java/res/values-lo-rLA/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-lo-rLA/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-mk-rMK/bools.xml b/java/res/values-mk-rMK/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-mk-rMK/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-ml-rIN/bools.xml b/java/res/values-ml-rIN/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-ml-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-mn-rMN/bools.xml b/java/res/values-mn-rMN/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-mn-rMN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-mr-rIN/bools.xml b/java/res/values-mr-rIN/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-mr-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-ne-rNP/bools.xml b/java/res/values-ne-rNP/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-ne-rNP/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-ta-rIN/bools.xml b/java/res/values-ta-rIN/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-ta-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-te-rIN/bools.xml b/java/res/values-te-rIN/bools.xml
new file mode 100644
index 0000000..130e52e
--- /dev/null
+++ b/java/res/values-te-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Whether this input method should be used as the default for a locale. Override it
+         for supported languages. -->
+    <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 57e7376..f1253b4 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -32,6 +32,8 @@
         <attr name="moreKeysKeyboardStyle" format="reference" />
         <!-- MoreKeysKeyboardView style -->
         <attr name="moreKeysKeyboardViewStyle" format="reference" />
+        <!-- MoreKeysKeyboardView style for action key -->
+        <attr name="moreKeysKeyboardViewForActionStyle" format="reference" />
         <!-- Suggestions strip style -->
         <attr name="suggestionStripViewStyle" format="reference" />
         <!-- Suggestion word style -->
@@ -119,6 +121,8 @@
         <attr name="keyPreviewDismissAnimator" format="reference" />
         <!-- Layout resource for more keys keyboard -->
         <attr name="moreKeysKeyboardLayout" format="reference" />
+        <!-- Layout resource for more keys keyboard of action key -->
+        <attr name="moreKeysKeyboardForActionLayout" format="reference" />
         <attr name="backgroundDimAlpha" format="integer" />
         <!-- More keys keyboard will shown at touched point. -->
         <attr name="showMoreKeysKeyboardAtTouchedPoint" format="boolean" />
@@ -173,6 +177,10 @@
         <attr name="suppressKeyPreviewAfterBatchInputDuration" format="integer" />
     </declare-styleable>
 
+    <declare-styleable name="MoreKeysKeyboardView">
+        <attr name="divider" format="reference" />
+    </declare-styleable>
+
     <declare-styleable name="EmojiPalettesView">
         <attr name="categoryIndicatorEnabled" format="boolean" />
         <attr name="categoryIndicatorDrawable" format="reference" />
@@ -330,6 +338,8 @@
             <!-- If true, use functionalTextColor instead of ketTextColor to drawing the label on
                  the key -->
             <flag name="followFunctionalTextColor" value="0x80000" />
+            <!-- Keep aspect ratio of key background. -->
+            <flag name="keepBackgroundAspectRatio" value="0x100000" />
             <!-- If true, disable keyHintLabel. -->
             <flag name="disableKeyHintLabel" value="0x40000000" />
             <!-- If true, disable additionalMoreKeys. -->
diff --git a/java/res/values/donottranslate-debug-settings.xml b/java/res/values/donottranslate-debug-settings.xml
new file mode 100644
index 0000000..35e6efa
--- /dev/null
+++ b/java/res/values/donottranslate-debug-settings.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Title for Android keyboard debug settings activity / dialog -->
+    <string name="english_ime_debug_settings">Android Keyboard Debug settings</string>
+    <string name="prefs_debug_mode">Debug Mode</string>
+    <string name="prefs_force_non_distinct_multitouch">Force non-distinct multitouch</string>
+    <string name="prefs_force_physical_keyboard_special_key">Force physical keyboard special key</string>
+    <string name="prefs_show_ui_to_accept_typed_word">Show UI to accept typed word</string>
+    <!-- Option to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=30]-->
+    <string name="sliding_key_input_preview">Show slide indicator</string>
+    <!-- Option summary to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=66]-->
+    <string name="sliding_key_input_preview_summary">Display visual cue while sliding from Shift or Symbol keys</string>
+    <!-- Title of the settings for key long press delay [CHAR LIMIT=35] -->
+    <string name="prefs_key_longpress_timeout_settings">Key long press delay</string>
+    <!-- Title of the settings for customize key popup animation parameters [CHAR LIMIT=35] -->
+    <string name="prefs_customize_key_preview_animation">Customize key preview animation</string>
+    <!-- Title of the settings for key popup show up animation duration (in milliseconds) [CHAR LIMIT=35] -->
+    <string name="prefs_key_popup_show_up_duration_settings">Key popup show up duration</string>
+    <!-- Title of the settings for key popup dismiss animation duration (in milliseconds) [CHAR LIMIT=35] -->
+    <string name="prefs_key_popup_dismiss_duration_settings">Key popup dismiss duration</string>
+    <!-- Title of the settings for key popup show up animation start X-scale (in percentile) [CHAR LIMIT=35] -->
+    <string name="prefs_key_popup_show_up_start_x_scale_settings">Key popup show up start X scale</string>
+    <!-- Title of the settings for key popup show up animation start Y-scale (in percentile) [CHAR LIMIT=35] -->
+    <string name="prefs_key_popup_show_up_start_y_scale_settings">Key popup show up start Y scale</string>
+    <!-- Title of the settings for key popup dismiss animation end X-scale (in percentile) [CHAR LIMIT=35] -->
+    <string name="prefs_key_popup_dismiss_end_x_scale_settings">Key popup dismiss end X scale</string>
+    <!-- Title of the settings for key popup dismiss animation end Y-scale (in percentile) [CHAR LIMIT=35] -->
+    <string name="prefs_key_popup_dismiss_end_y_scale_settings">Key popup dismiss end Y scale</string>
+    <!-- Title of the settings for reading an external dictionary file -->
+    <string name="prefs_read_external_dictionary">Read external dictionary file</string>
+    <!-- Message to show when there are no files to install as an external dictionary [CHAR LIMIT=100] -->
+    <string name="read_external_dictionary_no_files_message">No dictionary files in the Downloads folder</string>
+    <!-- Title of the dialog that selects a file to install as an external dictionary [CHAR LIMIT=50] -->
+    <string name="read_external_dictionary_multiple_files_title">Select a dictionary file to install</string>
+    <!-- Title of the confirmation dialog to install a file as an external dictionary [CHAR LIMIT=50] -->
+    <string name="read_external_dictionary_confirm_install_message">Really install this file for <xliff:g id="LANGUAGE_NAME" example="English">%s</xliff:g>?</string>
+    <!-- Title for an error dialog that contains the details of the error in the body [CHAR LIMIT=80] -->
+    <string name="read_external_dictionary_error">There was an error</string>
+    <!-- Title of the settings group for dumpping dictionary files that have been created on the device [CHAR LIMIT=35] -->
+    <string name="prefs_dump_dynamic_dicts">Dump dictionary</string>
+</resources>
diff --git a/java/res/values/donottranslate-text-decorator.xml b/java/res/values/donottranslate-text-decorator.xml
index a200349..832610b 100644
--- a/java/res/values/donottranslate-text-decorator.xml
+++ b/java/res/values/donottranslate-text-decorator.xml
@@ -61,24 +61,18 @@
     <!-- Coordinates of the closed path to be used to render the commit indicator.
          The format is:  X[0], Y[0], X[1], Y[1], ..., X[N-1], Y[N-1] -->
     <integer-array name="text_decorator_commit_indicator_path">
-        <item>240</item>
-        <item>80</item>
-        <item>212</item>
-        <item>108</item>
+        <item>180</item>
         <item>323</item>
-        <item>220</item>
-        <item>80</item>
-        <item>220</item>
-        <item>80</item>
-        <item>260</item>
-        <item>323</item>
-        <item>260</item>
-        <item>212</item>
-        <item>372</item>
+        <item>97</item>
         <item>240</item>
-        <item>400</item>
-        <item>400</item>
-        <item>240</item>
+        <item>68</item>
+        <item>268</item>
+        <item>180</item>
+        <item>380</item>
+        <item>420</item>
+        <item>140</item>
+        <item>392</item>
+        <item>112</item>
     </integer-array>
 
     <!-- Background color to be used to highlight the target text when the add-to-dictionary
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index b25a208..c54b995 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -22,13 +22,6 @@
          See {@link SettingsValues#needsToShowVoiceInputKey(SharedPreferences,Resources)} -->
     <string name="voice_mode_main">0</string>
 
-    <!-- Title for Android keyboard debug settings activity / dialog -->
-    <string name="english_ime_debug_settings">Android Keyboard Debug settings</string>
-    <string name="prefs_debug_mode">Debug Mode</string>
-    <string name="prefs_force_non_distinct_multitouch">Force non-distinct multitouch</string>
-    <string name="prefs_force_physical_keyboard_special_key">Force physical keyboard special key</string>
-    <string name="prefs_show_ui_to_accept_typed_word">Show UI to accept typed word</string>
-
     <!-- Subtype locale display name exceptions.
          For each exception, there should be related string resources for display name that may have
          explicit keyboard layout. The string resource name must be "subtype_<locale>" or
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 120b648..bccab93 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -58,11 +58,6 @@
     <!-- Option summary for showing language switch key [CHAR LIMIT=65] -->
     <string name="show_language_switch_key_summary">Show when multiple input languages are enabled</string>
 
-    <!-- Option to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=30]-->
-    <string name="sliding_key_input_preview">Show slide indicator</string>
-    <!-- Option summary to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=66]-->
-    <string name="sliding_key_input_preview_summary">Display visual cue while sliding from Shift or Symbol keys</string>
-
     <!-- Option for the dismiss delay of the key popup [CHAR LIMIT=25] -->
     <string name="key_preview_popup_dismiss_delay">Key popup dismiss delay</string>
     <!-- Description for delay for dismissing a popup on keypress: no delay [CHAR LIMIT=15] -->
@@ -325,38 +320,10 @@
     <!-- Toast text to describe the same input style already exists [CHAR LIMIT=64]-->
     <string name="custom_input_style_already_exists">"The same input style already exists: <xliff:g id="INPUT_STYLE_NAME" example="English (Dvorak)">%s</xliff:g>"</string>
 
-    <!-- Title of the settings for key long press delay [CHAR LIMIT=35] -->
-    <string name="prefs_key_longpress_timeout_settings">Key long press delay</string>
     <!-- Title of the settings for keypress vibration duration [CHAR LIMIT=35] -->
     <string name="prefs_keypress_vibration_duration_settings">Keypress vibration duration</string>
     <!-- Title of the settings for keypress sound volume [CHAR LIMIT=35] -->
     <string name="prefs_keypress_sound_volume_settings">Keypress sound volume</string>
-    <!-- Title of the settings for customize key popup animation parameters [CHAR LIMIT=35] -->
-    <string name="prefs_customize_key_preview_animation">Customize key preview animation</string>
-    <!-- Title of the settings for key popup show up animation duration (in milliseconds) [CHAR LIMIT=35] -->
-    <string name="prefs_key_popup_show_up_duration_settings" translatable="false">Key popup show up duration</string>
-    <!-- Title of the settings for key popup dismiss animation duration (in milliseconds) [CHAR LIMIT=35] -->
-    <string name="prefs_key_popup_dismiss_duration_settings" translatable="false">Key popup dismiss duration</string>
-    <!-- Title of the settings for key popup show up animation start X-scale (in percentile) [CHAR LIMIT=35] -->
-    <string name="prefs_key_popup_show_up_start_x_scale_settings" translatable="false">Key popup show up start X scale</string>
-    <!-- Title of the settings for key popup show up animation start Y-scale (in percentile) [CHAR LIMIT=35] -->
-    <string name="prefs_key_popup_show_up_start_y_scale_settings" translatable="false">Key popup show up start Y scale</string>
-    <!-- Title of the settings for key popup dismiss animation end X-scale (in percentile) [CHAR LIMIT=35] -->
-    <string name="prefs_key_popup_dismiss_end_x_scale_settings" translatable="false">Key popup dismiss end X scale</string>
-    <!-- Title of the settings for key popup dismiss animation end Y-scale (in percentile) [CHAR LIMIT=35] -->
-    <string name="prefs_key_popup_dismiss_end_y_scale_settings" translatable="false">Key popup dismiss end Y scale</string>
-    <!-- Title of the settings for reading an external dictionary file -->
-    <string name="prefs_read_external_dictionary">Read external dictionary file</string>
-    <!-- Message to show when there are no files to install as an external dictionary [CHAR LIMIT=100] -->
-    <string name="read_external_dictionary_no_files_message">No dictionary files in the Downloads folder</string>
-    <!-- Title of the dialog that selects a file to install as an external dictionary [CHAR LIMIT=50] -->
-    <string name="read_external_dictionary_multiple_files_title">Select a dictionary file to install</string>
-    <!-- Title of the confirmation dialog to install a file as an external dictionary [CHAR LIMIT=50] -->
-    <string name="read_external_dictionary_confirm_install_message">Really install this file for <xliff:g id="LANGUAGE_NAME" example="English">%s</xliff:g>?</string>
-    <!-- Title for an error dialog that contains the details of the error in the body [CHAR LIMIT=80] -->
-    <string name="error">There was an error</string>
-    <!-- Title of the settings group for dumpping dictionary files that have been created on the device [CHAR LIMIT=35] -->
-    <string name="prefs_dump_dynamic_dicts" translatable="false">Dump dictionary</string>
 
     <!-- Title of the button to revert to the default value of the device in the settings dialog [CHAR LIMIT=15] -->
     <string name="button_default">Default</string>
diff --git a/java/res/values/themes-common.xml b/java/res/values/themes-common.xml
index 6805830..becaddd 100644
--- a/java/res/values/themes-common.xml
+++ b/java/res/values/themes-common.xml
@@ -115,10 +115,7 @@
          for instance delete button, need themed {@link KeyboardView} attributes. -->
     <style name="EmojiPalettesView" />
     <style name="MoreKeysKeyboard" />
-    <style
-        name="MoreKeysKeyboardView"
-        parent="KeyboardView" />
-    <style name="MoreKeysKeyboardContainer" />
+    <style name="MoreKeysKeyboardView" />
     <style name="SuggestionStripView" />
     <style name="SuggestionWord">
         <item name="android:minWidth">@dimen/config_suggestion_min_width</item>
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
index a9c7294..9e656dd 100644
--- a/java/res/values/themes-ics.xml
+++ b/java/res/values/themes-ics.xml
@@ -25,7 +25,9 @@
         <item name="mainKeyboardViewStyle">@style/MainKeyboardView.ICS</item>
         <item name="emojiPalettesViewStyle">@style/EmojiPalettesView.ICS</item>
         <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.ICS</item>
+        <!-- Note: ICS theme uses the same style for both general more keys and action more keys. -->
         <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.ICS</item>
+        <item name="moreKeysKeyboardViewForActionStyle">@style/MoreKeysKeyboardView.ICS</item>
         <item name="suggestionStripViewStyle">@style/SuggestionStripView.ICS</item>
         <item name="suggestionWordStyle">@style/SuggestionWord.ICS</item>
     </style>
@@ -103,6 +105,7 @@
     >
         <item name="android:background">@drawable/keyboard_popup_panel_background_ics</item>
         <item name="keyBackground">@drawable/btn_keyboard_key_popup_ics</item>
+        <item name="divider">@drawable/more_keys_divider</item>
         <item name="keyTypeface">normal</item>
         <item name="verticalCorrection">@dimen/config_more_keys_keyboard_vertical_correction_holo</item>
     </style>
diff --git a/java/res/values/themes-klp.xml b/java/res/values/themes-klp.xml
index da5e27f..c6319bc 100644
--- a/java/res/values/themes-klp.xml
+++ b/java/res/values/themes-klp.xml
@@ -25,7 +25,9 @@
         <item name="mainKeyboardViewStyle">@style/MainKeyboardView.KLP</item>
         <item name="emojiPalettesViewStyle">@style/EmojiPalettesView.KLP</item>
         <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.KLP</item>
+        <!-- Note: KLP theme uses the same style for both general more keys and action more keys. -->
         <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.KLP</item>
+        <item name="moreKeysKeyboardViewForActionStyle">@style/MoreKeysKeyboardView.KLP</item>
         <item name="suggestionStripViewStyle">@style/SuggestionStripView.KLP</item>
         <item name="suggestionWordStyle">@style/SuggestionWord.KLP</item>
     </style>
@@ -103,6 +105,7 @@
     >
         <item name="android:background">@drawable/keyboard_popup_panel_background_klp</item>
         <item name="keyBackground">@drawable/btn_keyboard_key_popup_klp</item>
+        <item name="divider">@drawable/more_keys_divider</item>
         <item name="keyTypeface">normal</item>
         <item name="verticalCorrection">@dimen/config_more_keys_keyboard_vertical_correction_holo</item>
     </style>
diff --git a/java/res/values/themes-lxx-dark.xml b/java/res/values/themes-lxx-dark.xml
index c49436c..5b26813 100644
--- a/java/res/values/themes-lxx-dark.xml
+++ b/java/res/values/themes-lxx-dark.xml
@@ -26,6 +26,7 @@
         <item name="emojiPalettesViewStyle">@style/EmojiPalettesView.LXX_Dark</item>
         <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.LXX_Dark</item>
         <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.LXX_Dark</item>
+        <item name="moreKeysKeyboardViewForActionStyle">@style/MoreKeysKeyboardView.LXX_Dark.Action</item>
         <item name="suggestionStripViewStyle">@style/SuggestionStripView.LXX_Dark</item>
         <item name="suggestionWordStyle">@style/SuggestionWord.LXX_Dark</item>
     </style>
@@ -57,6 +58,7 @@
         name="MainKeyboardView.LXX_Dark"
         parent="KeyboardView.LXX_Dark"
     >
+        <item name="moreKeysKeyboardForActionLayout">@layout/more_keys_keyboard_for_action_lxx</item>
         <item name="keyPreviewBackground">@drawable/keyboard_key_feedback_lxx_dark</item>
         <item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
         <item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_lxx</item>
@@ -101,10 +103,20 @@
     >
         <item name="android:background">@drawable/keyboard_popup_panel_background_lxx_dark</item>
         <item name="keyBackground">@drawable/btn_keyboard_key_popup_lxx_dark</item>
+        <item name="divider">@drawable/more_keys_divider</item>
         <item name="keyTypeface">normal</item>
         <item name="verticalCorrection">@dimen/config_more_keys_keyboard_vertical_correction_holo</item>
     </style>
     <style
+        name="MoreKeysKeyboardView.LXX_Dark.Action"
+        parent="MoreKeysKeyboardView.LXX_Dark"
+    >
+        <item name="android:background">@android:color/transparent</item>
+        <item name="keyBackground">@drawable/btn_keyboard_key_popup_action_lxx_dark</item>
+        <item name="divider">@null</item>
+        <item name="keyLabelFlags">keepBackgroundAspectRatio</item>
+    </style>
+    <style
         name="SuggestionStripView.LXX_Dark"
         parent="KeyboardView.LXX_Dark"
     >
diff --git a/java/res/values/themes-lxx-light.xml b/java/res/values/themes-lxx-light.xml
index 6f0fb71..f607807 100644
--- a/java/res/values/themes-lxx-light.xml
+++ b/java/res/values/themes-lxx-light.xml
@@ -26,6 +26,7 @@
         <item name="emojiPalettesViewStyle">@style/EmojiPalettesView.LXX_Light</item>
         <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.LXX_Light</item>
         <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.LXX_Light</item>
+        <item name="moreKeysKeyboardViewForActionStyle">@style/MoreKeysKeyboardView.LXX_Light.Action</item>
         <item name="suggestionStripViewStyle">@style/SuggestionStripView.LXX_Light</item>
         <item name="suggestionWordStyle">@style/SuggestionWord.LXX_Light</item>
     </style>
@@ -57,6 +58,7 @@
         name="MainKeyboardView.LXX_Light"
         parent="KeyboardView.LXX_Light"
     >
+        <item name="moreKeysKeyboardForActionLayout">@layout/more_keys_keyboard_for_action_lxx</item>
         <item name="keyPreviewBackground">@drawable/keyboard_key_feedback_lxx_light</item>
         <item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
         <item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_lxx</item>
@@ -101,10 +103,20 @@
     >
         <item name="android:background">@drawable/keyboard_popup_panel_background_lxx_light</item>
         <item name="keyBackground">@drawable/btn_keyboard_key_popup_lxx_light</item>
+        <item name="divider">@drawable/more_keys_divider</item>
         <item name="keyTypeface">normal</item>
         <item name="verticalCorrection">@dimen/config_more_keys_keyboard_vertical_correction_holo</item>
     </style>
     <style
+        name="MoreKeysKeyboardView.LXX_Light.Action"
+        parent="MoreKeysKeyboardView.LXX_Light"
+    >
+        <item name="android:background">@android:color/transparent</item>
+        <item name="keyBackground">@drawable/btn_keyboard_key_popup_action_lxx_light</item>
+        <item name="divider">@null</item>
+        <item name="keyLabelFlags">keepBackgroundAspectRatio</item>
+    </style>
+    <style
         name="SuggestionStripView.LXX_Light"
         parent="KeyboardView.LXX_Light"
     >
diff --git a/java/res/xml-sw600dp/key_styles_enter.xml b/java/res/xml-sw600dp/key_styles_enter.xml
index 0227d81..63ef2f8 100644
--- a/java/res/xml-sw600dp/key_styles_enter.xml
+++ b/java/res/xml-sw600dp/key_styles_enter.xml
@@ -22,20 +22,18 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
     <!-- Navigate more keys style -->
+    <include latin:keyboardLayout="@xml/key_styles_navigate_more_keys" />
     <switch>
-        <!-- latin:passwordInput="true" -->
         <case
             latin:imeAction="actionNext"
             latin:navigatePrevious="true"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_previous" />
+                latin:parentStyle="navigatePreviousMoreKeysStyle" />
         </case>
         <case
             latin:imeAction="actionNext"
-            latin:navigatePrevious="false"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle" />
@@ -46,12 +44,10 @@
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_next" />
+                latin:parentStyle="navigateNextMoreKeysStyle" />
         </case>
         <case
             latin:imeAction="actionPrevious"
-            latin:navigateNext="false"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle" />
@@ -62,33 +58,21 @@
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_action_previous,!text/keyspec_action_next" />
+                latin:parentStyle="navigatePreviousNextMoreKeysStyle" />
         </case>
         <case
             latin:navigateNext="true"
-            latin:navigatePrevious="false"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_next" />
+                latin:parentStyle="navigateNextMoreKeysStyle" />
         </case>
         <case
-            latin:navigateNext="false"
             latin:navigatePrevious="true"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_previous" />
-        </case>
-        <case
-            latin:navigateNext="false"
-            latin:navigatePrevious="false"
-        >
-            <key-style
-                latin:styleName="navigateMoreKeysStyle" />
+                latin:parentStyle="navigatePreviousMoreKeysStyle" />
         </case>
         <default>
             <key-style
@@ -96,13 +80,28 @@
         </default>
     </switch>
     <!-- Enter key style -->
-    <key-style
-        latin:styleName="defaultEnterKeyStyle"
-        latin:keySpec="!icon/enter_key|!code/key_enter"
-        latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor"
-        latin:keyActionFlags="noKeyPreview"
-        latin:backgroundType="action"
-        latin:parentStyle="navigateMoreKeysStyle" />
+    <switch>
+        <case latin:keyboardTheme="ICS|KLP">
+            <key-style
+                latin:styleName="defaultEnterKeyStyle"
+                latin:keySpec="!icon/enter_key|!code/key_enter"
+                latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor"
+                latin:keyActionFlags="noKeyPreview"
+                latin:backgroundType="action"
+                latin:parentStyle="navigateMoreKeysStyle" />
+        </case>
+        <!-- keyboardTheme="LXXLight|LXXDark" -->
+        <default>
+            <key-style
+                latin:styleName="defaultEnterKeyStyle"
+                latin:keySpec="!icon/enter_key|!code/key_enter"
+                latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor|keepBackgroundAspectRatio"
+                latin:keyActionFlags="noKeyPreview"
+                latin:backgroundType="action"
+                latin:parentStyle="navigateMoreKeysStyle" />
+        </default>
+    </switch>
+    <include latin:keyboardLayout="@xml/key_styles_actions" />
     <switch>
         <!-- Shift + Enter in textMultiLine field. -->
         <case
@@ -116,133 +115,52 @@
         </case>
         <case
             latin:imeAction="actionGo"
-            latin:isIconDefined="go_key"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/go_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionGo"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_go_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionNext"
-            latin:isIconDefined="next_key"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/next_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="goActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionNext"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_next_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionPrevious"
-            latin:isIconDefined="previous_key"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/previous_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="nextActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionPrevious"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_previous_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionDone"
-            latin:isIconDefined="done_key"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/done_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="previousActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionDone"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_done_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionSend"
-            latin:isIconDefined="send_key"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/send_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="doneActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionSend"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_send_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionSearch"
-            latin:isIconDefined="search_key"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/search_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="sendActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionSearch"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_search_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="searchActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionCustomLabel"
-            latin:keyboardTheme="ICS|KLP"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="dummy_label|!code/key_enter"
-                latin:keyLabelFlags="fromCustomActionLabel"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionCustomLabel"
-            latin:keyboardTheme="LXXLight|LXXDark"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="dummy_label|!code/key_enter"
-                latin:keyLabelFlags="fromCustomActionLabel"
-                latin:backgroundType="functional"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="customLabelActionKeyStyle" />
         </case>
         <!-- imeAction is either actionNone or actionUnspecified. -->
         <default>
diff --git a/java/res/xml/key_styles_actions.xml b/java/res/xml/key_styles_actions.xml
new file mode 100644
index 0000000..83901ca
--- /dev/null
+++ b/java/res/xml/key_styles_actions.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <!-- Go key -->
+    <switch>
+        <case latin:isIconDefined="go_key">
+            <key-style
+                latin:styleName="goActionKeyStyle"
+                latin:keySpec="!icon/go_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="goActionKeyStyle"
+                latin:keySpec="!text/label_go_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </default>
+    </switch>
+    <!-- Next key -->
+    <switch>
+        <case latin:isIconDefined="next_key">
+            <key-style
+                latin:styleName="nextActionKeyStyle"
+                latin:keySpec="!icon/next_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="nextActionKeyStyle"
+                latin:keySpec="!text/label_next_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </default>
+    </switch>
+    <!-- Previous key -->
+    <switch>
+        <case latin:isIconDefined="previous_key">
+            <key-style
+                latin:styleName="previousActionKeyStyle"
+                latin:keySpec="!icon/previous_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="previousActionKeyStyle"
+                latin:keySpec="!text/label_previous_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </default>
+    </switch>
+    <!-- Done key -->
+    <switch>
+        <case latin:isIconDefined="done_key">
+            <key-style
+                latin:styleName="doneActionKeyStyle"
+                latin:keySpec="!icon/done_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="doneActionKeyStyle"
+                latin:keySpec="!text/label_done_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </default>
+    </switch>
+    <!-- Send key -->
+    <switch>
+        <case latin:isIconDefined="send_key">
+            <key-style
+                latin:styleName="sendActionKeyStyle"
+                latin:keySpec="!icon/send_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="sendActionKeyStyle"
+                latin:keySpec="!text/label_send_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </default>
+    </switch>
+    <!-- Seartch key -->
+    <switch>
+        <case latin:isIconDefined="search_key">
+            <key-style
+                latin:styleName="searchActionKeyStyle"
+                latin:keySpec="!icon/search_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="searchActionKeyStyle"
+                latin:keySpec="!text/label_search_key|!code/key_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </default>
+    </switch>
+    <switch>
+        <case latin:keyboardTheme="ICS|KLP">
+            <key-style
+                latin:styleName="customLabelActionKeyStyle"
+                latin:keySpec="dummy_label|!code/key_enter"
+                latin:keyLabelFlags="fromCustomActionLabel"
+                latin:backgroundType="action"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </case>
+        <!-- keyboardTheme="LXXLight|LXXDark" -->
+        <default>
+            <key-style
+                latin:styleName="customLabelActionKeyStyle"
+                latin:keySpec="dummy_label|!code/key_enter"
+                latin:keyLabelFlags="fromCustomActionLabel"
+                latin:backgroundType="functional"
+                latin:parentStyle="defaultEnterKeyStyle" />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index 43ee26b..b36ddf2 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -80,11 +80,24 @@
         latin:keyActionFlags="isRepeatable|noKeyPreview"
         latin:backgroundType="functional" />
     <!-- emojiKeyStyle must be defined before including @xml/key_syles_enter. -->
-    <key-style
-        latin:styleName="emojiKeyStyle"
-        latin:keySpec="!icon/emoji_action_key|!code/key_emoji"
-        latin:keyActionFlags="noKeyPreview"
-        latin:backgroundType="action" />
+    <switch>
+        <case latin:keyboardTheme="ICS|KLP">
+            <key-style
+                latin:styleName="emojiKeyStyle"
+                latin:keySpec="!icon/emoji_action_key|!code/key_emoji"
+                latin:keyActionFlags="noKeyPreview"
+                latin:backgroundType="action" />
+        </case>
+        <!-- keyboardTheme="LXXLight|LXXDark" -->
+        <default>
+            <key-style
+                latin:styleName="emojiKeyStyle"
+                latin:keySpec="!icon/emoji_action_key|!code/key_emoji"
+                latin:keyLabelFlags="keepBackgroundAspectRatio"
+                latin:keyActionFlags="noKeyPreview"
+                latin:backgroundType="action" />
+        </default>
+    </switch>
     <include
         latin:keyboardLayout="@xml/key_styles_enter" />
     <!-- TODO: Currently there is no way to specify icon alignment per theme. -->
diff --git a/java/res/xml/key_styles_enter.xml b/java/res/xml/key_styles_enter.xml
index 7aea1ce..564f465 100644
--- a/java/res/xml/key_styles_enter.xml
+++ b/java/res/xml/key_styles_enter.xml
@@ -21,8 +21,8 @@
 <merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
-    <!-- TODO: Stop using many conditional cases for keyspec_emoji_action_key. There are way too many to maintain. -->
     <!-- Navigate more keys style -->
+    <include latin:keyboardLayout="@xml/key_styles_navigate_more_keys" />
     <switch>
         <!-- latin:passwordInput="true" -->
         <case
@@ -32,12 +32,10 @@
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_previous" />
+                latin:parentStyle="navigatePreviousMoreKeysStyle" />
         </case>
         <case
             latin:imeAction="actionNext"
-            latin:navigatePrevious="false"
             latin:passwordInput="true"
         >
             <key-style
@@ -50,12 +48,10 @@
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_next" />
+                latin:parentStyle="navigateNextMoreKeysStyle" />
         </case>
         <case
             latin:imeAction="actionPrevious"
-            latin:navigateNext="false"
             latin:passwordInput="true"
         >
             <key-style
@@ -68,32 +64,25 @@
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_action_previous,!text/keyspec_action_next" />
+                latin:parentStyle="navigatePreviousNextMoreKeysStyle" />
         </case>
         <case
             latin:navigateNext="true"
-            latin:navigatePrevious="false"
             latin:passwordInput="true"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_next" />
+                latin:parentStyle="navigateNextMoreKeysStyle" />
         </case>
         <case
-            latin:navigateNext="false"
             latin:navigatePrevious="true"
             latin:passwordInput="true"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_previous" />
+                latin:parentStyle="navigatePreviousMoreKeysStyle" />
         </case>
         <case
-            latin:navigateNext="false"
-            latin:navigatePrevious="false"
             latin:passwordInput="true"
         >
             <key-style
@@ -107,12 +96,10 @@
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_previous" />
+                latin:parentStyle="navigatePreviousMoreKeysStyle" />
         </case>
         <case
             latin:imeAction="actionNext"
-            latin:navigatePrevious="false"
             latin:mode="email|url|phone|number|date|time|datetime"
         >
             <key-style
@@ -125,12 +112,10 @@
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_next" />
+                latin:parentStyle="navigateNextMoreKeysStyle" />
         </case>
         <case
             latin:imeAction="actionPrevious"
-            latin:navigateNext="false"
             latin:mode="email|url|phone|number|date|time|datetime"
         >
             <key-style
@@ -143,32 +128,25 @@
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_action_previous,!text/keyspec_action_next" />
+                latin:parentStyle="navigatePreviousNextMoreKeysStyle" />
         </case>
         <case
             latin:navigateNext="true"
-            latin:navigatePrevious="false"
             latin:mode="email|url|phone|number|date|time|datetime"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_next" />
+                latin:parentStyle="navigateNextMoreKeysStyle" />
         </case>
         <case
-            latin:navigateNext="false"
             latin:navigatePrevious="true"
             latin:mode="email|url|phone|number|date|time|datetime"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_action_previous" />
+                latin:parentStyle="navigatePreviousMoreKeysStyle" />
         </case>
         <case
-            latin:navigateNext="false"
-            latin:navigatePrevious="false"
             latin:mode="email|url|phone|number|date|time|datetime"
         >
             <key-style
@@ -181,17 +159,14 @@
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_previous" />
+                latin:parentStyle="navigateEmojiPreviousMoreKeysStyle" />
         </case>
         <case
             latin:imeAction="actionNext"
-            latin:navigatePrevious="false"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_emoji_action_key" />
+                latin:parentStyle="navigateEmojiMoreKeysStyle" />
         </case>
         <case
             latin:imeAction="actionPrevious"
@@ -199,17 +174,14 @@
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_next" />
+                latin:parentStyle="navigateEmojiNextMoreKeysStyle" />
         </case>
         <case
             latin:imeAction="actionPrevious"
-            latin:navigateNext="false"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_emoji_action_key" />
+                latin:parentStyle="navigateEmojiMoreKeysStyle" />
         </case>
         <case
             latin:navigateNext="true"
@@ -217,53 +189,51 @@
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!fixedColumnOrder!3,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_previous,!text/keyspec_action_next" />
+                latin:parentStyle="navigateEmojiPreviousNextMoreKeysStyle" />
         </case>
         <case
             latin:navigateNext="true"
-            latin:navigatePrevious="false"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_next" />
+                latin:parentStyle="navigateEmojiNextMoreKeysStyle" />
         </case>
         <case
-            latin:navigateNext="false"
             latin:navigatePrevious="true"
         >
             <key-style
                 latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_previous" />
-        </case>
-        <case
-            latin:navigateNext="false"
-            latin:navigatePrevious="false"
-        >
-            <key-style
-                latin:styleName="navigateMoreKeysStyle"
-                latin:keyLabelFlags="hasPopupHint|preserveCase"
-                latin:moreKeys="!text/keyspec_emoji_action_key" />
+                latin:parentStyle="navigateEmojiPreviousMoreKeysStyle" />
         </case>
         <default>
             <key-style
-                latin:styleName="navigateMoreKeysStyle" />
+                latin:styleName="navigateMoreKeysStyle"
+                latin:parentStyle="navigateEmojiMoreKeysStyle" />
         </default>
     </switch>
     <!-- Enter key style -->
-    <key-style
-        latin:styleName="defaultEnterKeyStyle"
-        latin:keySpec="!icon/enter_key|!code/key_enter"
-        latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor"
-        latin:keyActionFlags="noKeyPreview"
-        latin:backgroundType="action"
-        latin:parentStyle="navigateMoreKeysStyle" />
-    <key-style
-        latin:styleName="shiftEnterKeyStyle"
-        latin:keySpec="!icon/enter_key|!code/key_shift_enter"
-        latin:parentStyle="defaultEnterKeyStyle" />
+    <switch>
+        <case latin:keyboardTheme="ICS|KLP">
+            <key-style
+                latin:styleName="defaultEnterKeyStyle"
+                latin:keySpec="!icon/enter_key|!code/key_enter"
+                latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor"
+                latin:keyActionFlags="noKeyPreview"
+                latin:backgroundType="action"
+                latin:parentStyle="navigateMoreKeysStyle" />
+        </case>
+        <!-- keyboardTheme="LXXLight|LXXDark" -->
+        <default>
+            <key-style
+                latin:styleName="defaultEnterKeyStyle"
+                latin:keySpec="!icon/enter_key|!code/key_enter"
+                latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor|keepBackgroundAspectRatio"
+                latin:keyActionFlags="noKeyPreview"
+                latin:backgroundType="action"
+                latin:parentStyle="navigateMoreKeysStyle" />
+        </default>
+    </switch>
+    <include latin:keyboardLayout="@xml/key_styles_actions" />
     <switch>
         <!-- Shift + Enter in textMultiLine field. -->
         <case
@@ -272,7 +242,8 @@
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:parentStyle="shiftEnterKeyStyle" />
+                latin:keySpec="!icon/enter_key|!code/key_shift_enter"
+                latin:parentStyle="defaultEnterKeyStyle" />
         </case>
         <!-- Smiley in textShortMessage field.
              This <case> should be after Shift + Enter <case> and before any of action <case>. -->
@@ -285,139 +256,57 @@
         </case>
         <case
             latin:imeAction="actionGo"
-            latin:isIconDefined="go_key"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/go_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionGo"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_go_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionNext"
-            latin:isIconDefined="next_key"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/next_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="goActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionNext"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_next_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionPrevious"
-            latin:isIconDefined="previous_key"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/previous_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="nextActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionPrevious"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_previous_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionDone"
-            latin:isIconDefined="done_key"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/done_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="previousActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionDone"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_done_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionSend"
-            latin:isIconDefined="send_key"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/send_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="doneActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionSend"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_send_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionSearch"
-            latin:isIconDefined="search_key"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/search_key|!code/key_enter"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="sendActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionSearch"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_search_key|!code/key_enter"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="searchActionKeyStyle" />
         </case>
         <case
             latin:imeAction="actionCustomLabel"
-            latin:keyboardTheme="ICS|KLP"
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="dummy_label|!code/key_enter"
-                latin:keyLabelFlags="fromCustomActionLabel"
-                latin:backgroundType="action"
-                latin:parentStyle="defaultEnterKeyStyle" />
-        </case>
-        <case
-            latin:imeAction="actionCustomLabel"
-            latin:keyboardTheme="LXXLight|LXXDark"
-        >
-            <key-style
-                latin:styleName="enterKeyStyle"
-                latin:keySpec="dummy_label|!code/key_enter"
-                latin:keyLabelFlags="fromCustomActionLabel"
-                latin:backgroundType="functional"
-                latin:parentStyle="defaultEnterKeyStyle" />
+                latin:parentStyle="customLabelActionKeyStyle" />
         </case>
         <!-- imeAction is either actionNone or actionUnspecified. -->
         <default>
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!icon/enter_key|!code/key_enter"
                 latin:parentStyle="defaultEnterKeyStyle" />
         </default>
     </switch>
diff --git a/java/res/xml/key_styles_navigate_more_keys.xml b/java/res/xml/key_styles_navigate_more_keys.xml
new file mode 100644
index 0000000..f97114d
--- /dev/null
+++ b/java/res/xml/key_styles_navigate_more_keys.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case latin:keyboardTheme="ICS|KLP">
+            <key-style
+                latin:styleName="navigateNextMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!text/keyspec_action_next" />
+            <key-style
+                latin:styleName="navigatePreviousMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!text/keyspec_action_previous" />
+            <key-style
+                latin:styleName="navigatePreviousNextMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_action_previous,!text/keyspec_action_next" />
+            <key-style
+                latin:styleName="navigateEmojiMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!text/keyspec_emoji_action_key" />
+            <key-style
+                latin:styleName="navigateEmojiNextMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_next" />
+            <key-style
+                latin:styleName="navigateEmojiPreviousMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_previous" />
+            <key-style
+                latin:styleName="navigateEmojiPreviousNextMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!fixedColumnOrder!3,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_previous,!text/keyspec_action_next" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="navigateNextMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!icon/next_key|!code/key_action_next" />
+            <key-style
+                latin:styleName="navigatePreviousMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!icon/previous_key|!code/key_action_previous" />
+            <key-style
+                latin:styleName="navigatePreviousNextMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!icon/previous_key|!code/key_action_previous,!icon/next_key|!code/key_action_next" />
+            <key-style
+                latin:styleName="navigateEmojiMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!text/keyspec_emoji_action_key" />
+            <key-style
+                latin:styleName="navigateEmojiNextMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!icon/next_key|!code/key_action_next" />
+            <key-style
+                latin:styleName="navigateEmojiPreviousMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!icon/previous_key|!code/key_action_previous" />
+            <key-style
+                latin:styleName="navigateEmojiPreviousNextMoreKeysStyle"
+                latin:keyLabelFlags="hasPopupHint|preserveCase"
+                latin:moreKeys="!fixedColumnOrder!3,!needsDividers!,!text/keyspec_emoji_action_key,!icon/previous_key|!code/key_action_previous,!icon/next_key|!code/key_action_next" />
+        </default>
+    </switch>
+</merge>
diff --git a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
index 3a86ccb..8a28185 100644
--- a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
+++ b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
@@ -34,10 +34,15 @@
      */
     public static final int FLAG_HAS_INVISIBLE_REGION = 0x02;
 
+    /**
+     * The insertion marker or character bounds is placed at right-to-left (RTL) character.
+     */
+    public static final int FLAG_IS_RTL = 0x04;
+
     // Note that CursorAnchorInfo has been introduced in API level XX (Build.VERSION_CODE.LXX).
     private static final CompatUtils.ClassWrapper sCursorAnchorInfoClass;
-    private static final CompatUtils.ToObjectMethodWrapper<RectF> sGetCharacterRectMethod;
-    private static final CompatUtils.ToIntMethodWrapper sGetCharacterRectFlagsMethod;
+    private static final CompatUtils.ToObjectMethodWrapper<RectF> sGetCharacterBoundsMethod;
+    private static final CompatUtils.ToIntMethodWrapper sGetCharacterBoundsFlagsMethod;
     private static final CompatUtils.ToObjectMethodWrapper<CharSequence> sGetComposingTextMethod;
     private static final CompatUtils.ToIntMethodWrapper sGetComposingTextStartMethod;
     private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerBaselineMethod;
@@ -51,10 +56,10 @@
     static {
         sCursorAnchorInfoClass = CompatUtils.getClassWrapper(
                 "android.view.inputmethod.CursorAnchorInfo");
-        sGetCharacterRectMethod = sCursorAnchorInfoClass.getMethod(
-                "getCharacterRect", (RectF)null, int.class);
-        sGetCharacterRectFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
-                "getCharacterRectFlags", 0, int.class);
+        sGetCharacterBoundsMethod = sCursorAnchorInfoClass.getMethod(
+                "getCharacterBounds", (RectF)null, int.class);
+        sGetCharacterBoundsFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
+                "getCharacterBoundsFlags", 0, int.class);
         sGetComposingTextMethod = sCursorAnchorInfoClass.getMethod(
                 "getComposingText", (CharSequence)null);
         sGetComposingTextStartMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
@@ -112,12 +117,12 @@
         return sGetMatrixMethod.invoke(mInstance);
     }
 
-    public RectF getCharacterRect(final int index) {
-        return sGetCharacterRectMethod.invoke(mInstance, index);
+    public RectF getCharacterBounds(final int index) {
+        return sGetCharacterBoundsMethod.invoke(mInstance, index);
     }
 
-    public int getCharacterRectFlags(final int index) {
-        return sGetCharacterRectFlagsMethod.invoke(mInstance, index);
+    public int getCharacterBoundsFlags(final int index) {
+        return sGetCharacterBoundsFlagsMethod.invoke(mInstance, index);
     }
 
     public float getInsertionMarkerBaseline() {
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index f7e4d8b..86ea4c5 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -87,6 +87,7 @@
     private static final int LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED = 0x20000;
     private static final int LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL = 0x40000;
     private static final int LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR = 0x80000;
+    private static final int LABEL_FLAGS_KEEP_BACKGROUND_ASPECT_RATIO = 0x100000;
     private static final int LABEL_FLAGS_DISABLE_HINT_LABEL = 0x40000000;
     private static final int LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS = 0x80000000;
 
@@ -547,6 +548,10 @@
         return this instanceof Spacer;
     }
 
+    public final boolean isActionKey() {
+        return mBackgroundType == BACKGROUND_TYPE_ACTION;
+    }
+
     public final boolean isShift() {
         return mCode == CODE_SHIFT;
     }
@@ -693,6 +698,10 @@
         return (mLabelFlags & LABEL_FLAGS_AUTO_SCALE) == LABEL_FLAGS_AUTO_SCALE;
     }
 
+    public final boolean needsToKeepBackgroundAspectRatio(final int defaultFlags) {
+        return ((mLabelFlags | defaultFlags) & LABEL_FLAGS_KEEP_BACKGROUND_ASPECT_RATIO) != 0;
+    }
+
     private final boolean isShiftedLetterActivated() {
         return (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) != 0
                 && !TextUtils.isEmpty(mHintLabel);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index ec089f7..e487516 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -38,6 +38,7 @@
 import com.android.inputmethod.latin.RichInputMethodManager;
 import com.android.inputmethod.latin.SubtypeSwitcher;
 import com.android.inputmethod.latin.WordComposer;
+import com.android.inputmethod.latin.settings.Settings;
 import com.android.inputmethod.latin.settings.SettingsValues;
 import com.android.inputmethod.latin.utils.ResourceUtils;
 import com.android.inputmethod.latin.utils.ScriptUtils;
@@ -60,7 +61,6 @@
     private KeyboardLayoutSet mKeyboardLayoutSet;
     // TODO: The following {@link KeyboardTextsSet} should be in {@link KeyboardLayoutSet}.
     private final KeyboardTextsSet mKeyboardTextsSet = new KeyboardTextsSet();
-    private SettingsValues mCurrentSettingsValues;
 
     private KeyboardTheme mKeyboardTheme;
     private Context mThemeContext;
@@ -120,7 +120,6 @@
         builder.setVoiceInputKeyEnabled(settingsValues.mShowsVoiceInputKey);
         builder.setLanguageSwitchKeyEnabled(mLatinIME.shouldShowLanguageSwitchKey());
         mKeyboardLayoutSet = builder.build();
-        mCurrentSettingsValues = settingsValues;
         try {
             mState.onLoadKeyboard(currentAutoCapsState, currentRecapitalizeState);
             mKeyboardTextsSet.setLocale(mSubtypeSwitcher.getCurrentSubtypeLocale(), mThemeContext);
@@ -144,22 +143,24 @@
 
     private void setKeyboard(final Keyboard keyboard) {
         // Make {@link MainKeyboardView} visible and hide {@link EmojiPalettesView}.
-        setMainKeyboardFrame();
+        final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent();
+        setMainKeyboardFrame(currentSettingsValues);
+        // TODO: pass this object to setKeyboard instead of getting the current values.
         final MainKeyboardView keyboardView = mKeyboardView;
         final Keyboard oldKeyboard = keyboardView.getKeyboard();
         keyboardView.setKeyboard(keyboard);
         mCurrentInputView.setKeyboardTopPadding(keyboard.mTopPadding);
         keyboardView.setKeyPreviewPopupEnabled(
-                mCurrentSettingsValues.mKeyPreviewPopupOn,
-                mCurrentSettingsValues.mKeyPreviewPopupDismissDelay);
+                currentSettingsValues.mKeyPreviewPopupOn,
+                currentSettingsValues.mKeyPreviewPopupDismissDelay);
         keyboardView.setKeyPreviewAnimationParams(
-                mCurrentSettingsValues.mHasCustomKeyPreviewAnimationParams,
-                mCurrentSettingsValues.mKeyPreviewShowUpStartXScale,
-                mCurrentSettingsValues.mKeyPreviewShowUpStartYScale,
-                mCurrentSettingsValues.mKeyPreviewShowUpDuration,
-                mCurrentSettingsValues.mKeyPreviewDismissEndXScale,
-                mCurrentSettingsValues.mKeyPreviewDismissEndYScale,
-                mCurrentSettingsValues.mKeyPreviewDismissDuration);
+                currentSettingsValues.mHasCustomKeyPreviewAnimationParams,
+                currentSettingsValues.mKeyPreviewShowUpStartXScale,
+                currentSettingsValues.mKeyPreviewShowUpStartYScale,
+                currentSettingsValues.mKeyPreviewShowUpDuration,
+                currentSettingsValues.mKeyPreviewDismissEndXScale,
+                currentSettingsValues.mKeyPreviewDismissEndYScale,
+                currentSettingsValues.mKeyPreviewDismissDuration);
         keyboardView.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady());
         final boolean subtypeChanged = (oldKeyboard == null)
                 || !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
@@ -236,22 +237,13 @@
         setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS));
     }
 
-    private void setMainKeyboardFrame() {
-        mMainKeyboardFrame.setVisibility(hasHardwareKeyboard() ? View.GONE : View.VISIBLE);
+    private void setMainKeyboardFrame(final SettingsValues settingsValues) {
+        mMainKeyboardFrame.setVisibility(
+                settingsValues.mHasHardwareKeyboard ? View.GONE : View.VISIBLE);
         mEmojiPalettesView.setVisibility(View.GONE);
         mEmojiPalettesView.stopEmojiPalettes();
     }
 
-    // TODO: Move this boolean to a member of {@link SettingsValues} and reset it
-    // at {@link LatinIME#onConfigurationChanged(Configuration)}.
-    public boolean hasHardwareKeyboard() {
-        // Copied from {@link InputMethodServce#onEvaluateInputViewShown()}.
-        final Configuration config = mLatinIME.getResources().getConfiguration();
-        final boolean noHardwareKeyboard = config.keyboard == Configuration.KEYBOARD_NOKEYS
-                || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES;
-        return !noHardwareKeyboard;
-    }
-
     // Implements {@link KeyboardState.SwitchActions}.
     @Override
     public void setEmojiKeyboard() {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 075cd90..bb3cbb0 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -340,11 +340,25 @@
     // Draw key background.
     protected void onDrawKeyBackground(final Key key, final Canvas canvas,
             final Drawable background) {
-        final Rect padding = mKeyBackgroundPadding;
-        final int bgWidth = key.getDrawWidth() + padding.left + padding.right;
-        final int bgHeight = key.getHeight() + padding.top + padding.bottom;
-        final int bgX = -padding.left;
-        final int bgY = -padding.top;
+        final int keyWidth = key.getDrawWidth();
+        final int keyHeight = key.getHeight();
+        final int bgWidth, bgHeight, bgX, bgY;
+        if (key.needsToKeepBackgroundAspectRatio(mDefaultKeyLabelFlags)) {
+            final int intrinsicWidth = background.getIntrinsicWidth();
+            final int intrinsicHeight = background.getIntrinsicHeight();
+            final float minScale = Math.min(
+                    keyWidth / (float)intrinsicWidth, keyHeight / (float)intrinsicHeight);
+            bgWidth = (int)(intrinsicWidth * minScale);
+            bgHeight = (int)(intrinsicHeight * minScale);
+            bgX = (keyWidth - bgWidth) / 2;
+            bgY = (keyHeight - bgHeight) / 2;
+        } else {
+            final Rect padding = mKeyBackgroundPadding;
+            bgWidth = keyWidth + padding.left + padding.right;
+            bgHeight = keyHeight + padding.top + padding.bottom;
+            bgX = -padding.left;
+            bgY = -padding.top;
+        }
         final Rect bounds = background.getBounds();
         if (bgWidth != bounds.right || bgHeight != bounds.bottom) {
             background.setBounds(0, 0, bgWidth, bgHeight);
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index c73f084..6d0b2c2 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -89,6 +89,7 @@
  * @attr ref R.styleable#MainKeyboardView_keyPreviewShowUpAnimator
  * @attr ref R.styleable#MainKeyboardView_keyPreviewDismissAnimator
  * @attr ref R.styleable#MainKeyboardView_moreKeysKeyboardLayout
+ * @attr ref R.styleable#MainKeyboardView_moreKeysKeyboardForActionLayout
  * @attr ref R.styleable#MainKeyboardView_backgroundDimAlpha
  * @attr ref R.styleable#MainKeyboardView_showMoreKeysKeyboardAtTouchPoint
  * @attr ref R.styleable#MainKeyboardView_gestureFloatingPreviewTextLingerTimeout
@@ -148,6 +149,7 @@
     private final Paint mBackgroundDimAlphaPaint = new Paint();
     private boolean mNeedsToDimEntireKeyboard;
     private final View mMoreKeysKeyboardContainer;
+    private final View mMoreKeysKeyboardForActionContainer;
     private final WeakHashMap<Key, Keyboard> mMoreKeysKeyboardCache = new WeakHashMap<>();
     private final boolean mConfigShowMoreKeysKeyboardAtTouchedPoint;
     // More keys panel (used by both more keys keyboard and more suggestions view)
@@ -232,6 +234,9 @@
 
         final int moreKeysKeyboardLayoutId = mainKeyboardViewAttr.getResourceId(
                 R.styleable.MainKeyboardView_moreKeysKeyboardLayout, 0);
+        final int moreKeysKeyboardForActionLayoutId = mainKeyboardViewAttr.getResourceId(
+                R.styleable.MainKeyboardView_moreKeysKeyboardForActionLayout,
+                moreKeysKeyboardLayoutId);
         mConfigShowMoreKeysKeyboardAtTouchedPoint = mainKeyboardViewAttr.getBoolean(
                 R.styleable.MainKeyboardView_showMoreKeysKeyboardAtTouchedPoint, false);
 
@@ -249,8 +254,10 @@
         mSlidingKeyInputDrawingPreview.setDrawingView(mDrawingPreviewPlacerView);
         mainKeyboardViewAttr.recycle();
 
-        mMoreKeysKeyboardContainer = LayoutInflater.from(getContext())
-                .inflate(moreKeysKeyboardLayoutId, null);
+        final LayoutInflater inflater = LayoutInflater.from(getContext());
+        mMoreKeysKeyboardContainer = inflater.inflate(moreKeysKeyboardLayoutId, null);
+        mMoreKeysKeyboardForActionContainer = inflater.inflate(
+                moreKeysKeyboardForActionLayoutId, null);
         mLanguageOnSpacebarFadeoutAnimator = loadObjectAnimator(
                 languageOnSpacebarFadeoutAnimatorResId, this);
         mAltCodeKeyWhileTypingFadeoutAnimator = loadObjectAnimator(
@@ -582,7 +589,8 @@
             mMoreKeysKeyboardCache.put(key, moreKeysKeyboard);
         }
 
-        final View container = mMoreKeysKeyboardContainer;
+        final View container = key.isActionKey() ? mMoreKeysKeyboardForActionContainer
+                : mMoreKeysKeyboardContainer;
         final MoreKeysKeyboardView moreKeysKeyboardView =
                 (MoreKeysKeyboardView)container.findViewById(R.id.more_keys_keyboard_view);
         moreKeysKeyboardView.setKeyboard(moreKeysKeyboard);
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index 52e2e85..abcfff8 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -18,11 +18,9 @@
 
 import android.content.Context;
 import android.graphics.Paint;
-import android.graphics.drawable.Drawable;
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
-import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
 import com.android.inputmethod.keyboard.internal.KeyboardParams;
 import com.android.inputmethod.keyboard.internal.MoreKeySpec;
 import com.android.inputmethod.latin.R;
@@ -257,7 +255,6 @@
 
     public static class Builder extends KeyboardBuilder<MoreKeysKeyboardParams> {
         private final Key mParentKey;
-        private final Drawable mDivider;
 
         private static final float LABEL_PADDING_RATIO = 0.2f;
         private static final float DIVIDER_RATIO = 0.2f;
@@ -306,15 +303,13 @@
             }
             final int dividerWidth;
             if (key.needsDividersInMoreKeys()) {
-                mDivider = mResources.getDrawable(R.drawable.more_keys_divider);
                 dividerWidth = (int)(keyWidth * DIVIDER_RATIO);
             } else {
-                mDivider = null;
                 dividerWidth = 0;
             }
             final MoreKeySpec[] moreKeys = key.getMoreKeys();
-            mParams.setParameters(moreKeys.length, key.getMoreKeysColumnNumber(), keyWidth, rowHeight,
-                    key.getX() + key.getWidth() / 2, keyboard.mId.mWidth,
+            mParams.setParameters(moreKeys.length, key.getMoreKeysColumnNumber(), keyWidth,
+                    rowHeight, key.getX() + key.getWidth() / 2, keyboard.mId.mWidth,
                     key.isMoreKeysFixedColumn(), key.isMoreKeysFixedOrder(), dividerWidth);
         }
 
@@ -352,7 +347,8 @@
                 if (params.mDividerWidth > 0 && pos != 0) {
                     final int dividerX = (pos > 0) ? x - params.mDividerWidth
                             : x + params.mDefaultKeyWidth;
-                    final Key divider = new MoreKeyDivider(params, mDivider, dividerX, y);
+                    final Key divider = new MoreKeyDivider(
+                            params, dividerX, y, params.mDividerWidth, params.mDefaultRowHeight);
                     params.onAddKey(divider);
                 }
             }
@@ -360,22 +356,11 @@
         }
     }
 
-    private static class MoreKeyDivider extends Key.Spacer {
-        private final Drawable mIcon;
-
-        public MoreKeyDivider(final MoreKeysKeyboardParams params, final Drawable icon,
-                final int x, final int y) {
-            super(params, x, y, params.mDividerWidth, params.mDefaultRowHeight);
-            mIcon = icon;
-        }
-
-        @Override
-        public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) {
-            // KeyboardIconsSet and alpha are unused. Use the icon that has been passed to the
-            // constructor.
-            // TODO: Drawable itself should have an alpha value.
-            mIcon.setAlpha(128);
-            return mIcon;
+    // Used as a divider maker. A divider is drawn by {@link MoreKeysKeyboardView}.
+    public static class MoreKeyDivider extends Key.Spacer {
+        public MoreKeyDivider(final KeyboardParams params, final int x, final int y,
+                final int width, final int height) {
+            super(params, x, y, width, height);
         }
     }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index 5140c4f..a9d1239 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -17,6 +17,10 @@
 package com.android.inputmethod.keyboard;
 
 import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
@@ -24,6 +28,7 @@
 
 import com.android.inputmethod.accessibility.AccessibilityUtils;
 import com.android.inputmethod.accessibility.MoreKeysKeyboardAccessibilityDelegate;
+import com.android.inputmethod.keyboard.internal.KeyDrawParams;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.utils.CoordinateUtils;
@@ -35,6 +40,7 @@
 public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel {
     private final int[] mCoordinates = CoordinateUtils.newInstance();
 
+    private final Drawable mDivider;
     protected final KeyDetector mKeyDetector;
     private Controller mController = EMPTY_CONTROLLER;
     protected KeyboardActionListener mListener;
@@ -53,6 +59,14 @@
     public MoreKeysKeyboardView(final Context context, final AttributeSet attrs,
             final int defStyle) {
         super(context, attrs, defStyle);
+        final TypedArray moreKeysKeyboardViewAttr = context.obtainStyledAttributes(attrs,
+                R.styleable.MoreKeysKeyboardView, defStyle, R.style.MoreKeysKeyboardView);
+        mDivider = moreKeysKeyboardViewAttr.getDrawable(R.styleable.MoreKeysKeyboardView_divider);
+        if (mDivider != null) {
+            // TODO: Drawable itself should have an alpha value.
+            mDivider.setAlpha(128);
+        }
+        moreKeysKeyboardViewAttr.recycle();
         mKeyDetector = new MoreKeysDetector(getResources().getDimension(
                 R.dimen.config_more_keys_keyboard_slide_allowance));
     }
@@ -70,6 +84,23 @@
     }
 
     @Override
+    protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint,
+            final KeyDrawParams params) {
+        if (!key.isSpacer() || !(key instanceof MoreKeysKeyboard.MoreKeyDivider)
+                || mDivider == null) {
+            super.onDrawKeyTopVisuals(key, canvas, paint, params);
+            return;
+        }
+        final int keyWidth = key.getDrawWidth();
+        final int keyHeight = key.getHeight();
+        final int iconWidth = Math.min(mDivider.getIntrinsicWidth(), keyWidth);
+        final int iconHeight = mDivider.getIntrinsicHeight();
+        final int iconX = (keyWidth - iconWidth) / 2; // Align horizontally center
+        final int iconY = (keyHeight - iconHeight) / 2; // Align vertically center
+        drawIcon(canvas, mDivider, iconX, iconY, iconWidth, iconHeight);
+    }
+
+    @Override
     public void setKeyboard(final Keyboard keyboard) {
         super.setKeyboard(keyboard);
         mKeyDetector.setKeyboard(
diff --git a/java/src/com/android/inputmethod/keyboard/TextDecorator.java b/java/src/com/android/inputmethod/keyboard/TextDecorator.java
index 9192853..f614b22 100644
--- a/java/src/com/android/inputmethod/keyboard/TextDecorator.java
+++ b/java/src/com/android/inputmethod/keyboard/TextDecorator.java
@@ -24,7 +24,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
-import android.view.inputmethod.CursorAnchorInfo;
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper;
@@ -154,13 +153,11 @@
      * {@code false} is the input method is finishing the full screen mode.
      */
     public void notifyFullScreenMode(final boolean fullScreenMode) {
-        final boolean currentFullScreenMode = mIsFullScreenMode;
-        if (!currentFullScreenMode && fullScreenMode) {
-            // Currently full screen mode is not supported.
-            // TODO: Support full screen mode.
-            mUiOperator.hideUi();
-        }
+        final boolean fullScreenModeChanged = (mIsFullScreenMode != fullScreenMode);
         mIsFullScreenMode = fullScreenMode;
+        if (fullScreenModeChanged) {
+            layoutLater();
+        }
     }
 
     /**
@@ -183,11 +180,6 @@
      * @param info the compatibility wrapper object for the received {@link CursorAnchorInfo}.
      */
     public void onUpdateCursorAnchorInfo(final CursorAnchorInfoCompatWrapper info) {
-        if (mIsFullScreenMode) {
-            // TODO: Consider to call InputConnection#requestCursorAnchorInfo to disable the
-            // event callback to suppress unnecessary event callbacks.
-            return;
-        }
         mCursorAnchorInfoWrapper = info;
         // Do not use layoutLater() to minimize the latency.
         layoutImmediately();
@@ -240,11 +232,6 @@
     }
 
     private void layoutMain() {
-        if (mIsFullScreenMode) {
-            cancelLayoutInternalUnexpectedly("Full screen mode isn't yet supported.");
-            return;
-        }
-
         if (mMode != MODE_COMMIT && mMode != MODE_ADD_TO_DICTIONARY) {
             if (mMode == MODE_NONE) {
                 cancelLayoutInternalExpectedly("Not ready for layouting.");
@@ -274,8 +261,8 @@
             }
             final int composingTextStart = info.getComposingTextStart();
             final int lastCharRectIndex = composingTextStart + composingText.length() - 1;
-            final RectF lastCharRect = info.getCharacterRect(lastCharRectIndex);
-            final int lastCharRectFlag = info.getCharacterRectFlags(lastCharRectIndex);
+            final RectF lastCharRect = info.getCharacterBounds(lastCharRectIndex);
+            final int lastCharRectFlag = info.getCharacterBoundsFlags(lastCharRectIndex);
             final boolean hasInvisibleRegionInLastCharRect =
                     (lastCharRectFlag & CursorAnchorInfoCompatWrapper.FLAG_HAS_INVISIBLE_REGION)
                             != 0;
@@ -285,7 +272,7 @@
             }
             final RectF segmentStartCharRect = new RectF(lastCharRect);
             for (int i = composingText.length() - 2; i >= 0; --i) {
-                final RectF charRect = info.getCharacterRect(composingTextStart + i);
+                final RectF charRect = info.getCharacterBounds(composingTextStart + i);
                 if (charRect == null) {
                     break;
                 }
@@ -328,7 +315,7 @@
                 return;
             }
         } else {
-            if (!TextUtils.isEmpty(composingText)) {
+            if (!mIsFullScreenMode && !TextUtils.isEmpty(composingText)) {
                 // This is an unexpected case.
                 // TODO: Document this.
                 mUiOperator.hideUi();
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index c348e6c..86fe642 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -46,6 +46,7 @@
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
+import android.view.ViewTreeObserver;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.inputmethod.CompletionInfo;
@@ -53,6 +54,7 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethod;
 import android.view.inputmethod.InputMethodSubtype;
+import android.widget.TextView;
 
 import com.android.inputmethod.accessibility.AccessibilityUtils;
 import com.android.inputmethod.annotations.UsedForTesting;
@@ -85,6 +87,7 @@
 import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor;
 import com.android.inputmethod.latin.utils.ApplicationUtils;
 import com.android.inputmethod.latin.utils.CapsModeUtils;
+import com.android.inputmethod.latin.utils.CursorAnchorInfoUtils;
 import com.android.inputmethod.latin.utils.CoordinateUtils;
 import com.android.inputmethod.latin.utils.DialogUtils;
 import com.android.inputmethod.latin.utils.DistracterFilterCheckingExactMatchesAndSuggestions;
@@ -152,6 +155,7 @@
     // TODO: Move these {@link View}s to {@link KeyboardSwitcher}.
     private View mInputView;
     private SuggestionStripView mSuggestionStripView;
+    private TextView mExtractEditText;
 
     private RichInputMethodManager mRichImm;
     @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
@@ -713,11 +717,27 @@
 
     @Override
     public void onConfigurationChanged(final Configuration conf) {
-        final SettingsValues settingsValues = mSettings.getCurrent();
+        SettingsValues settingsValues = mSettings.getCurrent();
         if (settingsValues.mDisplayOrientation != conf.orientation) {
             mHandler.startOrientationChanging();
             mInputLogic.onOrientationChange(mSettings.getCurrent());
         }
+        if (settingsValues.mHasHardwareKeyboard != Settings.readHasHardwareKeyboard(conf)) {
+            // If the state of having a hardware keyboard changed, then we want to reload the
+            // settings to adjust for that.
+            // TODO: we should probably do this unconditionally here, rather than only when we
+            // have a change in hardware keyboard configuration.
+            loadSettings();
+            settingsValues = mSettings.getCurrent();
+            if (settingsValues.mHasHardwareKeyboard) {
+                // We call cleanupInternalStateForFinishInput() because it's the right thing to do;
+                // however, it seems at the moment the framework is passing us a seemingly valid
+                // but actually non-functional InputConnection object. So if this bug ever gets
+                // fixed we'll be able to remove the composition, but until it is this code is
+                // actually not doing much.
+                cleanupInternalStateForFinishInput();
+            }
+        }
         // TODO: Remove this test.
         if (!conf.locale.equals(mPersonalizationDictionaryUpdater.getLocale())) {
             refreshPersonalizationDictionarySession(settingsValues);
@@ -742,6 +762,49 @@
     }
 
     @Override
+    public void setExtractView(final View view) {
+        final TextView prevExtractEditText = mExtractEditText;
+        super.setExtractView(view);
+        TextView nextExtractEditText = null;
+        if (view != null) {
+            final View extractEditText = view.findViewById(android.R.id.inputExtractEditText);
+            if (extractEditText instanceof TextView) {
+                nextExtractEditText = (TextView)extractEditText;
+            }
+        }
+        if (prevExtractEditText == nextExtractEditText) {
+            return;
+        }
+        if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK && prevExtractEditText != null) {
+            prevExtractEditText.getViewTreeObserver().removeOnPreDrawListener(
+                    mExtractTextViewPreDrawListener);
+        }
+        mExtractEditText = nextExtractEditText;
+        if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK && mExtractEditText != null) {
+            mExtractEditText.getViewTreeObserver().addOnPreDrawListener(
+                    mExtractTextViewPreDrawListener);
+        }
+    }
+
+    private final ViewTreeObserver.OnPreDrawListener mExtractTextViewPreDrawListener =
+            new ViewTreeObserver.OnPreDrawListener() {
+                @Override
+                public boolean onPreDraw() {
+                    onExtractTextViewPreDraw();
+                    return true;
+                }
+            };
+
+    private void onExtractTextViewPreDraw() {
+        if (!ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK || !isFullscreenMode()
+                || mExtractEditText == null) {
+            return;
+        }
+        final CursorAnchorInfo info = CursorAnchorInfoUtils.getCursorAnchorInfo(mExtractEditText);
+        mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.fromObject(info));
+    }
+
+    @Override
     public void setCandidatesView(final View view) {
         // To ensure that CandidatesView will never be set.
         return;
@@ -843,40 +906,52 @@
         // Note: This call should be done by InputMethodService?
         updateFullscreenMode();
 
-        // The app calling setText() has the effect of clearing the composing
-        // span, so we should reset our state unconditionally, even if restarting is true.
-        // We also tell the input logic about the combining rules for the current subtype, so
-        // it can adjust its combiners if needed.
-        mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype(),
-                currentSettingsValues);
+        // ALERT: settings have not been reloaded and there is a chance they may be stale.
+        // In the practice, if it is, we should have gotten onConfigurationChanged so it should
+        // be fine, but this is horribly confusing and must be fixed AS SOON AS POSSIBLE.
 
-        // Note: the following does a round-trip IPC on the main thread: be careful
-        final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
+        // In some cases the input connection has not been reset yet and we can't access it. In
+        // this case we will need to call loadKeyboard() later, when it's accessible, so that we
+        // can go into the correct mode, so we need to do some housekeeping here.
+        final boolean needToCallLoadKeyboardLater;
         final Suggest suggest = mInputLogic.mSuggest;
-        if (null != currentLocale && !currentLocale.equals(suggest.getLocale())) {
-            // TODO: Do this automatically.
-            resetSuggest();
-        }
+        if (!currentSettingsValues.mHasHardwareKeyboard) {
+            // The app calling setText() has the effect of clearing the composing
+            // span, so we should reset our state unconditionally, even if restarting is true.
+            // We also tell the input logic about the combining rules for the current subtype, so
+            // it can adjust its combiners if needed.
+            mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype(),
+                    currentSettingsValues);
 
-        // TODO[IL]: Can the following be moved to InputLogic#startInput?
-        final boolean canReachInputConnection;
-        if (!mInputLogic.mConnection.resetCachesUponCursorMoveAndReturnSuccess(
-                editorInfo.initialSelStart, editorInfo.initialSelEnd,
-                false /* shouldFinishComposition */)) {
-            // Sometimes, while rotating, for some reason the framework tells the app we are not
-            // connected to it and that means we can't refresh the cache. In this case, schedule a
-            // refresh later.
-            // We try resetting the caches up to 5 times before giving up.
-            mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */);
-            // mLastSelection{Start,End} are reset later in this method, don't need to do it here
-            canReachInputConnection = false;
+            // Note: the following does a round-trip IPC on the main thread: be careful
+            final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
+            if (null != currentLocale && !currentLocale.equals(suggest.getLocale())) {
+                // TODO: Do this automatically.
+                resetSuggest();
+            }
+
+            // TODO[IL]: Can the following be moved to InputLogic#startInput?
+            if (!mInputLogic.mConnection.resetCachesUponCursorMoveAndReturnSuccess(
+                    editorInfo.initialSelStart, editorInfo.initialSelEnd,
+                    false /* shouldFinishComposition */)) {
+                // Sometimes, while rotating, for some reason the framework tells the app we are not
+                // connected to it and that means we can't refresh the cache. In this case, schedule
+                // a refresh later.
+                // We try resetting the caches up to 5 times before giving up.
+                mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */);
+                // mLastSelection{Start,End} are reset later in this method, no need to do it here
+                needToCallLoadKeyboardLater = true;
+            } else {
+                // When rotating, initialSelStart and initialSelEnd sometimes are lying. Make a best
+                // effort to work around this bug.
+                mInputLogic.mConnection.tryFixLyingCursorPosition();
+                mHandler.postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */,
+                        true /* shouldDelay */);
+                needToCallLoadKeyboardLater = false;
+            }
         } else {
-            // When rotating, initialSelStart and initialSelEnd sometimes are lying. Make a best
-            // effort to work around this bug.
-            mInputLogic.mConnection.tryFixLyingCursorPosition();
-            mHandler.postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */,
-                    true /* shouldDelay */);
-            canReachInputConnection = true;
+            // If we have a hardware keyboard we don't need to call loadKeyboard later anyway.
+            needToCallLoadKeyboardLater = false;
         }
 
         if (isDifferentTextField ||
@@ -894,9 +969,9 @@
 
             switcher.loadKeyboard(editorInfo, currentSettingsValues, getCurrentAutoCapsState(),
                     getCurrentRecapitalizeState());
-            if (!canReachInputConnection) {
-                // If we can't reach the input connection, we will call loadKeyboard again later,
-                // so we need to save its state now. The call will be done in #retryResetCaches.
+            if (needToCallLoadKeyboardLater) {
+                // If we need to call loadKeyboard again later, we need to save its state now. The
+                // later call will be done in #retryResetCaches.
                 switcher.saveKeyboardState();
             }
         } else if (restarting) {
@@ -953,6 +1028,10 @@
 
     private void onFinishInputViewInternal(final boolean finishingInput) {
         super.onFinishInputView(finishingInput);
+        cleanupInternalStateForFinishInput();
+    }
+
+    private void cleanupInternalStateForFinishInput() {
         mKeyboardSwitcher.deallocateMemory();
         // Remove pending messages related to update suggestions
         mHandler.cancelUpdateSuggestionStrip();
@@ -972,13 +1051,12 @@
                     + ", cs=" + composingSpanStart + ", ce=" + composingSpanEnd);
         }
 
-        // If the keyboard is not visible, we don't need to do all the housekeeping work, as it
-        // will be reset when the keyboard shows up anyway.
-        // TODO: revisit this when LatinIME supports hardware keyboards.
-        // NOTE: the test harness subclasses LatinIME and overrides isInputViewShown().
-        // TODO: find a better way to simulate actual execution.
-        if (isInputViewShown() &&
-                mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd)) {
+        // This call happens when we have a hardware keyboard as well as when we don't. While we
+        // don't support hardware keyboards yet we should avoid doing the processing associated
+        // with cursor movement when we have a hardware keyboard since we are not in charge.
+        final SettingsValues settingsValues = mSettings.getCurrent();
+        if ((!settingsValues.mHasHardwareKeyboard || ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED)
+                && mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd)) {
             mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(),
                     getCurrentRecapitalizeState());
         }
@@ -987,9 +1065,10 @@
     // We cannot mark this method as @Override until new SDK becomes publicly available.
     // @Override
     public void onUpdateCursorAnchorInfo(final CursorAnchorInfo info) {
-        if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) {
-            mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.fromObject(info));
+        if (!ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK || isFullscreenMode()) {
+            return;
         }
+        mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.fromObject(info));
     }
 
     /**
@@ -1074,12 +1153,13 @@
     @Override
     public void onComputeInsets(final InputMethodService.Insets outInsets) {
         super.onComputeInsets(outInsets);
+        final SettingsValues settingsValues = mSettings.getCurrent();
         final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView();
         if (visibleKeyboardView == null || !hasSuggestionStripView()) {
             return;
         }
         final int inputHeight = mInputView.getHeight();
-        final boolean hasHardwareKeyboard = mKeyboardSwitcher.hasHardwareKeyboard();
+        final boolean hasHardwareKeyboard = settingsValues.mHasHardwareKeyboard;
         if (hasHardwareKeyboard && visibleKeyboardView.getVisibility() == View.GONE) {
             // If there is a hardware keyboard and a visible software keyboard view has been hidden,
             // no visual element will be shown on the screen.
@@ -1115,7 +1195,8 @@
 
     @Override
     public boolean onShowInputRequested(final int flags, final boolean configChange) {
-        if ((flags & InputMethod.SHOW_EXPLICIT) == 0 && mKeyboardSwitcher.hasHardwareKeyboard()) {
+        final SettingsValues settingsValues = mSettings.getCurrent();
+        if ((flags & InputMethod.SHOW_EXPLICIT) == 0 && settingsValues.mHasHardwareKeyboard) {
             // Even when IME is implicitly shown and physical keyboard is connected, we should
             // show {@link InputView}.
             // See {@link InputMethodService#onShowInputRequested(int,boolean)}.
@@ -1126,7 +1207,8 @@
 
     @Override
     public boolean onEvaluateFullscreenMode() {
-        if (mKeyboardSwitcher.hasHardwareKeyboard()) {
+        final SettingsValues settingsValues = mSettings.getCurrent();
+        if (settingsValues.mHasHardwareKeyboard) {
             // If there is a hardware keyboard, disable full screen mode.
             return false;
         }
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 6b6384c..b5d42dd 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -623,14 +623,24 @@
         return Arrays.binarySearch(sortedSeparators, code) >= 0;
     }
 
+    private static boolean isPartOfCompositionForScript(final int codePoint,
+            final SpacingAndPunctuations spacingAndPunctuations, final int scriptId) {
+        // We always consider word connectors part of compositions.
+        return spacingAndPunctuations.isWordConnector(codePoint)
+                // Otherwise, it's part of composition if it's part of script and not a separator.
+                || (!spacingAndPunctuations.isWordSeparator(codePoint)
+                        && ScriptUtils.isLetterPartOfScript(codePoint, scriptId));
+    }
+
     /**
      * Returns the text surrounding the cursor.
      *
-     * @param sortedSeparators a sorted array of code points that split words.
+     * @param spacingAndPunctuations the rules for spacing and punctuation
      * @param scriptId the script we consider to be writing words, as one of ScriptUtils.SCRIPT_*
      * @return a range containing the text surrounding the cursor
      */
-    public TextRange getWordRangeAtCursor(final int[] sortedSeparators, final int scriptId) {
+    public TextRange getWordRangeAtCursor(final SpacingAndPunctuations spacingAndPunctuations,
+            final int scriptId) {
         mIC = mParent.getCurrentInputConnection();
         if (mIC == null) {
             return null;
@@ -647,8 +657,7 @@
         int startIndexInBefore = before.length();
         while (startIndexInBefore > 0) {
             final int codePoint = Character.codePointBefore(before, startIndexInBefore);
-            if (isSeparator(codePoint, sortedSeparators)
-                    || !ScriptUtils.isLetterPartOfScript(codePoint, scriptId)) {
+            if (!isPartOfCompositionForScript(codePoint, spacingAndPunctuations, scriptId)) {
                 break;
             }
             --startIndexInBefore;
@@ -661,8 +670,7 @@
         int endIndexInAfter = -1;
         while (++endIndexInAfter < after.length()) {
             final int codePoint = Character.codePointAt(after, endIndexInAfter);
-            if (isSeparator(codePoint, sortedSeparators)
-                    || !ScriptUtils.isLetterPartOfScript(codePoint, scriptId)) {
+            if (!isPartOfCompositionForScript(codePoint, spacingAndPunctuations, scriptId)) {
                 break;
             }
             if (Character.isSupplementaryCodePoint(codePoint)) {
diff --git a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
index 7071d86..a87785b 100644
--- a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
+++ b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
@@ -168,7 +168,7 @@
         } catch (IOException e) {
             // There was an error: show a dialog
             new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context))
-                    .setTitle(R.string.error)
+                    .setTitle(R.string.read_external_dictionary_error)
                     .setMessage(e.toString())
                     .setPositiveButton(android.R.string.ok, new OnClickListener() {
                         @Override
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 89aea43..5ab3571 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -1478,8 +1478,7 @@
             return;
         }
         final TextRange range = mConnection.getWordRangeAtCursor(
-                settingsValues.mSpacingAndPunctuations.mSortedWordSeparators,
-                currentKeyboardScriptId);
+                settingsValues.mSpacingAndPunctuations, currentKeyboardScriptId);
         if (null == range) return; // Happens if we don't have an input connection at all
         if (range.length() <= 0) {
             // Race condition, or touching a word in a non-supported script.
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 9d3c27b..3c7a991 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.pm.ApplicationInfo;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.os.Build;
 import android.preference.PreferenceManager;
@@ -368,6 +369,15 @@
         return prefs.getBoolean(PREF_SHOW_SETUP_WIZARD_ICON, false);
     }
 
+    public static boolean readHasHardwareKeyboard(final Configuration conf) {
+        // The standard way of finding out whether we have a hardware keyboard. This code is taken
+        // from InputMethodService#onEvaluateInputShown, which canonically determines this.
+        // In a nutshell, we have a keyboard if the configuration says the type of hardware keyboard
+        // is NOKEYS and if it's not hidden (e.g. folded inside the device).
+        return conf.keyboard != Configuration.KEYBOARD_NOKEYS
+                && conf.hardKeyboardHidden != Configuration.HARDKEYBOARDHIDDEN_YES;
+    }
+
     public static boolean isInternal(final SharedPreferences prefs) {
         return prefs.getBoolean(PREF_KEY_IS_INTERNAL, false);
     }
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index 1da112b..308f3b4 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -52,7 +52,10 @@
     public final SpacingAndPunctuations mSpacingAndPunctuations;
     public final int mDelayInMillisecondsToUpdateOldSuggestions;
     public final long mDoubleSpacePeriodTimeout;
-
+    // From configuration:
+    public final Locale mLocale;
+    public final boolean mHasHardwareKeyboard;
+    public final int mDisplayOrientation;
     // From preferences, in the same order as xml/prefs.xml:
     public final boolean mAutoCap;
     public final boolean mVibrateOn;
@@ -73,7 +76,6 @@
     public final boolean mSlidingKeyInputPreviewEnabled;
     public final boolean mPhraseGestureEnabled;
     public final int mKeyLongpressTimeout;
-    public final Locale mLocale;
     public final boolean mEnableMetricsLogging;
     public final boolean mShouldShowUiToAcceptTypedWord;
 
@@ -88,7 +90,6 @@
     public final float mAutoCorrectionThreshold;
     public final boolean mAutoCorrectionEnabledPerUserSettings;
     private final boolean mSuggestionsEnabledPerUserSettings;
-    public final int mDisplayOrientation;
     private final AsyncResultHolder<AppWorkaroundsUtils> mAppWorkarounds;
 
     // Setting values for additional features
@@ -152,6 +153,7 @@
         mAutoCorrectEnabled = Settings.readAutoCorrectEnabled(autoCorrectionThresholdRawValue, res);
         mBigramPredictionEnabled = readBigramPredictionEnabled(prefs, res);
         mDoubleSpacePeriodTimeout = res.getInteger(R.integer.config_double_space_period_timeout);
+        mHasHardwareKeyboard = Settings.readHasHardwareKeyboard(res.getConfiguration());
         mEnableMetricsLogging = prefs.getBoolean(Settings.PREF_ENABLE_METRICS_LOGGING, true);
         mShouldShowUiToAcceptTypedWord = Settings.HAS_UI_TO_ACCEPT_TYPED_WORD
                 && prefs.getBoolean(DebugSettings.PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD, true);
diff --git a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
index b8d2a22..49d8110 100644
--- a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
+++ b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
@@ -18,6 +18,7 @@
 
 import android.content.res.Resources;
 
+import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.internal.MoreKeySpec;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.PunctuationSuggestions;
@@ -68,6 +69,22 @@
         mSuggestPuncList = PunctuationSuggestions.newPunctuationSuggestions(suggestPuncsSpec);
     }
 
+    @UsedForTesting
+    public SpacingAndPunctuations(final SpacingAndPunctuations model,
+            final int[] overrideSortedWordSeparators) {
+        mSortedSymbolsPrecededBySpace = model.mSortedSymbolsPrecededBySpace;
+        mSortedSymbolsFollowedBySpace = model.mSortedSymbolsFollowedBySpace;
+        mSortedSymbolsClusteringTogether = model.mSortedSymbolsClusteringTogether;
+        mSortedWordConnectors = model.mSortedWordConnectors;
+        mSortedWordSeparators = overrideSortedWordSeparators;
+        mSuggestPuncList = model.mSuggestPuncList;
+        mSentenceSeparator = model.mSentenceSeparator;
+        mSentenceSeparatorAndSpace = model.mSentenceSeparatorAndSpace;
+        mCurrentLanguageHasSpaces = model.mCurrentLanguageHasSpaces;
+        mUsesAmericanTypography = model.mUsesAmericanTypography;
+        mUsesGermanRules = model.mUsesGermanRules;
+    }
+
     public boolean isWordSeparator(final int code) {
         return Arrays.binarySearch(mSortedWordSeparators, code) >= 0;
     }
diff --git a/java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java
new file mode 100644
index 0000000..9dc0524
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.utils;
+
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.inputmethodservice.ExtractEditText;
+import android.inputmethodservice.InputMethodService;
+import android.text.Layout;
+import android.text.Spannable;
+import android.view.View;
+import android.view.ViewParent;
+import android.view.inputmethod.CursorAnchorInfo;
+import android.widget.TextView;
+
+/**
+ * This class allows input methods to extract {@link CursorAnchorInfo} directly from the given
+ * {@link TextView}. This is useful and even necessary to support full-screen mode where the default
+ * {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} event callback must be
+ * ignored because it reports the character locations of the target application rather than
+ * characters on {@link ExtractEditText}.
+ */
+public final class CursorAnchorInfoUtils {
+    private CursorAnchorInfoUtils() {
+        // This helper class is not instantiable.
+    }
+
+    private static boolean isPositionVisible(final View view, final float positionX,
+            final float positionY) {
+        final float[] position = new float[] { positionX, positionY };
+        View currentView = view;
+
+        while (currentView != null) {
+            if (currentView != view) {
+                // Local scroll is already taken into account in positionX/Y
+                position[0] -= currentView.getScrollX();
+                position[1] -= currentView.getScrollY();
+            }
+
+            if (position[0] < 0 || position[1] < 0 ||
+                    position[0] > currentView.getWidth() || position[1] > currentView.getHeight()) {
+                return false;
+            }
+
+            if (!currentView.getMatrix().isIdentity()) {
+                currentView.getMatrix().mapPoints(position);
+            }
+
+            position[0] += currentView.getLeft();
+            position[1] += currentView.getTop();
+
+            final ViewParent parent = currentView.getParent();
+            if (parent instanceof View) {
+                currentView = (View) parent;
+            } else {
+                // We've reached the ViewRoot, stop iterating
+                currentView = null;
+            }
+        }
+
+        // We've been able to walk up the view hierarchy and the position was never clipped
+        return true;
+    }
+
+    /**
+     * Returns {@link CursorAnchorInfo} from the given {@link TextView}.
+     * @param textView the target text view from which {@link CursorAnchorInfo} is to be extracted.
+     * @return the {@link CursorAnchorInfo} object based on the current layout. {@code null} if it
+     * is not feasible.
+     */
+    public static CursorAnchorInfo getCursorAnchorInfo(final TextView textView) {
+        Layout layout = textView.getLayout();
+        if (layout == null) {
+            return null;
+        }
+
+        final CursorAnchorInfo.Builder builder = new CursorAnchorInfo.Builder();
+
+        final int selectionStart = textView.getSelectionStart();
+        builder.setSelectionRange(selectionStart, textView.getSelectionEnd());
+
+        // Construct transformation matrix from view local coordinates to screen coordinates.
+        final Matrix viewToScreenMatrix = new Matrix(textView.getMatrix());
+        final int[] viewOriginInScreen = new int[2];
+        textView.getLocationOnScreen(viewOriginInScreen);
+        viewToScreenMatrix.postTranslate(viewOriginInScreen[0], viewOriginInScreen[1]);
+        builder.setMatrix(viewToScreenMatrix);
+
+        if (layout.getLineCount() == 0) {
+            return null;
+        }
+        final Rect lineBoundsWithoutOffset = new Rect();
+        final Rect lineBoundsWithOffset = new Rect();
+        layout.getLineBounds(0, lineBoundsWithoutOffset);
+        textView.getLineBounds(0, lineBoundsWithOffset);
+        final float viewportToContentHorizontalOffset = lineBoundsWithOffset.left
+                - lineBoundsWithoutOffset.left - textView.getScrollX();
+        final float viewportToContentVerticalOffset = lineBoundsWithOffset.top
+                - lineBoundsWithoutOffset.top - textView.getScrollY();
+
+        final CharSequence text = textView.getText();
+        if (text instanceof Spannable) {
+            // Here we assume that the composing text is marked as SPAN_COMPOSING flag. This is not
+            // necessarily true, but basically works.
+            int composingTextStart = text.length();
+            int composingTextEnd = 0;
+            final Spannable spannable = (Spannable) text;
+            final Object[] spans = spannable.getSpans(0, text.length(), Object.class);
+            for (Object span : spans) {
+                final int spanFlag = spannable.getSpanFlags(span);
+                if ((spanFlag & Spannable.SPAN_COMPOSING) != 0) {
+                    composingTextStart = Math.min(composingTextStart,
+                            spannable.getSpanStart(span));
+                    composingTextEnd = Math.max(composingTextEnd, spannable.getSpanEnd(span));
+                }
+            }
+
+            final boolean hasComposingText =
+                    (0 <= composingTextStart) && (composingTextStart < composingTextEnd);
+            if (hasComposingText) {
+                final CharSequence composingText = text.subSequence(composingTextStart,
+                        composingTextEnd);
+                builder.setComposingText(composingTextStart, composingText);
+
+                final int minLine = layout.getLineForOffset(composingTextStart);
+                final int maxLine = layout.getLineForOffset(composingTextEnd - 1);
+                for (int line = minLine; line <= maxLine; ++line) {
+                    final int lineStart = layout.getLineStart(line);
+                    final int lineEnd = layout.getLineEnd(line);
+                    final int offsetStart = Math.max(lineStart, composingTextStart);
+                    final int offsetEnd = Math.min(lineEnd, composingTextEnd);
+                    final boolean ltrLine =
+                            layout.getParagraphDirection(line) == Layout.DIR_LEFT_TO_RIGHT;
+                    final float[] widths = new float[offsetEnd - offsetStart];
+                    layout.getPaint().getTextWidths(text, offsetStart, offsetEnd, widths);
+                    final float top = layout.getLineTop(line);
+                    final float bottom = layout.getLineBottom(line);
+                    for (int offset = offsetStart; offset < offsetEnd; ++offset) {
+                        final float charWidth = widths[offset - offsetStart];
+                        final boolean isRtl = layout.isRtlCharAt(offset);
+                        final float primary = layout.getPrimaryHorizontal(offset);
+                        final float secondary = layout.getSecondaryHorizontal(offset);
+                        // TODO: This doesn't work perfectly for text with custom styles and TAB
+                        // chars.
+                        final float left;
+                        final float right;
+                        if (ltrLine) {
+                            if (isRtl) {
+                                left = secondary - charWidth;
+                                right = secondary;
+                            } else {
+                                left = primary;
+                                right = primary + charWidth;
+                            }
+                        } else {
+                            if (!isRtl) {
+                                left = secondary;
+                                right = secondary + charWidth;
+                            } else {
+                                left = primary - charWidth;
+                                right = primary;
+                            }
+                        }
+                        // TODO: Check top-right and bottom-left as well.
+                        final float localLeft = left + viewportToContentHorizontalOffset;
+                        final float localRight = right + viewportToContentHorizontalOffset;
+                        final float localTop = top + viewportToContentVerticalOffset;
+                        final float localBottom = bottom + viewportToContentVerticalOffset;
+                        final boolean isTopLeftVisible = isPositionVisible(textView,
+                                localLeft, localTop);
+                        final boolean isBottomRightVisible =
+                                isPositionVisible(textView, localRight, localBottom);
+                        int characterBoundsFlags = 0;
+                        if (isTopLeftVisible || isBottomRightVisible) {
+                            characterBoundsFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
+                        }
+                        if (!isTopLeftVisible || !isTopLeftVisible) {
+                            characterBoundsFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
+                        }
+                        if (isRtl) {
+                            characterBoundsFlags |= CursorAnchorInfo.FLAG_IS_RTL;
+                        }
+                        // Here offset is the index in Java chars.
+                        builder.addCharacterBounds(offset, localLeft, localTop, localRight,
+                                localBottom, characterBoundsFlags);
+                    }
+                }
+            }
+        }
+
+        // Treat selectionStart as the insertion point.
+        if (0 <= selectionStart) {
+            final int offset = selectionStart;
+            final int line = layout.getLineForOffset(offset);
+            final float insertionMarkerX = layout.getPrimaryHorizontal(offset)
+                    + viewportToContentHorizontalOffset;
+            final float insertionMarkerTop = layout.getLineTop(line)
+                    + viewportToContentVerticalOffset;
+            final float insertionMarkerBaseline = layout.getLineBaseline(line)
+                    + viewportToContentVerticalOffset;
+            final float insertionMarkerBottom = layout.getLineBottom(line)
+                    + viewportToContentVerticalOffset;
+            final boolean isTopVisible =
+                    isPositionVisible(textView, insertionMarkerX, insertionMarkerTop);
+            final boolean isBottomVisible =
+                    isPositionVisible(textView, insertionMarkerX, insertionMarkerBottom);
+            int insertionMarkerFlags = 0;
+            if (isTopVisible || isBottomVisible) {
+                insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
+            }
+            if (!isTopVisible || !isBottomVisible) {
+                insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
+            }
+            if (layout.isRtlCharAt(offset)) {
+                insertionMarkerFlags |= CursorAnchorInfo.FLAG_IS_RTL;
+            }
+            builder.setInsertionMarkerLocation(insertionMarkerX, insertionMarkerTop,
+                    insertionMarkerBaseline, insertionMarkerBottom, insertionMarkerFlags);
+        }
+        return builder.build();
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysBase.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysBase.java
index 1fce362..8a55455 100644
--- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysBase.java
@@ -35,12 +35,24 @@
     private ExpectedMoreKey mExpectedNavigatePreviousMoreKey;
     private ExpectedMoreKey mExpectedEmojiMoreKey;
 
+    protected ExpectedMoreKey getExpectedNavigateNextMoreKey() {
+        return new ExpectedMoreKey(R.string.label_next_key);
+    }
+
+    protected ExpectedMoreKey getExpectedNavigatePreviousMoreKey() {
+        return new ExpectedMoreKey(R.string.label_previous_key);
+    }
+
+    protected ExpectedMoreKey getExpectedEmojiMoreKey() {
+        return new ExpectedMoreKey(KeyboardIconsSet.NAME_EMOJI_ACTION_KEY);
+    }
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mExpectedNavigateNextMoreKey = new ExpectedMoreKey(R.string.label_next_key);
-        mExpectedNavigatePreviousMoreKey = new ExpectedMoreKey(R.string.label_previous_key);
-        mExpectedEmojiMoreKey = new ExpectedMoreKey(KeyboardIconsSet.NAME_EMOJI_ACTION_KEY);
+        mExpectedNavigateNextMoreKey = getExpectedNavigateNextMoreKey();
+        mExpectedNavigatePreviousMoreKey =  getExpectedNavigatePreviousMoreKey();
+        mExpectedEmojiMoreKey = getExpectedEmojiMoreKey();
     }
 
     /**
@@ -90,6 +102,7 @@
             assertEquals(tag + " column",
                     expectedMoreKeys.length, actualKey.getMoreKeysColumnNumber());
         }
+        assertNotNull(tag + " moreKeys", actualMoreKeys);
         assertEquals(tag, expectedMoreKeys.length, actualMoreKeys.length);
         for (int index = 0; index < actualMoreKeys.length; index++) {
             final int expectedLabelResId = expectedMoreKeys[index].mLabelResId;
diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysLxxTests.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysLxxTests.java
index 02593cb..d2bb41e 100644
--- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysLxxTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysLxxTests.java
@@ -18,6 +18,8 @@
 
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
+
 @SmallTest
 public class KeyboardLayoutSetNavigateMoreKeysLxxTests
         extends KeyboardLayoutSetNavigateMoreKeysBase {
@@ -25,4 +27,14 @@
     protected int getKeyboardThemeForTests() {
         return KeyboardTheme.THEME_ID_LXX_LIGHT;
     }
+
+    @Override
+    protected ExpectedMoreKey getExpectedNavigateNextMoreKey() {
+        return new ExpectedMoreKey(KeyboardIconsSet.NAME_NEXT_KEY);
+    }
+
+    @Override
+    protected ExpectedMoreKey getExpectedNavigatePreviousMoreKey() {
+        return new ExpectedMoreKey(KeyboardIconsSet.NAME_PREVIOUS_KEY);
+    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java
index f95ba3c..a002bbe 100644
--- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java
@@ -52,6 +52,7 @@
         final KeyboardTheme keyboardTheme = KeyboardTheme.searchKeyboardThemeById(
                 getKeyboardThemeForTests());
         setContext(new ContextThemeWrapper(getContext(), keyboardTheme.mStyleId));
+        KeyboardLayoutSet.onKeyboardThemeChanged();
 
         final Context context = getContext();
         mScreenMetrics = context.getResources().getInteger(R.integer.config_screen_metrics);
diff --git a/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java b/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java
index 1999224..f9d7226 100644
--- a/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java
+++ b/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java
@@ -215,18 +215,23 @@
                 "abc 'def", mSpacingAndPunctuations, 2), PrevWordsInfo.EMPTY_PREV_WORDS_INFO);
     }
 
-    /**
-     * Test logic in getting the word range at the cursor.
-     */
-    private static final int[] SPACE = { Constants.CODE_SPACE };
-    static final int[] TAB = { Constants.CODE_TAB };
-    private static final int[] SPACE_TAB = StringUtils.toSortedCodePointArray(" \t");
-    // A character that needs surrogate pair to represent its code point (U+2008A).
-    private static final String SUPPLEMENTARY_CHAR = "\uD840\uDC8A";
-    private static final String HIRAGANA_WORD = "\u3042\u3044\u3046\u3048\u304A"; // あいうえお
-    private static final String GREEK_WORD = "\u03BA\u03B1\u03B9"; // και
-
     public void testGetWordRangeAtCursor() {
+        /**
+         * Test logic in getting the word range at the cursor.
+         */
+        final SpacingAndPunctuations SPACE = new SpacingAndPunctuations(
+                mSpacingAndPunctuations, new int[] { Constants.CODE_SPACE });
+        final SpacingAndPunctuations TAB = new SpacingAndPunctuations(
+                mSpacingAndPunctuations, new int[] { Constants.CODE_TAB });
+        final int[] SPACE_TAB = StringUtils.toSortedCodePointArray(" \t");
+        // A character that needs surrogate pair to represent its code point (U+2008A).
+        final String SUPPLEMENTARY_CHAR_STRING = "\uD840\uDC8A";
+        final SpacingAndPunctuations SUPPLEMENTARY_CHAR = new SpacingAndPunctuations(
+                mSpacingAndPunctuations, StringUtils.toSortedCodePointArray(
+                        SUPPLEMENTARY_CHAR_STRING));
+        final String HIRAGANA_WORD = "\u3042\u3044\u3046\u3048\u304A"; // あいうえお
+        final String GREEK_WORD = "\u03BA\u03B1\u03B9"; // και
+
         ExtractedText et = new ExtractedText();
         final MockInputMethodService mockInputMethodService = new MockInputMethodService();
         final RichInputConnection ic = new RichInputConnection(mockInputMethodService);
@@ -249,10 +254,9 @@
 
         // splitting on supplementary character
         mockInputMethodService.setInputConnection(
-                new MockConnection("one word" + SUPPLEMENTARY_CHAR + "wo", "rd", et));
+                new MockConnection("one word" + SUPPLEMENTARY_CHAR_STRING + "wo", "rd", et));
         ic.beginBatchEdit();
-        r = ic.getWordRangeAtCursor(StringUtils.toSortedCodePointArray(SUPPLEMENTARY_CHAR),
-                ScriptUtils.SCRIPT_LATIN);
+        r = ic.getWordRangeAtCursor(SUPPLEMENTARY_CHAR, ScriptUtils.SCRIPT_LATIN);
         ic.endBatchEdit();
         assertTrue(TextUtils.equals("word", r.mWord));
 
@@ -260,8 +264,7 @@
         mockInputMethodService.setInputConnection(
                 new MockConnection(HIRAGANA_WORD + "wo", "rd" + GREEK_WORD, et));
         ic.beginBatchEdit();
-        r = ic.getWordRangeAtCursor(StringUtils.toSortedCodePointArray(SUPPLEMENTARY_CHAR),
-                ScriptUtils.SCRIPT_LATIN);
+        r = ic.getWordRangeAtCursor(SUPPLEMENTARY_CHAR, ScriptUtils.SCRIPT_LATIN);
         ic.endBatchEdit();
         assertTrue(TextUtils.equals("word", r.mWord));
 
@@ -269,8 +272,7 @@
         mockInputMethodService.setInputConnection(
                 new MockConnection("text" + GREEK_WORD, "text", et));
         ic.beginBatchEdit();
-        r = ic.getWordRangeAtCursor(StringUtils.toSortedCodePointArray(SUPPLEMENTARY_CHAR),
-                ScriptUtils.SCRIPT_GREEK);
+        r = ic.getWordRangeAtCursor(SUPPLEMENTARY_CHAR, ScriptUtils.SCRIPT_GREEK);
         ic.endBatchEdit();
         assertTrue(TextUtils.equals(GREEK_WORD, r.mWord));
     }
@@ -286,6 +288,8 @@
     }
 
     private void helpTestGetSuggestionSpansAtWord(final int cursorPos) {
+        final SpacingAndPunctuations SPACE = new SpacingAndPunctuations(
+                mSpacingAndPunctuations, new int[] { Constants.CODE_SPACE });
         final MockInputMethodService mockInputMethodService = new MockInputMethodService();
         final RichInputConnection ic = new RichInputConnection(mockInputMethodService);
 
diff --git a/tools/dicttool/NativeLib.mk b/tools/dicttool/NativeLib.mk
index 028025d..ffb32ed 100644
--- a/tools/dicttool/NativeLib.mk
+++ b/tools/dicttool/NativeLib.mk
@@ -34,7 +34,6 @@
 LOCAL_MULTILIB := 64
 endif #HOST_JDK_IS_64BIT_VERSION
 
-LOCAL_CLANG := true
 # For C++11
 LOCAL_CFLAGS += -std=c++11