diff --git a/res/drawable-hdpi/keyboard_suggest_strip_divider.png b/res/drawable-hdpi/keyboard_suggest_strip_divider.png
old mode 100755
new mode 100644
index 1a03c52e64df4681aacb8bf1c15cb741eaf0b568..a5980388a979b9348d43a7c9e8b97b312c0fa00e
Binary files a/res/drawable-hdpi/keyboard_suggest_strip_divider.png and b/res/drawable-hdpi/keyboard_suggest_strip_divider.png differ
diff --git a/res/layout/candidates.xml b/res/layout/candidates.xml
index 3af967fd20873ea20ca124bb59dc89f5fd3cadeb..068c17e56b3d62fad5f500ef357c61257161a08d 100755
--- a/res/layout/candidates.xml
+++ b/res/layout/candidates.xml
@@ -22,7 +22,7 @@
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="horizontal"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_height="@dimen/candidate_strip_height"
         android:background="@drawable/keyboard_suggest_strip"
         >
 
@@ -76,4 +76,4 @@
             />
     </LinearLayout>        
     
-</com.android.inputmethod.latin.CandidateViewContainer>
\ No newline at end of file
+</com.android.inputmethod.latin.CandidateViewContainer>
diff --git a/res/values/donottranslate.xml b/res/values/donottranslate.xml
index b9cfbd135990a86c465381f0d26d0d1e43f652a2..edf230061de7df1cd4f44f1318925c0b57195ee1 100644
--- a/res/values/donottranslate.xml
+++ b/res/values/donottranslate.xml
@@ -22,6 +22,8 @@
     <string name="word_separators">.\u0020,;:!?\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string>
     <!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. -->
     <string name="sentence_separators">.,!?</string>
+    <!-- Symbols that are suggested between words -->
+    <string name="suggested_punctuations">!?,@_</string>
     <!-- Accented characters related to "d" -->
     <string name="alternates_for_d"></string>
     <!-- Accented characters related to "r" -->
diff --git a/src/com/android/inputmethod/latin/CandidateView.java b/src/com/android/inputmethod/latin/CandidateView.java
index e6a9d6bbf02abad4590e3cf00b3ecc0924c40652..0b6b89e6bc385d716a8b39cab0882fbcc8f13f31 100755
--- a/src/com/android/inputmethod/latin/CandidateView.java
+++ b/src/com/android/inputmethod/latin/CandidateView.java
@@ -26,6 +26,7 @@ import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.Typeface;
+import android.graphics.Paint.Align;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Message;
@@ -82,7 +83,9 @@ public class CandidateView extends View {
     private int mDescent;
     private boolean mScrolled;
     private int mTargetScrollX;
-    
+
+    private int mMinTouchableWidth;
+
     private int mTotalWidth;
     
     private GestureDetector mGestureDetector;
@@ -133,7 +136,10 @@ public class CandidateView extends View {
         mPaint.setAntiAlias(true);
         mPaint.setTextSize(mPreviewText.getTextSize());
         mPaint.setStrokeWidth(0);
+        mPaint.setTextAlign(Align.CENTER);
         mDescent = (int) mPaint.descent();
+        // 80 pixels for a 160dpi device would mean half an inch
+        mMinTouchableWidth = (int) (getResources().getDisplayMetrics().density * 50);
         
         mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
             @Override
@@ -203,7 +209,7 @@ public class CandidateView extends View {
             if (getBackground() != null) {
                 getBackground().getPadding(mBgPadding);
             }
-            mDivider.setBounds(0, mBgPadding.top, mDivider.getIntrinsicWidth(), 
+            mDivider.setBounds(0, 0, mDivider.getIntrinsicWidth(),
                     mDivider.getIntrinsicHeight());
         }
         int x = 0;
@@ -233,7 +239,7 @@ public class CandidateView extends View {
                 wordWidth = mWordWidth[i];
             } else {
                 float textWidth =  paint.measureText(suggestion, 0, suggestion.length());
-                wordWidth = (int) textWidth + X_GAP * 2;
+                wordWidth = Math.max(mMinTouchableWidth, (int) textWidth + X_GAP * 2);
                 mWordWidth[i] = wordWidth;
             }
 
@@ -253,7 +259,7 @@ public class CandidateView extends View {
             }
 
             if (canvas != null) {
-                canvas.drawText(suggestion, 0, suggestion.length(), x + X_GAP, y, paint);
+                canvas.drawText(suggestion, 0, suggestion.length(), x + wordWidth / 2, y, paint);
                 paint.setColor(mColorOther);
                 canvas.translate(x + wordWidth, 0);
                 mDivider.draw(canvas);
@@ -462,7 +468,8 @@ public class CandidateView extends View {
                         + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight();
                 final int popupHeight = mPreviewText.getMeasuredHeight();
                 //mPreviewText.setVisibility(INVISIBLE);
-                mPopupPreviewX = mWordX[wordIndex] - mPreviewText.getPaddingLeft() - getScrollX();
+                mPopupPreviewX = mWordX[wordIndex] - mPreviewText.getPaddingLeft() - getScrollX()
+                        + (mWordWidth[wordIndex] - wordWidth) / 2;
                 mPopupPreviewY = - popupHeight;
                 mHandler.removeMessages(MSG_REMOVE_PREVIEW);
                 int [] offsetInWindow = new int[2];
@@ -488,6 +495,7 @@ public class CandidateView extends View {
     
     private void longPressFirstWord() {
         CharSequence word = mSuggestions.get(0);
+        if (word.length() < 2) return;
         if (mService.addWordToDictionary(word.toString())) {
             showPreview(0, getContext().getResources().getString(R.string.added_word, word));
         }
diff --git a/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/src/com/android/inputmethod/latin/KeyboardSwitcher.java
index 0ebfe4a9ab7afd60bb8065da7753d8bc2a3b9004..529edeb817caab9cdcaeab448e5215811a6c6d3a 100644
--- a/src/com/android/inputmethod/latin/KeyboardSwitcher.java
+++ b/src/com/android/inputmethod/latin/KeyboardSwitcher.java
@@ -159,7 +159,6 @@ public class KeyboardSwitcher {
 
     void setVoiceMode(boolean enableVoice, boolean voiceOnPrimary) {
         if (enableVoice != mHasVoice || voiceOnPrimary != mVoiceOnPrimary) {
-            System.err.println("Clearing keyboards");
             mKeyboards.clear();
         }
         mHasVoice = enableVoice;
diff --git a/src/com/android/inputmethod/latin/LatinIME.java b/src/com/android/inputmethod/latin/LatinIME.java
index ee525b495283a9af324c1fd87c3e344eae28d681..9924561832ff3e55065ac187c65595121d1c5a35 100644
--- a/src/com/android/inputmethod/latin/LatinIME.java
+++ b/src/com/android/inputmethod/latin/LatinIME.java
@@ -215,6 +215,7 @@ public class LatinIME extends InputMethodService
     private boolean mEnableVoice = true;
     private boolean mVoiceOnPrimary;
     private int     mOrientation;
+    private List<CharSequence> mSuggestPuncList;
 
     // Indicates whether the suggestion strip is to be on in landscape
     private boolean mJustAccepted;
@@ -296,6 +297,7 @@ public class LatinIME extends InputMethodService
         }
         initSuggest(inputLanguage);
         mOrientation = conf.orientation;
+        initSuggestPuncList();
 
         mVibrateDuration = mResources.getInteger(R.integer.vibrate_duration_ms);
 
@@ -1337,7 +1339,7 @@ public class LatinIME extends InputMethodService
         }
 
         if (!mPredicting) {
-            setSuggestions(null, false, false, false);
+            setNextSuggestions();
             return;
         }
 
@@ -1397,6 +1399,12 @@ public class LatinIME extends InputMethodService
             updateShiftKeyState(getCurrentInputEditorInfo());
             return;
         }
+
+        // If this is a punctuation, apply it through the normal key press
+        if (suggestion.length() == 1 && isWordSeparator(suggestion.charAt(0))) {
+            onKey(suggestion.charAt(0), null);
+            return;
+        }
         pickSuggestion(suggestion);
         TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion);
         // Follow it with a space
@@ -1430,10 +1438,14 @@ public class LatinIME extends InputMethodService
         }
         mPredicting = false;
         mCommittedLength = suggestion.length();
-        setSuggestions(null, false, false, false);
+        setNextSuggestions();
         updateShiftKeyState(getCurrentInputEditorInfo());
     }
 
+    private void setNextSuggestions() {
+        setSuggestions(mSuggestPuncList, false, false, false);
+    }
+
     private boolean isCursorTouchingWord() {
         InputConnection ic = getCurrentInputConnection();
         if (ic == null) return false;
@@ -1767,6 +1779,16 @@ public class LatinIME extends InputMethodService
         return sp.getString(PREF_SELECTED_LANGUAGES, null);
     }
 
+    private void initSuggestPuncList() {
+        mSuggestPuncList = new ArrayList<CharSequence>();
+        String suggestPuncs = mResources.getString(R.string.suggested_punctuations);
+        if (suggestPuncs != null) {
+            for (int i = 0; i < suggestPuncs.length(); i++) {
+                mSuggestPuncList.add(suggestPuncs.subSequence(i, i + 1));
+            }
+        }
+    }
+
     private void showOptionsMenu() {
         AlertDialog.Builder builder = new AlertDialog.Builder(this);
         builder.setCancelable(true);