diff --git a/java/res/values-ar/donottranslate.xml b/java/res/values-ar/donottranslate.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c51ac502a13818e250e05cb22133c35fcb2773b5
--- /dev/null
+++ b/java/res/values-ar/donottranslate.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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">
+    <!-- The all letters need to be mirrored are found at
+         http://www.unicode.org/Public/6.0.0/ucd/extracted/DerivedBinaryProperties.txt -->
+    <!-- Symbols that are suggested between words -->
+    <string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(|),)|(,\u0027,-,/,@,_</string>
+</resources>
diff --git a/java/res/values-iw/donottranslate.xml b/java/res/values-iw/donottranslate.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c51ac502a13818e250e05cb22133c35fcb2773b5
--- /dev/null
+++ b/java/res/values-iw/donottranslate.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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">
+    <!-- The all letters need to be mirrored are found at
+         http://www.unicode.org/Public/6.0.0/ucd/extracted/DerivedBinaryProperties.txt -->
+    <!-- Symbols that are suggested between words -->
+    <string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(|),)|(,\u0027,-,/,@,_</string>
+</resources>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 8bd25c00d3ebaa149a66b434786f53359e875e82..cd5e3d8ea8541af0fb0eb3a46e4b52df1c707eb2 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -19,7 +19,7 @@
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Symbols that are suggested between words -->
-    <string name="suggested_punctuations">!?,:;\u0022()\u0027-/@_</string>
+    <string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(,),\u0027,-,/,@,_</string>
     <!-- Symbols that should be swapped with a magic space -->
     <string name="magic_space_swapping_symbols">.,;:!?)]}\u0022</string>
     <!-- Symbols that should strip a magic space -->
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
index 1450192b25f4d5a082e6fe2b0ebffcf987f78910..25a2c23c4e0b41fcb2b07bf0713fa30ef1c32722 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
@@ -16,7 +16,6 @@
 
 package com.android.inputmethod.keyboard.internal;
 
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.util.Log;
 
@@ -28,7 +27,6 @@ import com.android.inputmethod.latin.XmlParseUtils;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 
 public class KeyStyles {
@@ -74,63 +72,8 @@ public class KeyStyles {
         protected static String[] parseStringArray(TypedArray a, int index) {
             if (!a.hasValue(index))
                 return null;
-            return parseCsvString(a.getString(index), a.getResources(), R.string.english_ime_name);
-        }
-    }
-
-    /* package for test */
-    static String[] parseCsvString(String rawText, Resources res, int packageNameResId) {
-        final String text = Utils.resolveStringResource(rawText, res, packageNameResId);
-        final int size = text.length();
-        if (size == 0) {
-            return null;
-        }
-        if (size == 1) {
-            return new String[] { text };
-        }
-
-        final StringBuilder sb = new StringBuilder();
-        ArrayList<String> list = null;
-        int start = 0;
-        for (int pos = 0; pos < size; pos++) {
-            final char c = text.charAt(pos);
-            if (c == ',') {
-                if (list == null) {
-                    list = new ArrayList<String>();
-                }
-                if (sb.length() == 0) {
-                    list.add(text.substring(start, pos));
-                } else {
-                    list.add(sb.toString());
-                    sb.setLength(0);
-                }
-                start = pos + 1;
-                continue;
-            } else if (c == Utils.ESCAPE_CHAR) {
-                if (start == pos) {
-                    // Skip escape character at the beginning of the value.
-                    start++;
-                    pos++;
-                } else {
-                    if (start < pos && sb.length() == 0) {
-                        sb.append(text.subSequence(start, pos));
-                    }
-                    pos++;
-                    if (pos < size) {
-                        sb.append(text.charAt(pos));
-                    }
-                }
-            } else if (sb.length() > 0) {
-                sb.append(c);
-            }
-        }
-        if (list == null) {
-            return new String[] {
-                    sb.length() > 0 ? sb.toString() : text.substring(start)
-            };
-        } else {
-            list.add(sb.length() > 0 ? sb.toString() : text.substring(start));
-            return list.toArray(new String[list.size()]);
+            return Utils.parseCsvString(
+                    a.getString(index), a.getResources(), R.string.english_ime_name);
         }
     }
 
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index ef8fd13790a952c4614861c9f86f580afea34a40..19cd16ad2ed9d16b291d033f471b34eccf6b53ea 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -59,7 +59,6 @@ import com.android.inputmethod.compat.SuggestionSpanUtils;
 import com.android.inputmethod.compat.VibratorCompatWrapper;
 import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
 import com.android.inputmethod.deprecated.VoiceProxy;
-import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardActionListener;
 import com.android.inputmethod.keyboard.KeyboardId;
@@ -1897,16 +1896,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
             // So, LatinImeLogger logs "" as a user's input.
             LatinImeLogger.logOnManualSuggestion(
                     "", suggestion.toString(), index, suggestions.mWords);
+            final CharSequence outputText = mSettingsValues.mSuggestPuncOutputTextList
+                    .getWord(index);
+            final int primaryCode = outputText.charAt(0);
             // Find out whether the previous character is a space. If it is, as a special case
             // for punctuation entered through the suggestion strip, it should be swapped
             // if it was a magic or a weak space. This is meant to help in case the user
             // pressed space on purpose of displaying the suggestion strip punctuation.
-            final int rawPrimaryCode = suggestion.charAt(0);
-            // Maybe apply the "bidi mirrored" conversions for parentheses
-            final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
-            final boolean isRtl = keyboard != null && keyboard.mIsRtlKeyboard;
-            final int primaryCode = Key.getRtlParenthesisCode(rawPrimaryCode, isRtl);
-
             insertPunctuationFromSuggestionStrip(ic, primaryCode);
             // TODO: the following endBatchEdit seems useless, check
             if (ic != null) {
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index e6ef3962e8828e01097e3e015894b559d3761d48..5f9cb8df6a9f6bd6a39a2931019ef051a2383cef 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -25,6 +25,7 @@ import android.view.inputmethod.EditorInfo;
 
 import com.android.inputmethod.compat.InputTypeCompatUtils;
 import com.android.inputmethod.compat.VibratorCompatWrapper;
+import com.android.inputmethod.keyboard.internal.MoreKeySpecParser;
 
 import java.util.Arrays;
 import java.util.Locale;
@@ -36,8 +37,9 @@ public class SettingsValues {
     public final int mDelayUpdateOldSuggestions;
     public final String mMagicSpaceStrippers;
     public final String mMagicSpaceSwappers;
-    public final String mSuggestPuncs;
+    private final String mSuggestPuncs;
     public final SuggestedWords mSuggestPuncList;
+    public final SuggestedWords mSuggestPuncOutputTextList;
     private final String mSymbolsExcludedFromWordSeparators;
     public final String mWordSeparators;
     public final CharSequence mHintToSaveText;
@@ -98,9 +100,11 @@ public class SettingsValues {
                 }
             }
         }
-        mSuggestPuncs = res.getString(R.string.suggested_punctuations);
-        // TODO: it would be nice not to recreate this each time we change the configuration
-        mSuggestPuncList = createSuggestPuncList(mSuggestPuncs);
+        final String[] suggestPuncsSpec = Utils.parseCsvString(
+                res.getString(R.string.suggested_punctuations), res, R.string.english_ime_name);
+        mSuggestPuncs = createSuggestPuncs(suggestPuncsSpec);
+        mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
+        mSuggestPuncOutputTextList = createSuggestPuncOutputTextList(suggestPuncsSpec);
         mSymbolsExcludedFromWordSeparators =
                 res.getString(R.string.symbols_excluded_from_word_separators);
         mWordSeparators = createWordSeparators(mMagicSpaceStrippers, mMagicSpaceSwappers,
@@ -150,11 +154,36 @@ public class SettingsValues {
     }
 
     // Helper functions to create member values.
-    private static SuggestedWords createSuggestPuncList(final String puncs) {
-        SuggestedWords.Builder builder = new SuggestedWords.Builder();
+    private static String createSuggestPuncs(final String[] puncs) {
+        final StringBuilder sb = new StringBuilder();
         if (puncs != null) {
-            for (int i = 0; i < puncs.length(); i++) {
-                builder.addWord(puncs.subSequence(i, i + 1));
+            for (final String puncSpec : puncs) {
+                sb.append(MoreKeySpecParser.getLabel(puncSpec));
+            }
+        }
+        return sb.toString();
+    }
+
+    private static SuggestedWords createSuggestPuncList(final String[] puncs) {
+        final SuggestedWords.Builder builder = new SuggestedWords.Builder();
+        if (puncs != null) {
+            for (final String puncSpec : puncs) {
+                builder.addWord(MoreKeySpecParser.getLabel(puncSpec));
+            }
+        }
+        return builder.setIsPunctuationSuggestions().build();
+    }
+
+    private static SuggestedWords createSuggestPuncOutputTextList(final String[] puncs) {
+        final SuggestedWords.Builder builder = new SuggestedWords.Builder();
+        if (puncs != null) {
+            for (final String puncSpec : puncs) {
+                final String outputText = MoreKeySpecParser.getOutputText(puncSpec);
+                if (outputText != null) {
+                    builder.addWord(outputText);
+                } else {
+                    builder.addWord(MoreKeySpecParser.getLabel(puncSpec));
+                }
             }
         }
         return builder.setIsPunctuationSuggestions().build();
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index a70808741d2e41226a5f412a348bc4cd3cb56d31..d1b808fc876c500efb570b2dc407a069d22f2cae 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -857,4 +857,59 @@ public class Utils {
         }
         return size;
     }
+
+    public static String[] parseCsvString(String rawText, Resources res, int packageNameResId) {
+        final String text = resolveStringResource(rawText, res, packageNameResId);
+        final int size = text.length();
+        if (size == 0) {
+            return null;
+        }
+        if (size == 1) {
+            return new String[] { text };
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        ArrayList<String> list = null;
+        int start = 0;
+        for (int pos = 0; pos < size; pos++) {
+            final char c = text.charAt(pos);
+            if (c == ',') {
+                if (list == null) {
+                    list = new ArrayList<String>();
+                }
+                if (sb.length() == 0) {
+                    list.add(text.substring(start, pos));
+                } else {
+                    list.add(sb.toString());
+                    sb.setLength(0);
+                }
+                start = pos + 1;
+                continue;
+            } else if (c == ESCAPE_CHAR) {
+                if (start == pos) {
+                    // Skip escape character at the beginning of the value.
+                    start++;
+                    pos++;
+                } else {
+                    if (start < pos && sb.length() == 0) {
+                        sb.append(text.subSequence(start, pos));
+                    }
+                    pos++;
+                    if (pos < size) {
+                        sb.append(text.charAt(pos));
+                    }
+                }
+            } else if (sb.length() > 0) {
+                sb.append(c);
+            }
+        }
+        if (list == null) {
+            return new String[] {
+                    sb.length() > 0 ? sb.toString() : text.substring(start)
+            };
+        } else {
+            list.add(sb.length() > 0 ? sb.toString() : text.substring(start));
+            return list.toArray(new String[list.size()]);
+        }
+    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyStylesTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyStylesTests.java
index 2ae8027af735c430100c2f665aef5650600a4a01..54a8e6246a42e05c82fa13b2b6f59760f112c465 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyStylesTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyStylesTests.java
@@ -20,6 +20,7 @@ import android.content.res.Resources;
 import android.test.AndroidTestCase;
 import android.text.TextUtils;
 
+import com.android.inputmethod.latin.Utils;
 import com.android.inputmethod.latin.tests.R;
 
 import java.util.Arrays;
@@ -39,7 +40,7 @@ public class KeyStylesTests extends AndroidTestCase {
     }
 
     private void assertTextArray(String message, String value, String ... expected) {
-        final String actual[] = KeyStyles.parseCsvString(value, mTestResources,
+        final String actual[] = Utils.parseCsvString(value, mTestResources,
                 R.string.empty_string);
         if (expected.length == 0) {
             assertNull(message, actual);