Merge "Support migration/dump of Beginning-of-Sentence entries."
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index 5d8ef43..6f4e602 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -86,7 +86,7 @@
         </receiver>
 
         <activity android:name=".settings.SettingsActivity"
-                android:theme="@style/platformSettingsTheme"
+                android:theme="@style/platformActivityTheme"
                 android:label="@string/english_ime_settings"
                 android:uiOptions="splitActionBarWhenNarrow">
             <intent-filter>
@@ -95,7 +95,7 @@
         </activity>
 
         <activity android:name=".spellcheck.SpellCheckerSettingsActivity"
-                  android:theme="@style/platformSettingsTheme"
+                  android:theme="@style/platformActivityTheme"
                   android:label="@string/android_spell_checker_settings">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -103,7 +103,7 @@
         </activity>
 
         <activity android:name=".settings.DebugSettingsActivity"
-                android:theme="@style/platformSettingsTheme"
+                android:theme="@style/platformActivityTheme"
                 android:label="@string/english_ime_debug_settings">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -150,7 +150,7 @@
         </receiver>
 
         <activity android:name="com.android.inputmethod.dictionarypack.DictionarySettingsActivity"
-                android:theme="@style/platformSettingsTheme"
+                android:theme="@style/platformActivityTheme"
                 android:label="@string/dictionary_settings_title"
                 android:uiOptions="splitActionBarWhenNarrow">
             <intent-filter>
diff --git a/java/res/values-v20/platform-theme.xml b/java/res/values-v20/platform-theme.xml
new file mode 100644
index 0000000..52e7f35
--- /dev/null
+++ b/java/res/values-v20/platform-theme.xml
@@ -0,0 +1,26 @@
+<?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.
+*/
+-->
+
+<!-- TODO: This file is temporarily placed under values-v20. -->
+<!-- TODO: It might be moved under values-v21. -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="platformActivityTheme" parent="@android:style/Theme.Material.Light" />
+    <style name="platformDialogTheme" parent="@android:style/Theme.Material.Light.Dialog" />
+</resources>
diff --git a/java/res/values-v21/platform-theme.xml b/java/res/values-v21/platform-theme.xml
deleted file mode 100644
index a49e364..0000000
--- a/java/res/values-v21/platform-theme.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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:android="http://schemas.android.com/apk/res/android">
-    <style name="platformActivityTheme" parent="@android:style/Theme.Material.Light" />
-    <!-- From packages/apps/Settings -->
-    <style name="platformSettingsTheme" parent="@android:style/Theme.Material.Settings">
-        <item name="android:actionBarStyle">@android:style/Widget.Material.Light.ActionBar.Solid</item>
-        <item name="android:alertDialogTheme">@style/Theme.AlertDialog</item>
-    </style>
-    <!-- From packages/apps/Settings -->
-    <style name="Theme.AlertDialog" parent="@*android:style/Theme.Material.Light.Dialog.Alert">
-        <!-- Used by the ActionBar: @color/theme_primary -->
-        <item name="android:colorPrimary">#ff263238</item>
-        <!-- Used by the StatusBar: @color/theme_primary_dark -->
-        <item name="android:colorPrimaryDark">#ff21272b</item>
-        <!-- Used by controls, e.g. CheckBox, ProgressBar, etc.: @color/theme_accent -->
-        <item name="android:colorAccent">#ff009688</item>
-    </style>
-    <style name="platformDialogTheme" parent="@android:style/Theme.Material.Light.Dialog" />
-</resources>
diff --git a/java/res/values/platform-theme.xml b/java/res/values/platform-theme.xml
index e688597..8e131a2 100644
--- a/java/res/values/platform-theme.xml
+++ b/java/res/values/platform-theme.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <style name="platformActivityTheme" parent="@android:style/Theme.Holo" />
-    <style name="platformSettingsTheme" parent="@android:style/Theme.Holo" />
     <style name="platformDialogTheme" parent="@android:style/Theme.Holo.Dialog" />
 </resources>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index cb951d2..e71d951 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -21,77 +21,61 @@
     <PreferenceScreen
         android:title="@string/settings_screen_input"
         android:key="screen_input">
-        <SwitchPreference
+        <CheckBoxPreference
             android:key="auto_cap"
             android:title="@string/auto_cap"
             android:summary="@string/auto_cap_summary"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="true" />
-        <SwitchPreference
+            android:defaultValue="true"
+            android:persistent="true" />
+        <CheckBoxPreference
             android:key="pref_key_use_double_space_period"
             android:title="@string/use_double_space_period"
             android:summary="@string/use_double_space_period_summary"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="true" />
-        <SwitchPreference
+            android:defaultValue="true"
+            android:persistent="true" />
+        <CheckBoxPreference
             android:key="vibrate_on"
             android:title="@string/vibrate_on_keypress"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="@bool/config_default_vibration_enabled" />
-        <SwitchPreference
+            android:defaultValue="@bool/config_default_vibration_enabled"
+            android:persistent="true" />
+        <CheckBoxPreference
             android:key="sound_on"
             android:title="@string/sound_on_keypress"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="@bool/config_default_sound_enabled" />
-        <SwitchPreference
+            android:defaultValue="@bool/config_default_sound_enabled"
+            android:persistent="true" />
+        <CheckBoxPreference
             android:key="popup_on"
             android:title="@string/popup_on_keypress"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="@bool/config_default_key_preview_popup" />
-        <SwitchPreference
+            android:defaultValue="@bool/config_default_key_preview_popup"
+            android:persistent="true" />
+        <CheckBoxPreference
             android:key="pref_voice_input_key"
             android:title="@string/voice_input"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="true" />
+            android:defaultValue="true"
+            android:persistent="true" />
     </PreferenceScreen>
     <ListPreference
         android:key="pref_keyboard_theme"
         android:title="@string/keyboard_theme"
-        android:persistent="true"
         android:entryValues="@array/keyboard_theme_ids"
-        android:entries="@array/keyboard_theme_names" />
+        android:entries="@array/keyboard_theme_names"
+        android:persistent="true" />
     <PreferenceScreen
         android:title="@string/settings_screen_multi_lingual"
         android:key="screen_multi_lingual">
-        <SwitchPreference
+        <CheckBoxPreference
             android:key="pref_show_language_switch_key"
             android:title="@string/show_language_switch_key"
             android:summary="@string/show_language_switch_key_summary"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="true" />
-        <SwitchPreference
+            android:defaultValue="true"
+            android:persistent="true" />
+        <CheckBoxPreference
             android:key="pref_include_other_imes_in_language_switch_list"
             android:dependency="pref_show_language_switch_key"
             android:title="@string/include_other_imes_in_language_switch_list"
             android:summary="@string/include_other_imes_in_language_switch_list_summary"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="false" />
+            android:defaultValue="false"
+            android:persistent="true" />
         <PreferenceScreen
             android:fragment="com.android.inputmethod.latin.settings.AdditionalSubtypeSettings"
             android:key="custom_input_styles"
@@ -100,31 +84,25 @@
     <PreferenceScreen
         android:title="@string/settings_screen_gesture"
         android:key="screen_gesture">
-        <SwitchPreference
+        <CheckBoxPreference
             android:key="gesture_input"
             android:title="@string/gesture_input"
             android:summary="@string/gesture_input_summary"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="true" />
-        <SwitchPreference
+            android:defaultValue="true"
+            android:persistent="true" />
+        <CheckBoxPreference
             android:key="pref_gesture_floating_preview_text"
             android:dependency="gesture_input"
             android:title="@string/gesture_floating_preview_text"
             android:summary="@string/gesture_floating_preview_text_summary"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="true" />
-        <SwitchPreference
+            android:defaultValue="true"
+            android:persistent="true" />
+        <CheckBoxPreference
             android:key="pref_gesture_preview_trail"
             android:dependency="gesture_input"
             android:title="@string/gesture_preview_trail"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="true" />
+            android:defaultValue="true"
+            android:persistent="true" />
     </PreferenceScreen>
     <PreferenceScreen
         android:title="@string/settings_screen_correction"
@@ -145,55 +123,47 @@
                  android:value="@string/dictionary_pack_client_id" />
            </intent>
         </PreferenceScreen>
-        <SwitchPreference
+        <CheckBoxPreference
             android:key="pref_key_block_potentially_offensive"
             android:title="@string/prefs_block_potentially_offensive_title"
             android:summary="@string/prefs_block_potentially_offensive_summary"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="@bool/config_block_potentially_offensive" />
+            android:defaultValue="@bool/config_block_potentially_offensive"
+            android:persistent="true" />
         <ListPreference
             android:key="auto_correction_threshold"
             android:title="@string/auto_correction"
             android:summary="@string/auto_correction_summary"
-            android:persistent="true"
             android:entryValues="@array/auto_correction_threshold_mode_indexes"
             android:entries="@array/auto_correction_threshold_modes"
-            android:defaultValue="@string/auto_correction_threshold_mode_index_modest" />
+            android:defaultValue="@string/auto_correction_threshold_mode_index_modest"
+            android:persistent="true" />
         <ListPreference
             android:key="show_suggestions_setting"
             android:summary="@string/prefs_show_suggestions_summary"
             android:title="@string/prefs_show_suggestions"
-            android:persistent="true"
             android:entryValues="@array/prefs_suggestion_visibility_values"
             android:entries="@array/prefs_suggestion_visibilities"
-            android:defaultValue="@string/prefs_suggestion_visibility_default_value" />
-        <SwitchPreference
+            android:defaultValue="@string/prefs_suggestion_visibility_default_value"
+            android:persistent="true" />
+        <CheckBoxPreference
             android:key="pref_key_use_personalized_dicts"
             android:title="@string/use_personalized_dicts"
             android:summary="@string/use_personalized_dicts_summary"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="true" />
-        <SwitchPreference
+            android:defaultValue="true"
+            android:persistent="true" />
+        <CheckBoxPreference
             android:key="pref_key_use_contacts_dict"
             android:title="@string/use_contacts_dict"
             android:summary="@string/use_contacts_dict_summary"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="true" />
-        <SwitchPreference
+            android:defaultValue="true"
+            android:persistent="true" />
+        <CheckBoxPreference
             android:key="next_word_prediction"
             android:title="@string/bigram_prediction"
             android:summary="@string/bigram_prediction_summary"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="true" />
-    </PreferenceScreen>
+            android:defaultValue="true"
+            android:persistent="true" />
+        </PreferenceScreen>
     <PreferenceScreen
         android:title="@string/settings_screen_advanced"
         android:key="screen_advanced">
@@ -211,24 +181,20 @@
             latin:maxValue="100" /> <!-- percent -->
         <!-- The settigs for showing setup wizard application icon shouldn't be persistent and
              the default value is added programmatically. -->
-        <SwitchPreference
+        <CheckBoxPreference
             android:key="pref_show_setup_wizard_icon"
             android:title="@string/show_setup_wizard_icon"
-            android:summary="@string/show_setup_wizard_icon_summary"
-            android:switchTextOn=""
-            android:switchTextOff="" />
+            android:summary="@string/show_setup_wizard_icon_summary" />
         <!-- title will be set programmatically to embed application name -->
-        <SwitchPreference
+        <CheckBoxPreference
             android:key="pref_enable_metrics_logging"
             android:summary="@string/enable_metrics_logging_summary"
-            android:switchTextOn=""
-            android:switchTextOff=""
-            android:persistent="true"
-            android:defaultValue="true" />
+            android:defaultValue="true"
+            android:persistent="true" />
         <PreferenceScreen
             android:key="screen_debug"
             android:title="Debug settings"
-            android:persistent="true"
-            android:defaultValue="false" />
-    </PreferenceScreen>
+            android:defaultValue="false"
+            android:persistent="true" />
+        </PreferenceScreen>
 </PreferenceScreen>
diff --git a/java/res/xml/prefs_for_debug.xml b/java/res/xml/prefs_for_debug.xml
index be4c8b3..ae29a8a 100644
--- a/java/res/xml/prefs_for_debug.xml
+++ b/java/res/xml/prefs_for_debug.xml
@@ -20,28 +20,22 @@
     android:title="@string/prefs_debug_mode"
     android:key="english_ime_debug_settings"
 >
-    <SwitchPreference
+    <CheckBoxPreference
         android:key="debug_mode"
         android:title="@string/prefs_debug_mode"
-        android:switchTextOn=""
-        android:switchTextOff=""
-        android:persistent="true"
-        android:defaultValue="false" />
-    <SwitchPreference
+        android:defaultValue="false"
+        android:persistent="true" />
+    <CheckBoxPreference
         android:key="force_non_distinct_multitouch"
         android:title="@string/prefs_force_non_distinct_multitouch"
-        android:switchTextOn=""
-        android:switchTextOff=""
-        android:persistent="true"
-        android:defaultValue="false" />
-    <SwitchPreference
+        android:defaultValue="false"
+        android:persistent="true" />
+    <CheckBoxPreference
         android:key="pref_sliding_key_input_preview"
         android:title="@string/sliding_key_input_preview"
         android:summary="@string/sliding_key_input_preview_summary"
-        android:switchTextOn=""
-        android:switchTextOff=""
-        android:persistent="true"
-        android:defaultValue="true" />
+        android:defaultValue="true"
+        android:persistent="true" />
     <com.android.inputmethod.latin.settings.SeekBarDialogPreference
         android:key="pref_key_longpress_timeout"
         android:title="@string/prefs_key_longpress_timeout_settings"
diff --git a/java/res/xml/spell_checker_settings.xml b/java/res/xml/spell_checker_settings.xml
index e3db485..3d95018 100644
--- a/java/res/xml/spell_checker_settings.xml
+++ b/java/res/xml/spell_checker_settings.xml
@@ -17,12 +17,10 @@
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
 >
-    <SwitchPreference
+    <CheckBoxPreference
         android:key="pref_spellcheck_use_contacts"
         android:title="@string/use_contacts_for_spellchecking_option_title"
         android:summary="@string/use_contacts_for_spellchecking_option_summary"
-        android:switchTextOn=""
-        android:switchTextOff=""
-        android:persistent="true"
-        android:defaultValue="true" />
+        android:defaultValue="true"
+        android:persistent="true" />
 </PreferenceScreen>
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 8182593..702efb3 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -451,7 +451,7 @@
 
         locatePreviewPlacerView();
         getLocationInWindow(mOriginCoords);
-        mKeyPreviewChoreographer.placeKeyPreviewAndShow(key, keyboard.mIconsSet, mKeyDrawParams,
+        mKeyPreviewChoreographer.placeAndShowKeyPreview(key, keyboard.mIconsSet, mKeyDrawParams,
                 getWidth(), mOriginCoords, mDrawingPreviewPlacerView, isHardwareAccelerated());
     }
 
@@ -554,11 +554,11 @@
             // though there may be some chances that the value is zero. <code>width == 0</code>
             // will cause zero-division error at
             // {@link MoreKeysKeyboardParams#setParameters(int,int,int,int,int,int,boolean,int)}.
-            final boolean singleMoreKeyWithPreview = mKeyPreviewDrawParams.isPopupEnabled()
+            final boolean isSingleMoreKeyWithPreview = mKeyPreviewDrawParams.isPopupEnabled()
                     && !key.noKeyPreview() && moreKeys.length == 1
                     && mKeyPreviewDrawParams.getVisibleWidth() > 0;
             final MoreKeysKeyboard.Builder builder = new MoreKeysKeyboard.Builder(
-                    context, key, getKeyboard(), singleMoreKeyWithPreview,
+                    context, key, getKeyboard(), isSingleMoreKeyWithPreview,
                     mKeyPreviewDrawParams.getVisibleWidth(),
                     mKeyPreviewDrawParams.getVisibleHeight(), newLabelPaint(key));
             moreKeysKeyboard = builder.build();
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index 353e07c..e0184d7 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -261,13 +261,13 @@
          * @param context the context of {@link MoreKeysKeyboardView}.
          * @param key the {@link Key} that invokes more keys keyboard.
          * @param keyboard the {@link Keyboard} that contains the parentKey.
-         * @param singleMoreKeyWithPreview true if the <code>key</code> has only one more key
-         *        and key popup preview is enabled.
+         * @param isSingleMoreKeyWithPreview true if the <code>key</code> has just a single
+         *        "more key" and its key popup preview is enabled.
          * @param keyPreviewDrawParams the parameter to place key preview.
-         * @param paintToMeasure the {@link Paint} object to measure a more key width
+         * @param paintToMeasure the {@link Paint} object to measure a "more key" width
          */
         public Builder(final Context context, final Key key, final Keyboard keyboard,
-                final boolean singleMoreKeyWithPreview, final int keyPreviewVisibleWidth,
+                final boolean isSingleMoreKeyWithPreview, final int keyPreviewVisibleWidth,
                 final int keyPreviewVisibleHeight, final Paint paintToMeasure) {
             super(context, new MoreKeysKeyboardParams());
             load(keyboard.mMoreKeysTemplate, keyboard.mId);
@@ -275,10 +275,11 @@
             // TODO: More keys keyboard's vertical gap is currently calculated heuristically.
             // Should revise the algorithm.
             mParams.mVerticalGap = keyboard.mVerticalGap / 2;
+            // This {@link MoreKeysKeyboard} is invoked from the <code>key</code>.
             mParentKey = key;
 
             final int keyWidth, rowHeight;
-            if (singleMoreKeyWithPreview) {
+            if (isSingleMoreKeyWithPreview) {
                 // Use pre-computed width and height if this more keys keyboard has only one key to
                 // mitigate visual flicker between key preview and more keys keyboard.
                 // Caveats for the visual assets: To achieve this effect, both the key preview
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
index 6fc300b..cd29c8d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
@@ -105,7 +105,7 @@
         mFreeKeyPreviewViews.add(keyPreviewView);
     }
 
-    public void placeKeyPreviewAndShow(final Key key, final KeyboardIconsSet iconsSet,
+    public void placeAndShowKeyPreview(final Key key, final KeyboardIconsSet iconsSet,
             final KeyDrawParams drawParams, final int keyboardViewWidth, final int[] keyboardOrigin,
             final ViewGroup placerView, final boolean withAnimation) {
         final KeyPreviewView keyPreviewView = getKeyPreviewView(key, placerView);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 8c4870d..304c450 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -485,7 +485,7 @@
     public SuggestionResults getSuggestionResults(final WordComposer composer,
             final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
             final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
-            final int sessionId, final ArrayList<SuggestedWordInfo> rawSuggestions) {
+            final int sessionId) {
         final Dictionaries dictionaries = mDictionaries;
         final SuggestionResults suggestionResults =
                 new SuggestionResults(dictionaries.mLocale, SuggestedWords.MAX_SUGGESTIONS);
@@ -499,21 +499,13 @@
                             languageWeight);
             if (null == dictionarySuggestions) continue;
             suggestionResults.addAll(dictionarySuggestions);
-            if (null != rawSuggestions) {
-                rawSuggestions.addAll(dictionarySuggestions);
+            if (null != suggestionResults.mRawSuggestions) {
+                suggestionResults.mRawSuggestions.addAll(dictionarySuggestions);
             }
         }
         return suggestionResults;
     }
 
-    public boolean isValidMainDictWord(final String word) {
-        final Dictionary mainDict = mDictionaries.getDict(Dictionary.TYPE_MAIN);
-        if (TextUtils.isEmpty(word) || mainDict == null) {
-            return false;
-        }
-        return mainDict.isValidWord(word);
-    }
-
     public boolean isValidWord(final String word, final boolean ignoreCase) {
         if (TextUtils.isEmpty(word)) {
             return false;
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 670d856..9d03e8a 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -100,30 +100,43 @@
                 ? typedWord.substring(0, typedWord.length() - trailingSingleQuotesCount)
                 : typedWord;
 
-        final ArrayList<SuggestedWordInfo> rawSuggestions;
-        if (ProductionFlag.INCLUDE_RAW_SUGGESTIONS) {
-            rawSuggestions = new ArrayList<>();
-        } else {
-            rawSuggestions = null;
-        }
         final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
                 wordComposer, prevWordsInfo, proximityInfo, blockOffensiveWords,
-                additionalFeaturesOptions, SESSION_TYPING, rawSuggestions);
+                additionalFeaturesOptions, SESSION_TYPING);
 
+        final boolean isPrediction = !wordComposer.isComposingWord();
+        final boolean shouldMakeSuggestionsAllUpperCase = wordComposer.isAllUpperCase()
+                && !wordComposer.isResumed();
         final boolean isOnlyFirstCharCapitalized =
                 wordComposer.isOrWillBeOnlyFirstCharCapitalized();
+
+        final ArrayList<SuggestedWordInfo> suggestionsContainer =
+                new ArrayList<>(suggestionResults);
+        final int suggestionsCount = suggestionsContainer.size();
+        if (isOnlyFirstCharCapitalized || shouldMakeSuggestionsAllUpperCase
+                || 0 != trailingSingleQuotesCount) {
+            for (int i = 0; i < suggestionsCount; ++i) {
+                final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
+                final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo(
+                        wordInfo, suggestionResults.mLocale, shouldMakeSuggestionsAllUpperCase,
+                        isOnlyFirstCharCapitalized, trailingSingleQuotesCount);
+                suggestionsContainer.set(i, transformedWordInfo);
+            }
+        }
+        SuggestedWordInfo.removeDups(typedWord, suggestionsContainer);
+
         // If resumed, then we don't want to upcase everything: resuming on a fully-capitalized
         // words is rarely done to switch to another fully-capitalized word, but usually to a
         // normal, non-capitalized suggestion.
-        final boolean isAllUpperCase = wordComposer.isAllUpperCase() && !wordComposer.isResumed();
         final String firstSuggestion;
         final String whitelistedWord;
         if (suggestionResults.isEmpty()) {
             whitelistedWord = firstSuggestion = null;
         } else {
             final SuggestedWordInfo firstSuggestedWordInfo = getTransformedSuggestedWordInfo(
-                    suggestionResults.first(), suggestionResults.mLocale, isAllUpperCase,
-                    isOnlyFirstCharCapitalized, trailingSingleQuotesCount);
+                    suggestionResults.first(), suggestionResults.mLocale,
+                    shouldMakeSuggestionsAllUpperCase, isOnlyFirstCharCapitalized,
+                    trailingSingleQuotesCount);
             firstSuggestion = firstSuggestedWordInfo.mWord;
             if (!firstSuggestedWordInfo.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) {
                 whitelistedWord = null;
@@ -132,8 +145,6 @@
             }
         }
 
-        final boolean isPrediction = !wordComposer.isComposingWord();
-
         // We allow auto-correction if we have a whitelisted word, or if the word is not a valid
         // word of more than 1 char, except if the first suggestion is the same as the typed string
         // because in this case if it's strong enough to auto-correct that will mistakenly designate
@@ -171,19 +182,6 @@
                     suggestionResults.first(), consideredWord, mAutoCorrectionThreshold);
         }
 
-        final ArrayList<SuggestedWordInfo> suggestionsContainer =
-                new ArrayList<>(suggestionResults);
-        final int suggestionsCount = suggestionsContainer.size();
-        if (isOnlyFirstCharCapitalized || isAllUpperCase || 0 != trailingSingleQuotesCount) {
-            for (int i = 0; i < suggestionsCount; ++i) {
-                final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
-                final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo(
-                        wordInfo, suggestionResults.mLocale, isAllUpperCase,
-                        isOnlyFirstCharCapitalized, trailingSingleQuotesCount);
-                suggestionsContainer.set(i, transformedWordInfo);
-            }
-        }
-
         if (!TextUtils.isEmpty(typedWord)) {
             suggestionsContainer.add(0, new SuggestedWordInfo(typedWord,
                     SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED,
@@ -191,7 +189,6 @@
                     SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
                     SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
         }
-        SuggestedWordInfo.removeDups(suggestionsContainer);
 
         final ArrayList<SuggestedWordInfo> suggestionsList;
         if (DBG && !suggestionsContainer.isEmpty()) {
@@ -200,12 +197,13 @@
             suggestionsList = suggestionsContainer;
         }
 
-        callback.onGetSuggestedWords(new SuggestedWords(suggestionsList, rawSuggestions,
+        callback.onGetSuggestedWords(new SuggestedWords(suggestionsList,
+                suggestionResults.mRawSuggestions,
                 // TODO: this first argument is lying. If this is a whitelisted word which is an
                 // actual word, it says typedWordValid = false, which looks wrong. We should either
                 // rename the attribute or change the value.
                 !isPrediction && !allowsToBeAutoCorrected /* typedWordValid */,
-                hasAutoCorrection, /* willAutoCorrect */
+                hasAutoCorrection /* willAutoCorrect */,
                 false /* isObsoleteSuggestions */, isPrediction, sequenceNumber));
     }
 
@@ -216,15 +214,9 @@
             final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
             final int sessionId, final int sequenceNumber,
             final OnGetSuggestedWordsCallback callback) {
-        final ArrayList<SuggestedWordInfo> rawSuggestions;
-        if (ProductionFlag.INCLUDE_RAW_SUGGESTIONS) {
-            rawSuggestions = new ArrayList<>();
-        } else {
-            rawSuggestions = null;
-        }
         final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
                 wordComposer, prevWordsInfo, proximityInfo, blockOffensiveWords,
-                additionalFeaturesOptions, sessionId, rawSuggestions);
+                additionalFeaturesOptions, sessionId);
         final ArrayList<SuggestedWordInfo> suggestionsContainer =
                 new ArrayList<>(suggestionResults);
         final int suggestionsCount = suggestionsContainer.size();
@@ -245,7 +237,7 @@
             final SuggestedWordInfo rejected = suggestionsContainer.remove(0);
             suggestionsContainer.add(1, rejected);
         }
-        SuggestedWordInfo.removeDups(suggestionsContainer);
+        SuggestedWordInfo.removeDups(null /* typedWord */, suggestionsContainer);
 
         // For some reason some suggestions with MIN_VALUE are making their way here.
         // TODO: Find a more robust way to detect distractors.
@@ -257,7 +249,8 @@
 
         // In the batch input mode, the most relevant suggested word should act as a "typed word"
         // (typedWordValid=true), not as an "auto correct word" (willAutoCorrect=false).
-        callback.onGetSuggestedWords(new SuggestedWords(suggestionsContainer, rawSuggestions,
+        callback.onGetSuggestedWords(new SuggestedWords(suggestionsContainer,
+                suggestionResults.mRawSuggestions,
                 true /* typedWordValid */,
                 false /* willAutoCorrect */,
                 false /* isObsoleteSuggestions */,
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 72461e1..8e78e97 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -316,10 +316,6 @@
             return mDebugString;
         }
 
-        public int codePointCount() {
-            return mCodePointCount;
-        }
-
         public int codePointAt(int i) {
             return mWord.codePointAt(i);
         }
@@ -333,23 +329,28 @@
             }
         }
 
-        // TODO: Consolidate this method and StringUtils.removeDupes() in the future.
-        public static void removeDups(ArrayList<SuggestedWordInfo> candidates) {
-            if (candidates.size() <= 1) {
+        // This will always remove the higher index if a duplicate is found.
+        public static void removeDups(final String typedWord,
+                ArrayList<SuggestedWordInfo> candidates) {
+            if (candidates.isEmpty()) {
                 return;
             }
-            int i = 1;
-            while (i < candidates.size()) {
-                final SuggestedWordInfo cur = candidates.get(i);
-                for (int j = 0; j < i; ++j) {
-                    final SuggestedWordInfo previous = candidates.get(j);
-                    if (cur.mWord.equals(previous.mWord)) {
-                        candidates.remove(cur.mScore < previous.mScore ? i : j);
-                        --i;
-                        break;
-                    }
+            if (!TextUtils.isEmpty(typedWord)) {
+                removeSuggestedWordInfoFrom(typedWord, candidates, 0);
+            }
+            for (int i = 0; i < candidates.size(); ++i) {
+                removeSuggestedWordInfoFrom(candidates.get(i).mWord, candidates, i);
+            }
+        }
+
+        private static void removeSuggestedWordInfoFrom(final String word,
+                final ArrayList<SuggestedWordInfo> candidates, final int startIndex) {
+            for (int i = startIndex + 1; i < candidates.size(); ++i) {
+                final SuggestedWordInfo previous = candidates.get(i);
+                if (word.equals(previous.mWord)) {
+                    candidates.remove(i);
+                    --i;
                 }
-                ++i;
             }
         }
     }
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 9462c38..faa5582 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -733,8 +733,7 @@
 
             sendKeyCodePoint(settingsValues, codePoint);
 
-            if (swapWeakSpace) {
-                swapSwapperAndSpace(inputTransaction);
+            if (swapWeakSpace && swapSwapperAndSpace(inputTransaction)) {
                 mSpaceState = SpaceState.WEAK;
             }
             // In case the "add to dictionary" hint was still displayed.
@@ -810,8 +809,6 @@
 
         if (Constants.CODE_SPACE == codePoint) {
             if (maybeDoubleSpacePeriod(inputTransaction)) {
-                inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
-                inputTransaction.setRequiresUpdateSuggestions();
                 mSpaceState = SpaceState.DOUBLE;
             } else if (!mSuggestedWords.isPunctuationSuggestions()) {
                 mSpaceState = SpaceState.WEAK;
@@ -823,8 +820,9 @@
             }
         } else {
             if (swapWeakSpace) {
-                swapSwapperAndSpace(inputTransaction);
-                mSpaceState = SpaceState.SWAP_PUNCTUATION;
+                if (swapSwapperAndSpace(inputTransaction)) {
+                    mSpaceState = SpaceState.SWAP_PUNCTUATION;
+                }
             } else if ((SpaceState.PHANTOM == inputTransaction.mSpaceState
                     && settingsValues.isUsuallyFollowedBySpace(codePoint))
                     || (Constants.CODE_DOUBLE_QUOTE == codePoint
@@ -1008,8 +1006,9 @@
      * This method will check that there are two characters before the cursor and that the first
      * one is a space before it does the actual swapping.
      * @param inputTransaction The transaction in progress.
+     * @return true if the swap has been performed, false if it was prevented by preliminary checks.
      */
-    private void swapSwapperAndSpace(final InputTransaction inputTransaction) {
+    private boolean swapSwapperAndSpace(final InputTransaction inputTransaction) {
         final CharSequence lastTwo = mConnection.getTextBeforeCursor(2, 0);
         // It is guaranteed lastTwo.charAt(1) is a swapper - else this method is not called.
         if (lastTwo != null && lastTwo.length() == 2 && lastTwo.charAt(0) == Constants.CODE_SPACE) {
@@ -1017,7 +1016,9 @@
             final String text = lastTwo.charAt(1) + " ";
             mConnection.commitText(text, 1);
             inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
+            return true;
         }
+        return false;
     }
 
     /*
@@ -1078,6 +1079,8 @@
      */
     private boolean maybeDoubleSpacePeriod(final InputTransaction inputTransaction) {
         if (!inputTransaction.mSettingsValues.mUseDoubleSpacePeriod) return false;
+        // This can't happen right now because we don't call this method when the code is not space
+        if (Constants.CODE_SPACE != inputTransaction.mEvent.mCodePoint) return false;
         if (!isDoubleSpacePeriodCountdownActive(inputTransaction)) return false;
         // We only do this when we see two spaces and an accepted code point before the cursor.
         // The code point may be a surrogate pair but the two spaces may not, so we need 4 chars.
@@ -1099,6 +1102,8 @@
             final String textToInsert = inputTransaction.mSettingsValues.mSpacingAndPunctuations
                     .mSentenceSeparatorAndSpace;
             mConnection.commitText(textToInsert, 1);
+            inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
+            inputTransaction.setRequiresUpdateSuggestions();
             return true;
         }
         return false;
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index 9d82412..689f878 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -126,9 +126,17 @@
 
         final PreferenceScreen inputScreen =
                 (PreferenceScreen) findPreference(Settings.SCREEN_INPUT);
+        final PreferenceScreen multiLingualScreen =
+                (PreferenceScreen) findPreference(Settings.SCREEN_MULTI_LINGUAL);
+        final PreferenceScreen gestureScreen =
+                (PreferenceScreen) findPreference(Settings.SCREEN_GESTURE);
+        final PreferenceScreen correctionScreen =
+                (PreferenceScreen) findPreference(Settings.SCREEN_CORRECTION);
         final PreferenceScreen advancedScreen =
                 (PreferenceScreen) findPreference(Settings.SCREEN_ADVANCED);
-        final Preference debugScreen = findPreference(Settings.SCREEN_DEBUG);
+        final PreferenceScreen debugScreen =
+                (PreferenceScreen) findPreference(Settings.SCREEN_DEBUG);
+
         if (Settings.isInternal(prefs)) {
             final Intent debugSettingsIntent = new Intent(Intent.ACTION_MAIN);
             debugSettingsIntent.setClassName(
@@ -149,8 +157,6 @@
             removePreference(Settings.PREF_VIBRATION_DURATION_SETTINGS, advancedScreen);
         }
         if (!Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS) {
-            final PreferenceScreen multiLingualScreen =
-                    (PreferenceScreen) findPreference(Settings.SCREEN_MULTI_LINGUAL);
             removePreference(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY, multiLingualScreen);
             removePreference(
                     Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, multiLingualScreen);
@@ -185,8 +191,6 @@
             removePreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON, advancedScreen);
         }
 
-        final PreferenceScreen correctionScreen =
-                (PreferenceScreen) findPreference(Settings.SCREEN_CORRECTION);
         final PreferenceScreen dictionaryLink =
                 (PreferenceScreen) findPreference(Settings.PREF_CONFIGURE_DICTIONARIES_KEY);
         final Intent intent = dictionaryLink.getIntent();
@@ -221,7 +225,7 @@
         }
 
         if (!Settings.readFromBuildConfigIfGestureInputEnabled(res)) {
-            removePreference(Settings.SCREEN_GESTURE, getPreferenceScreen());
+            getPreferenceScreen().removePreference(gestureScreen);
         }
 
         AdditionalFeaturesSettingUtils.addAdditionalFeaturesPreferences(context, this);
@@ -462,13 +466,14 @@
 
     @Override
     public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
-        if (!FeedbackUtils.isFeedbackFormSupported()) {
-            return;
+        if (FeedbackUtils.isFeedbackFormSupported()) {
+            menu.add(NO_MENU_GROUP, MENU_FEEDBACK /* itemId */, MENU_FEEDBACK /* order */,
+                    R.string.send_feedback);
         }
-        menu.add(NO_MENU_GROUP, MENU_FEEDBACK /* itemId */, MENU_FEEDBACK /* order */,
-                R.string.send_feedback);
-        menu.add(NO_MENU_GROUP, MENU_ABOUT /* itemId */, MENU_ABOUT /* order */,
-                FeedbackUtils.getAboutKeyboardTitleResId());
+        final int aboutResId = FeedbackUtils.getAboutKeyboardTitleResId();
+        if (aboutResId != 0) {
+            menu.add(NO_MENU_GROUP, MENU_ABOUT /* itemId */, MENU_ABOUT /* order */, aboutResId);
+        }
     }
 
     @Override
@@ -479,8 +484,11 @@
             return true;
         }
         if (itemId == MENU_ABOUT) {
-            startActivity(FeedbackUtils.getAboutKeyboardIntent(getActivity()));
-            return true;
+            final Intent aboutIntent = FeedbackUtils.getAboutKeyboardIntent(getActivity());
+            if (aboutIntent != null) {
+                startActivity(aboutIntent);
+                return true;
+            }
         }
         return super.onOptionsItemSelected(item);
     }
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 46f5cde..ad5aad7 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -49,6 +49,7 @@
 import com.android.inputmethod.latin.PunctuationSuggestions;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
 import com.android.inputmethod.latin.utils.ResourceUtils;
 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
@@ -250,8 +251,8 @@
         final int positionInStrip =
                 getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords);
         // Use identity for strings, not #equals : it's the typed word if it's the same object
-        final boolean isTypedWord =
-                suggestedWords.getWord(indexInSuggestedWords) == suggestedWords.mTypedWord;
+        final boolean isTypedWord = suggestedWords.getInfo(indexInSuggestedWords).isKindOf(
+                SuggestedWordInfo.KIND_TYPED);
 
         final int color;
         if (positionInStrip == mCenterPositionInStrip && suggestedWords.mWillAutoCorrect) {
diff --git a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
index 0b362c4..5c109a6 100644
--- a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
+++ b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
@@ -17,7 +17,9 @@
 package com.android.inputmethod.latin.utils;
 
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.define.ProductionFlag;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.Locale;
@@ -29,6 +31,7 @@
  */
 public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
     public final Locale mLocale;
+    public final ArrayList<SuggestedWordInfo> mRawSuggestions;
     private final int mCapacity;
 
     public SuggestionResults(final Locale locale, final int capacity) {
@@ -40,6 +43,11 @@
         super(comparator);
         mLocale = locale;
         mCapacity = capacity;
+        if (ProductionFlag.INCLUDE_RAW_SUGGESTIONS) {
+            mRawSuggestions = new ArrayList<>();
+        } else {
+            mRawSuggestions = null;
+        }
     }
 
     @Override
diff --git a/tests/src/com/android/inputmethod/latin/ShiftModeTests.java b/tests/src/com/android/inputmethod/latin/ShiftModeTests.java
index a319ffd..db3c9ba 100644
--- a/tests/src/com/android/inputmethod/latin/ShiftModeTests.java
+++ b/tests/src/com/android/inputmethod/latin/ShiftModeTests.java
@@ -111,24 +111,16 @@
         assertTrue("(Spanish) Auto caps after inverted bang", isCapsModeAutoShifted());
     }
 
-    public void DISABLED_testOtherSentenceSeparators() {
-        // We only run this test on Kitkat+ because previous versions of Android don't
-        // have an Armenian locale. For some reason I don't know, when the requested
-        // locale is not present as a device locale, then the application under test can't
-        // access the resources in that locale -- though it works when the app is actually
-        // running on the device and not under test. If we ever figure out what's going
-        // on, remove this test.
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            changeLanguage("hy-AM");
-            assertTrue("(Armenian) Auto caps at start", isCapsModeAutoShifted());
-            type("Hey. ");
-            assertFalse("(Armenian) No auto-caps after latin period", isCapsModeAutoShifted());
-            type("Hey\u0589");
-            assertFalse("(Armenian) No auto-caps directly after armenian period",
-                    isCapsModeAutoShifted());
-            type(" ");
-            assertTrue("(Armenian) Auto-caps after armenian period-whitespace",
-                    isCapsModeAutoShifted());
-        }
+    public void testOtherSentenceSeparators() {
+        changeLanguage("hy_AM");
+        assertTrue("(Armenian) Auto caps at start", isCapsModeAutoShifted());
+        type("Hey. ");
+        assertFalse("(Armenian) No auto-caps after latin period", isCapsModeAutoShifted());
+        type("Hey\u0589");
+        assertFalse("(Armenian) No auto-caps directly after armenian period",
+                isCapsModeAutoShifted());
+        type(" ");
+        assertTrue("(Armenian) Auto-caps after armenian period-whitespace",
+                isCapsModeAutoShifted());
     }
 }
diff --git a/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java
index 020d632..c746c83 100644
--- a/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java
@@ -22,6 +22,7 @@
 import android.text.TextUtils;
 
 import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
+import com.android.inputmethod.latin.utils.LocaleUtils;
 
 import java.util.Locale;
 
@@ -109,5 +110,19 @@
         allPathsForCaps("Liebe Sara,  \n  ", c | w | s, sp, false);
         allPathsForCaps("Liebe Sara  \n  ", c | w | s, sp, false);
         allPathsForCaps("Liebe Sara.\n  ", c | w | s, sp, false);
+
+        // Test armenian period
+        sp = job.runInLocale(res, LocaleUtils.constructLocaleFromString("hy_AM"));
+        assertTrue("Period is not sentence separator in Armenian",
+                !sp.isSentenceSeparator('.'));
+        assertTrue("Sentence separator is Armenian period in Armenian",
+                sp.isSentenceSeparator(0x589));
+        // No space : capitalize only if MODE_CHARACTERS
+        allPathsForCaps("Word", c, sp, false);
+        allPathsForCaps("Word.", c, sp, false);
+        // Space, but no armenian period : capitalize if MODE_WORDS but not SENTENCES
+        allPathsForCaps("Word. ", c | w, sp, false);
+        // Armenian period : capitalize if MODE_SENTENCES
+        allPathsForCaps("Word\u0589 ", c | w | s, sp, false);
     }
 }