diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
new file mode 100644
index 0000000..03f38f3
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -0,0 +1,554 @@
+/*
+ * Copyright (C) 2013 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.suggestions;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.graphics.Paint.Align;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.TextPaint;
+import android.text.TextUtils;
+import android.text.style.CharacterStyle;
+import android.text.style.StyleSpan;
+import android.text.style.UnderlineSpan;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.inputmethod.keyboard.ViewLayoutUtils;
+import com.android.inputmethod.latin.AutoCorrection;
+import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.ResourceUtils;
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.Utils;
+
+import java.util.ArrayList;
+
+final class SuggestionStripLayoutHelper {
+    private static final int DEFAULT_SUGGESTIONS_COUNT_IN_STRIP = 3;
+    private static final float DEFAULT_CENTER_SUGGESTION_PERCENTILE = 0.40f;
+    private static final int DEFAULT_MAX_MORE_SUGGESTIONS_ROW = 2;
+    private static final int PUNCTUATIONS_IN_STRIP = 5;
+    private static final float MIN_TEXT_XSCALE = 0.70f;
+
+    public final int mPadding;
+    public final int mDividerWidth;
+    public final int mSuggestionsStripHeight;
+    public final int mSuggestionsCountInStrip;
+    public final int mMoreSuggestionsRowHeight;
+    private int mMaxMoreSuggestionsRow;
+    public final float mMinMoreSuggestionsWidth;
+    public final int mMoreSuggestionsBottomGap;
+
+    private final ArrayList<TextView> mWords;
+    private final ArrayList<View> mDividers;
+    private final ArrayList<TextView> mInfos;
+
+    private final int mColorValidTypedWord;
+    private final int mColorTypedWord;
+    private final int mColorAutoCorrect;
+    private final int mColorSuggested;
+    private final float mAlphaObsoleted;
+    private final float mCenterSuggestionWeight;
+    private final int mCenterSuggestionIndex;
+    private final Drawable mMoreSuggestionsHint;
+    private static final String MORE_SUGGESTIONS_HINT = "\u2026";
+    private static final String LEFTWARDS_ARROW = "\u2190";
+
+    private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
+    private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
+    private static final int AUTO_CORRECT_BOLD = 0x01;
+    private static final int AUTO_CORRECT_UNDERLINE = 0x02;
+    private static final int VALID_TYPED_WORD_BOLD = 0x04;
+
+    private final int mSuggestionStripOption;
+
+    private final ArrayList<CharSequence> mTexts = CollectionUtils.newArrayList();
+
+    public boolean mMoreSuggestionsAvailable;
+
+    private final TextView mWordToSaveView;
+    private final TextView mLeftwardsArrowView;
+    private final TextView mHintToSaveView;
+
+    public SuggestionStripLayoutHelper(final Context context, final AttributeSet attrs,
+            final int defStyle, final ArrayList<TextView> words, final ArrayList<View> dividers,
+            final ArrayList<TextView> infos) {
+        mWords = words;
+        mDividers = dividers;
+        mInfos = infos;
+
+        final TextView word = words.get(0);
+        final View divider = dividers.get(0);
+        mPadding = word.getCompoundPaddingLeft() + word.getCompoundPaddingRight();
+        divider.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+        mDividerWidth = divider.getMeasuredWidth();
+
+        final Resources res = word.getResources();
+        mSuggestionsStripHeight = res.getDimensionPixelSize(R.dimen.suggestions_strip_height);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.SuggestionStripView, defStyle, R.style.SuggestionStripViewStyle);
+        mSuggestionStripOption = a.getInt(
+                R.styleable.SuggestionStripView_suggestionStripOption, 0);
+        final float alphaValidTypedWord = ResourceUtils.getFraction(a,
+                R.styleable.SuggestionStripView_alphaValidTypedWord, 1.0f);
+        final float alphaTypedWord = ResourceUtils.getFraction(a,
+                R.styleable.SuggestionStripView_alphaTypedWord, 1.0f);
+        final float alphaAutoCorrect = ResourceUtils.getFraction(a,
+                R.styleable.SuggestionStripView_alphaAutoCorrect, 1.0f);
+        final float alphaSuggested = ResourceUtils.getFraction(a,
+                R.styleable.SuggestionStripView_alphaSuggested, 1.0f);
+        mAlphaObsoleted = ResourceUtils.getFraction(a,
+                R.styleable.SuggestionStripView_alphaSuggested, 1.0f);
+        mColorValidTypedWord = applyAlpha(a.getColor(
+                R.styleable.SuggestionStripView_colorValidTypedWord, 0), alphaValidTypedWord);
+        mColorTypedWord = applyAlpha(a.getColor(
+                R.styleable.SuggestionStripView_colorTypedWord, 0), alphaTypedWord);
+        mColorAutoCorrect = applyAlpha(a.getColor(
+                R.styleable.SuggestionStripView_colorAutoCorrect, 0), alphaAutoCorrect);
+        mColorSuggested = applyAlpha(a.getColor(
+                R.styleable.SuggestionStripView_colorSuggested, 0), alphaSuggested);
+        mSuggestionsCountInStrip = a.getInt(
+                R.styleable.SuggestionStripView_suggestionsCountInStrip,
+                DEFAULT_SUGGESTIONS_COUNT_IN_STRIP);
+        mCenterSuggestionWeight = ResourceUtils.getFraction(a,
+                R.styleable.SuggestionStripView_centerSuggestionPercentile,
+                DEFAULT_CENTER_SUGGESTION_PERCENTILE);
+        mMaxMoreSuggestionsRow = a.getInt(
+                R.styleable.SuggestionStripView_maxMoreSuggestionsRow,
+                DEFAULT_MAX_MORE_SUGGESTIONS_ROW);
+        mMinMoreSuggestionsWidth = ResourceUtils.getFraction(a,
+                R.styleable.SuggestionStripView_minMoreSuggestionsWidth, 1.0f);
+        a.recycle();
+
+        mMoreSuggestionsHint = getMoreSuggestionsHint(res,
+                res.getDimension(R.dimen.more_suggestions_hint_text_size), mColorAutoCorrect);
+        mCenterSuggestionIndex = mSuggestionsCountInStrip / 2;
+        mMoreSuggestionsBottomGap = res.getDimensionPixelOffset(
+                R.dimen.more_suggestions_bottom_gap);
+        mMoreSuggestionsRowHeight = res.getDimensionPixelSize(R.dimen.more_suggestions_row_height);
+
+        final LayoutInflater inflater = LayoutInflater.from(context);
+        mWordToSaveView = (TextView)inflater.inflate(R.layout.suggestion_word, null);
+        mLeftwardsArrowView = (TextView)inflater.inflate(R.layout.hint_add_to_dictionary, null);
+        mHintToSaveView = (TextView)inflater.inflate(R.layout.hint_add_to_dictionary, null);
+    }
+
+    public int getMaxMoreSuggestionsRow() {
+        return mMaxMoreSuggestionsRow;
+    }
+
+    private int getMoreSuggestionsHeight() {
+        return mMaxMoreSuggestionsRow * mMoreSuggestionsRowHeight + mMoreSuggestionsBottomGap;
+    }
+
+    public int setMoreSuggestionsHeight(final int remainingHeight) {
+        final int currentHeight = getMoreSuggestionsHeight();
+        if (currentHeight <= remainingHeight) {
+            return currentHeight;
+        }
+
+        mMaxMoreSuggestionsRow = (remainingHeight - mMoreSuggestionsBottomGap)
+                / mMoreSuggestionsRowHeight;
+        final int newHeight = getMoreSuggestionsHeight();
+        return newHeight;
+    }
+
+    private static Drawable getMoreSuggestionsHint(final Resources res, final float textSize,
+            final int color) {
+        final Paint paint = new Paint();
+        paint.setAntiAlias(true);
+        paint.setTextAlign(Align.CENTER);
+        paint.setTextSize(textSize);
+        paint.setColor(color);
+        final Rect bounds = new Rect();
+        paint.getTextBounds(MORE_SUGGESTIONS_HINT, 0, MORE_SUGGESTIONS_HINT.length(), bounds);
+        final int width = Math.round(bounds.width() + 0.5f);
+        final int height = Math.round(bounds.height() + 0.5f);
+        final Bitmap buffer = Bitmap.createBitmap(width, (height * 3 / 2), Bitmap.Config.ARGB_8888);
+        final Canvas canvas = new Canvas(buffer);
+        canvas.drawText(MORE_SUGGESTIONS_HINT, width / 2, height, paint);
+        return new BitmapDrawable(res, buffer);
+    }
+
+    private CharSequence getStyledSuggestionWord(final SuggestedWords suggestedWords,
+            final int indexInSuggestedWords) {
+        final String word = suggestedWords.getWord(indexInSuggestedWords);
+        final boolean isAutoCorrect = indexInSuggestedWords == 1
+                && suggestedWords.willAutoCorrect();
+        final boolean isTypedWordValid = indexInSuggestedWords == 0
+                && suggestedWords.mTypedWordValid;
+        if (!isAutoCorrect && !isTypedWordValid)
+            return word;
+
+        final int len = word.length();
+        final Spannable spannedWord = new SpannableString(word);
+        final int option = mSuggestionStripOption;
+        if ((isAutoCorrect && (option & AUTO_CORRECT_BOLD) != 0)
+                || (isTypedWordValid && (option & VALID_TYPED_WORD_BOLD) != 0)) {
+            spannedWord.setSpan(BOLD_SPAN, 0, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+        }
+        if (isAutoCorrect && (option & AUTO_CORRECT_UNDERLINE) != 0) {
+            spannedWord.setSpan(UNDERLINE_SPAN, 0, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+        }
+        return spannedWord;
+    }
+
+    private int getIndexInSuggestedWords(final int indexInStrip,
+            final SuggestedWords suggestedWords) {
+        // TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more
+        // suggestions.
+        final int mostImportantIndexInSuggestedWords = suggestedWords.willAutoCorrect() ? 1 : 0;
+        if (indexInStrip == mCenterSuggestionIndex) {
+            return mostImportantIndexInSuggestedWords;
+        } else if (indexInStrip == mostImportantIndexInSuggestedWords) {
+            return mCenterSuggestionIndex;
+        } else {
+            return indexInStrip;
+        }
+    }
+
+    private int getSuggestionTextColor(final int indexInStrip,
+            final SuggestedWords suggestedWords) {
+        final int indexInSuggestedWords = getIndexInSuggestedWords(
+                indexInStrip, suggestedWords);
+        // TODO: Need to revisit this logic with bigram suggestions
+        final boolean isSuggested = (indexInSuggestedWords != 0);
+
+        final int color;
+        if (indexInStrip == mCenterSuggestionIndex && suggestedWords.willAutoCorrect()) {
+            color = mColorAutoCorrect;
+        } else if (indexInStrip == mCenterSuggestionIndex && suggestedWords.mTypedWordValid) {
+            color = mColorValidTypedWord;
+        } else if (isSuggested) {
+            color = mColorSuggested;
+        } else {
+            color = mColorTypedWord;
+        }
+        if (LatinImeLogger.sDBG && suggestedWords.size() > 1) {
+            // If we auto-correct, then the autocorrection is in slot 0 and the typed word
+            // is in slot 1.
+            if (indexInStrip == mCenterSuggestionIndex
+                    && AutoCorrection.shouldBlockAutoCorrectionBySafetyNet(
+                            suggestedWords.getWord(1), suggestedWords.getWord(0))) {
+                return 0xFFFF0000;
+            }
+        }
+
+        if (suggestedWords.mIsObsoleteSuggestions && isSuggested) {
+            return applyAlpha(color, mAlphaObsoleted);
+        } else {
+            return color;
+        }
+    }
+
+    private static int applyAlpha(final int color, final float alpha) {
+        final int newAlpha = (int)(Color.alpha(color) * alpha);
+        return Color.argb(newAlpha, Color.red(color), Color.green(color), Color.blue(color));
+    }
+
+    private static void addDivider(final ViewGroup stripView, final View divider) {
+        stripView.addView(divider);
+        final LinearLayout.LayoutParams params =
+                (LinearLayout.LayoutParams)divider.getLayoutParams();
+        params.gravity = Gravity.CENTER;
+    }
+
+    public void layout(final SuggestedWords suggestedWords, final ViewGroup stripView,
+            final ViewGroup placer, final int stripWidth) {
+        if (suggestedWords.mIsPunctuationSuggestions) {
+            layoutPunctuationSuggestions(suggestedWords, stripView);
+            return;
+        }
+
+        final int countInStrip = mSuggestionsCountInStrip;
+        setupTexts(suggestedWords, countInStrip);
+        mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
+        int x = 0;
+        for (int indexInStrip = 0; indexInStrip < countInStrip; indexInStrip++) {
+            if (indexInStrip != 0) {
+                final View divider = mDividers.get(indexInStrip);
+                // Add divider if this isn't the left most suggestion in suggestions strip.
+                addDivider(stripView, divider);
+                x += divider.getMeasuredWidth();
+            }
+
+            final int width = getSuggestionWidth(indexInStrip, stripWidth);
+            final TextView word = layoutWord(suggestedWords, indexInStrip, width);
+            stripView.addView(word);
+            setLayoutWeight(word, getSuggestionWeight(indexInStrip),
+                    ViewGroup.LayoutParams.MATCH_PARENT);
+            x += word.getMeasuredWidth();
+
+            if (SuggestionStripView.DBG) {
+                layoutDebugInfo(suggestedWords, indexInStrip, placer, x);
+            }
+        }
+    }
+
+    /**
+     * Format appropriately the suggested word indirectly specified by
+     * <code>indexInStrip</code> as text in a corresponding {@link TextView}. When the
+     * suggested word doesn't exist, the corresponding {@link TextView} will be disabled
+     * and never respond to user interaction. The suggested word may be shrunk or ellipsized to
+     * fit in the specified width.
+     *
+     * The <code>indexInStrip</code> argument is the index in the suggestion strip. The indices
+     * increase towards the right for LTR scripts and the left for RTL scripts, starting with 0.
+     * The index of the most important suggestion is in {@link #mCenterSuggestionIndex}. This
+     * usually doesn't match the index in <code>suggedtedWords</code> -- see
+     * {@link #getIndexInSuggestedWords(int,SuggestedWords)}.
+     *
+     * @param suggestedWords the list of suggestions.
+     * @param indexInStrip the in the suggestion strip.
+     * @param width the maximum width for layout in pixels.
+     * @return the {@link TextView} containing the suggested word appropriately formatted.
+     */
+    private TextView layoutWord(final SuggestedWords suggestedWords, final int indexInStrip,
+            final int width) {
+        final int indexInSuggestedWords = getIndexInSuggestedWords(indexInStrip, suggestedWords);
+        final CharSequence styled = mTexts.get(indexInSuggestedWords);
+        final TextView word = mWords.get(indexInSuggestedWords);
+        if (indexInStrip == mCenterSuggestionIndex && mMoreSuggestionsAvailable) {
+            // TODO: This "more suggestions hint" should have a nicely designed icon.
+            word.setCompoundDrawablesWithIntrinsicBounds(
+                    null, null, null, mMoreSuggestionsHint);
+            // HACK: Align with other TextViews that have no compound drawables.
+            word.setCompoundDrawablePadding(-mMoreSuggestionsHint.getIntrinsicHeight());
+        } else {
+            word.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+        }
+
+        // Disable this suggestion if the suggestion is null or empty.
+        word.setEnabled(!TextUtils.isEmpty(styled));
+        word.setTextColor(getSuggestionTextColor(indexInStrip, suggestedWords));
+        final CharSequence text = getEllipsizedText(styled, width, word.getPaint());
+        final float scaleX = word.getTextScaleX();
+        word.setText(text); // TextView.setText() resets text scale x to 1.0.
+        word.setTextScaleX(scaleX);
+        return word;
+    }
+
+    private void layoutDebugInfo(final SuggestedWords suggestedWords, final int indexInStrip,
+            final ViewGroup placer, final int x) {
+        final int indexInSuggestedWords = getIndexInSuggestedWords(indexInStrip, suggestedWords);
+        if (indexInSuggestedWords >= suggestedWords.size()) {
+            return;
+        }
+        final String debugInfo = Utils.getDebugInfo(suggestedWords, indexInSuggestedWords);
+        if (debugInfo == null) {
+            return;
+        }
+        final TextView info = mInfos.get(indexInSuggestedWords);
+        info.setText(debugInfo);
+        placer.addView(info);
+        info.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        final int infoWidth = info.getMeasuredWidth();
+        final int y = info.getMeasuredHeight();
+        ViewLayoutUtils.placeViewAt(
+                info, x - infoWidth, y, infoWidth, info.getMeasuredHeight());
+    }
+
+    private int getSuggestionWidth(final int indexInStrip, final int maxWidth) {
+        final int paddings = mPadding * mSuggestionsCountInStrip;
+        final int dividers = mDividerWidth * (mSuggestionsCountInStrip - 1);
+        final int availableWidth = maxWidth - paddings - dividers;
+        return (int)(availableWidth * getSuggestionWeight(indexInStrip));
+    }
+
+    private float getSuggestionWeight(final int indexInStrip) {
+        if (indexInStrip == mCenterSuggestionIndex) {
+            return mCenterSuggestionWeight;
+        } else {
+            // TODO: Revisit this for cases of 5 or more suggestions
+            return (1.0f - mCenterSuggestionWeight) / (mSuggestionsCountInStrip - 1);
+        }
+    }
+
+    private void setupTexts(final SuggestedWords suggestedWords, final int countInStrip) {
+        mTexts.clear();
+        final int count = Math.min(suggestedWords.size(), countInStrip);
+        for (int pos = 0; pos < count; pos++) {
+            final CharSequence styled = getStyledSuggestionWord(suggestedWords, pos);
+            mTexts.add(styled);
+        }
+        for (int pos = count; pos < countInStrip; pos++) {
+            // Make this inactive for touches in layout().
+            mTexts.add(null);
+        }
+    }
+
+    private void layoutPunctuationSuggestions(final SuggestedWords suggestedWords,
+            final ViewGroup stripView) {
+        final int countInStrip = Math.min(suggestedWords.size(), PUNCTUATIONS_IN_STRIP);
+        for (int indexInStrip = 0; indexInStrip < countInStrip; indexInStrip++) {
+            if (indexInStrip != 0) {
+                // Add divider if this isn't the left most suggestion in suggestions strip.
+                addDivider(stripView, mDividers.get(indexInStrip));
+            }
+
+            final TextView word = mWords.get(indexInStrip);
+            word.setEnabled(true);
+            word.setTextColor(mColorAutoCorrect);
+            final String text = suggestedWords.getWord(indexInStrip);
+            word.setText(text);
+            word.setTextScaleX(1.0f);
+            word.setCompoundDrawables(null, null, null, null);
+            stripView.addView(word);
+            setLayoutWeight(word, 1.0f, mSuggestionsStripHeight);
+        }
+        mMoreSuggestionsAvailable = false;
+    }
+
+    public void layoutAddToDictionaryHint(final String word, final ViewGroup stripView,
+            final int stripWidth, final CharSequence hintText, final OnClickListener listener) {
+        final int width = stripWidth - mDividerWidth - mPadding * 2;
+
+        final TextView wordView = mWordToSaveView;
+        wordView.setTextColor(mColorTypedWord);
+        final int wordWidth = (int)(width * mCenterSuggestionWeight);
+        final CharSequence text = getEllipsizedText(word, wordWidth, wordView.getPaint());
+        final float wordScaleX = wordView.getTextScaleX();
+        wordView.setTag(word);
+        wordView.setText(text);
+        wordView.setTextScaleX(wordScaleX);
+        stripView.addView(wordView);
+        setLayoutWeight(wordView, mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
+
+        stripView.addView(mDividers.get(0));
+
+        final TextView leftArrowView = mLeftwardsArrowView;
+        leftArrowView.setTextColor(mColorAutoCorrect);
+        leftArrowView.setText(LEFTWARDS_ARROW);
+        stripView.addView(leftArrowView);
+
+        final TextView hintView = mHintToSaveView;
+        hintView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
+        hintView.setTextColor(mColorAutoCorrect);
+        final int hintWidth = width - wordWidth - leftArrowView.getWidth();
+        final float hintScaleX = getTextScaleX(hintText, hintWidth, hintView.getPaint());
+        hintView.setText(hintText);
+        hintView.setTextScaleX(hintScaleX);
+        stripView.addView(hintView);
+        setLayoutWeight(
+                hintView, 1.0f - mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
+
+        wordView.setOnClickListener(listener);
+        leftArrowView.setOnClickListener(listener);
+        hintView.setOnClickListener(listener);
+    }
+
+    public CharSequence getAddToDictionaryWord() {
+        return (CharSequence)mWordToSaveView.getTag();
+    }
+
+    public boolean isAddToDictionaryShowing(final View v) {
+        return v == mWordToSaveView || v == mHintToSaveView || v == mLeftwardsArrowView;
+    }
+
+    private static void setLayoutWeight(final View v, final float weight, final int height) {
+        final ViewGroup.LayoutParams lp = v.getLayoutParams();
+        if (lp instanceof LinearLayout.LayoutParams) {
+            final LinearLayout.LayoutParams llp = (LinearLayout.LayoutParams)lp;
+            llp.weight = weight;
+            llp.width = 0;
+            llp.height = height;
+        }
+    }
+
+    private static float getTextScaleX(final CharSequence text, final int maxWidth,
+            final TextPaint paint) {
+        paint.setTextScaleX(1.0f);
+        final int width = getTextWidth(text, paint);
+        if (width <= maxWidth) {
+            return 1.0f;
+        }
+        return maxWidth / (float)width;
+    }
+
+    private static CharSequence getEllipsizedText(final CharSequence text, final int maxWidth,
+            final TextPaint paint) {
+        if (text == null) return null;
+        paint.setTextScaleX(1.0f);
+        final int width = getTextWidth(text, paint);
+        if (width <= maxWidth) {
+            return text;
+        }
+        final float scaleX = maxWidth / (float)width;
+        if (scaleX >= MIN_TEXT_XSCALE) {
+            paint.setTextScaleX(scaleX);
+            return text;
+        }
+
+        // Note that TextUtils.ellipsize() use text-x-scale as 1.0 if ellipsize is needed. To
+        // get squeezed and ellipsized text, passes enlarged width (maxWidth / MIN_TEXT_XSCALE).
+        final CharSequence ellipsized = TextUtils.ellipsize(
+                text, paint, maxWidth / MIN_TEXT_XSCALE, TextUtils.TruncateAt.MIDDLE);
+        paint.setTextScaleX(MIN_TEXT_XSCALE);
+        return ellipsized;
+    }
+
+    private static int getTextWidth(final CharSequence text, final TextPaint paint) {
+        if (TextUtils.isEmpty(text)) return 0;
+        final Typeface savedTypeface = paint.getTypeface();
+        paint.setTypeface(getTextTypeface(text));
+        final int len = text.length();
+        final float[] widths = new float[len];
+        final int count = paint.getTextWidths(text, 0, len, widths);
+        int width = 0;
+        for (int i = 0; i < count; i++) {
+            width += Math.round(widths[i] + 0.5f);
+        }
+        paint.setTypeface(savedTypeface);
+        return width;
+    }
+
+    private static Typeface getTextTypeface(final CharSequence text) {
+        if (!(text instanceof SpannableString))
+            return Typeface.DEFAULT;
+
+        final SpannableString ss = (SpannableString)text;
+        final StyleSpan[] styles = ss.getSpans(0, text.length(), StyleSpan.class);
+        if (styles.length == 0)
+            return Typeface.DEFAULT;
+
+        switch (styles[0].getStyle()) {
+        case Typeface.BOLD: return Typeface.DEFAULT_BOLD;
+        // TODO: BOLD_ITALIC, ITALIC case?
+        default: return Typeface.DEFAULT;
+        }
+    }
+}
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 9764610..59a05de 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -18,34 +18,14 @@
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Paint.Align;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.TextPaint;
-import android.text.TextUtils;
-import android.text.style.CharacterStyle;
-import android.text.style.StyleSpan;
-import android.text.style.UnderlineSpan;
 import android.util.AttributeSet;
 import android.view.GestureDetector;
-import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.View.OnLongClickListener;
 import android.view.ViewGroup;
-import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
@@ -53,17 +33,13 @@
 import com.android.inputmethod.keyboard.KeyboardSwitcher;
 import com.android.inputmethod.keyboard.MainKeyboardView;
 import com.android.inputmethod.keyboard.MoreKeysPanel;
-import com.android.inputmethod.keyboard.ViewLayoutUtils;
 import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
-import com.android.inputmethod.latin.AutoCorrection;
 import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResourceUtils;
 import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.Utils;
 import com.android.inputmethod.latin.define.ProductionFlag;
 import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionsListener;
 import com.android.inputmethod.research.ResearchLogger;
@@ -96,509 +72,7 @@
     Listener mListener;
     private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
 
-    private final SuggestionStripViewParams mParams;
-    private static final float MIN_TEXT_XSCALE = 0.70f;
-
-    private static final class SuggestionStripViewParams {
-        private static final int DEFAULT_SUGGESTIONS_COUNT_IN_STRIP = 3;
-        private static final float DEFAULT_CENTER_SUGGESTION_PERCENTILE = 0.40f;
-        private static final int DEFAULT_MAX_MORE_SUGGESTIONS_ROW = 2;
-        private static final int PUNCTUATIONS_IN_STRIP = 5;
-
-        public final int mPadding;
-        public final int mDividerWidth;
-        public final int mSuggestionsStripHeight;
-        public final int mSuggestionsCountInStrip;
-        public final int mMoreSuggestionsRowHeight;
-        private int mMaxMoreSuggestionsRow;
-        public final float mMinMoreSuggestionsWidth;
-        public final int mMoreSuggestionsBottomGap;
-
-        private final ArrayList<TextView> mWords;
-        private final ArrayList<View> mDividers;
-        private final ArrayList<TextView> mInfos;
-
-        private final int mColorValidTypedWord;
-        private final int mColorTypedWord;
-        private final int mColorAutoCorrect;
-        private final int mColorSuggested;
-        private final float mAlphaObsoleted;
-        private final float mCenterSuggestionWeight;
-        private final int mCenterSuggestionIndex;
-        private final Drawable mMoreSuggestionsHint;
-        private static final String MORE_SUGGESTIONS_HINT = "\u2026";
-        private static final String LEFTWARDS_ARROW = "\u2190";
-
-        private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
-        private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
-        private static final int AUTO_CORRECT_BOLD = 0x01;
-        private static final int AUTO_CORRECT_UNDERLINE = 0x02;
-        private static final int VALID_TYPED_WORD_BOLD = 0x04;
-
-        private final int mSuggestionStripOption;
-
-        private final ArrayList<CharSequence> mTexts = CollectionUtils.newArrayList();
-
-        public boolean mMoreSuggestionsAvailable;
-
-        private final TextView mWordToSaveView;
-        private final TextView mLeftwardsArrowView;
-        private final TextView mHintToSaveView;
-
-        public SuggestionStripViewParams(final Context context, final AttributeSet attrs,
-                final int defStyle, final ArrayList<TextView> words, final ArrayList<View> dividers,
-                final ArrayList<TextView> infos) {
-            mWords = words;
-            mDividers = dividers;
-            mInfos = infos;
-
-            final TextView word = words.get(0);
-            final View divider = dividers.get(0);
-            mPadding = word.getCompoundPaddingLeft() + word.getCompoundPaddingRight();
-            divider.measure(
-                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
-            mDividerWidth = divider.getMeasuredWidth();
-
-            final Resources res = word.getResources();
-            mSuggestionsStripHeight = res.getDimensionPixelSize(R.dimen.suggestions_strip_height);
-
-            final TypedArray a = context.obtainStyledAttributes(attrs,
-                    R.styleable.SuggestionStripView, defStyle, R.style.SuggestionStripViewStyle);
-            mSuggestionStripOption = a.getInt(
-                    R.styleable.SuggestionStripView_suggestionStripOption, 0);
-            final float alphaValidTypedWord = ResourceUtils.getFraction(a,
-                    R.styleable.SuggestionStripView_alphaValidTypedWord, 1.0f);
-            final float alphaTypedWord = ResourceUtils.getFraction(a,
-                    R.styleable.SuggestionStripView_alphaTypedWord, 1.0f);
-            final float alphaAutoCorrect = ResourceUtils.getFraction(a,
-                    R.styleable.SuggestionStripView_alphaAutoCorrect, 1.0f);
-            final float alphaSuggested = ResourceUtils.getFraction(a,
-                    R.styleable.SuggestionStripView_alphaSuggested, 1.0f);
-            mAlphaObsoleted = ResourceUtils.getFraction(a,
-                    R.styleable.SuggestionStripView_alphaSuggested, 1.0f);
-            mColorValidTypedWord = applyAlpha(a.getColor(
-                    R.styleable.SuggestionStripView_colorValidTypedWord, 0), alphaValidTypedWord);
-            mColorTypedWord = applyAlpha(a.getColor(
-                    R.styleable.SuggestionStripView_colorTypedWord, 0), alphaTypedWord);
-            mColorAutoCorrect = applyAlpha(a.getColor(
-                    R.styleable.SuggestionStripView_colorAutoCorrect, 0), alphaAutoCorrect);
-            mColorSuggested = applyAlpha(a.getColor(
-                    R.styleable.SuggestionStripView_colorSuggested, 0), alphaSuggested);
-            mSuggestionsCountInStrip = a.getInt(
-                    R.styleable.SuggestionStripView_suggestionsCountInStrip,
-                    DEFAULT_SUGGESTIONS_COUNT_IN_STRIP);
-            mCenterSuggestionWeight = ResourceUtils.getFraction(a,
-                    R.styleable.SuggestionStripView_centerSuggestionPercentile,
-                    DEFAULT_CENTER_SUGGESTION_PERCENTILE);
-            mMaxMoreSuggestionsRow = a.getInt(
-                    R.styleable.SuggestionStripView_maxMoreSuggestionsRow,
-                    DEFAULT_MAX_MORE_SUGGESTIONS_ROW);
-            mMinMoreSuggestionsWidth = ResourceUtils.getFraction(a,
-                    R.styleable.SuggestionStripView_minMoreSuggestionsWidth, 1.0f);
-            a.recycle();
-
-            mMoreSuggestionsHint = getMoreSuggestionsHint(res,
-                    res.getDimension(R.dimen.more_suggestions_hint_text_size), mColorAutoCorrect);
-            mCenterSuggestionIndex = mSuggestionsCountInStrip / 2;
-            mMoreSuggestionsBottomGap = res.getDimensionPixelOffset(
-                    R.dimen.more_suggestions_bottom_gap);
-            mMoreSuggestionsRowHeight = res.getDimensionPixelSize(
-                    R.dimen.more_suggestions_row_height);
-
-            final LayoutInflater inflater = LayoutInflater.from(context);
-            mWordToSaveView = (TextView)inflater.inflate(R.layout.suggestion_word, null);
-            mLeftwardsArrowView = (TextView)inflater.inflate(R.layout.hint_add_to_dictionary, null);
-            mHintToSaveView = (TextView)inflater.inflate(R.layout.hint_add_to_dictionary, null);
-        }
-
-        public int getMaxMoreSuggestionsRow() {
-            return mMaxMoreSuggestionsRow;
-        }
-
-        private int getMoreSuggestionsHeight() {
-            return mMaxMoreSuggestionsRow * mMoreSuggestionsRowHeight + mMoreSuggestionsBottomGap;
-        }
-
-        public int setMoreSuggestionsHeight(final int remainingHeight) {
-            final int currentHeight = getMoreSuggestionsHeight();
-            if (currentHeight <= remainingHeight) {
-                return currentHeight;
-            }
-
-            mMaxMoreSuggestionsRow = (remainingHeight - mMoreSuggestionsBottomGap)
-                    / mMoreSuggestionsRowHeight;
-            final int newHeight = getMoreSuggestionsHeight();
-            return newHeight;
-        }
-
-        private static Drawable getMoreSuggestionsHint(final Resources res, final float textSize,
-                final int color) {
-            final Paint paint = new Paint();
-            paint.setAntiAlias(true);
-            paint.setTextAlign(Align.CENTER);
-            paint.setTextSize(textSize);
-            paint.setColor(color);
-            final Rect bounds = new Rect();
-            paint.getTextBounds(MORE_SUGGESTIONS_HINT, 0, MORE_SUGGESTIONS_HINT.length(), bounds);
-            final int width = Math.round(bounds.width() + 0.5f);
-            final int height = Math.round(bounds.height() + 0.5f);
-            final Bitmap buffer = Bitmap.createBitmap(
-                    width, (height * 3 / 2), Bitmap.Config.ARGB_8888);
-            final Canvas canvas = new Canvas(buffer);
-            canvas.drawText(MORE_SUGGESTIONS_HINT, width / 2, height, paint);
-            return new BitmapDrawable(res, buffer);
-        }
-
-        private CharSequence getStyledSuggestionWord(final SuggestedWords suggestedWords,
-                final int indexInSuggestedWords) {
-            final String word = suggestedWords.getWord(indexInSuggestedWords);
-            final boolean isAutoCorrect = indexInSuggestedWords == 1
-                    && suggestedWords.willAutoCorrect();
-            final boolean isTypedWordValid = indexInSuggestedWords == 0
-                    && suggestedWords.mTypedWordValid;
-            if (!isAutoCorrect && !isTypedWordValid)
-                return word;
-
-            final int len = word.length();
-            final Spannable spannedWord = new SpannableString(word);
-            final int option = mSuggestionStripOption;
-            if ((isAutoCorrect && (option & AUTO_CORRECT_BOLD) != 0)
-                    || (isTypedWordValid && (option & VALID_TYPED_WORD_BOLD) != 0)) {
-                spannedWord.setSpan(BOLD_SPAN, 0, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
-            }
-            if (isAutoCorrect && (option & AUTO_CORRECT_UNDERLINE) != 0) {
-                spannedWord.setSpan(UNDERLINE_SPAN, 0, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
-            }
-            return spannedWord;
-        }
-
-        private int getIndexInSuggestedWords(final int indexInStrip,
-                final SuggestedWords suggestedWords) {
-            // TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more
-            // suggestions.
-            final int mostImportantIndexInSuggestedWords = suggestedWords.willAutoCorrect() ? 1 : 0;
-            if (indexInStrip == mCenterSuggestionIndex) {
-                return mostImportantIndexInSuggestedWords;
-            } else if (indexInStrip == mostImportantIndexInSuggestedWords) {
-                return mCenterSuggestionIndex;
-            } else {
-                return indexInStrip;
-            }
-        }
-
-        private int getSuggestionTextColor(final int indexInStrip,
-                final SuggestedWords suggestedWords) {
-            final int indexInSuggestedWords = getIndexInSuggestedWords(
-                    indexInStrip, suggestedWords);
-            // TODO: Need to revisit this logic with bigram suggestions
-            final boolean isSuggested = (indexInSuggestedWords != 0);
-
-            final int color;
-            if (indexInStrip == mCenterSuggestionIndex && suggestedWords.willAutoCorrect()) {
-                color = mColorAutoCorrect;
-            } else if (indexInStrip == mCenterSuggestionIndex && suggestedWords.mTypedWordValid) {
-                color = mColorValidTypedWord;
-            } else if (isSuggested) {
-                color = mColorSuggested;
-            } else {
-                color = mColorTypedWord;
-            }
-            if (LatinImeLogger.sDBG && suggestedWords.size() > 1) {
-                // If we auto-correct, then the autocorrection is in slot 0 and the typed word
-                // is in slot 1.
-                if (indexInStrip == mCenterSuggestionIndex
-                        && AutoCorrection.shouldBlockAutoCorrectionBySafetyNet(
-                                suggestedWords.getWord(1), suggestedWords.getWord(0))) {
-                    return 0xFFFF0000;
-                }
-            }
-
-            if (suggestedWords.mIsObsoleteSuggestions && isSuggested) {
-                return applyAlpha(color, mAlphaObsoleted);
-            } else {
-                return color;
-            }
-        }
-
-        private static int applyAlpha(final int color, final float alpha) {
-            final int newAlpha = (int)(Color.alpha(color) * alpha);
-            return Color.argb(newAlpha, Color.red(color), Color.green(color), Color.blue(color));
-        }
-
-        private static void addDivider(final ViewGroup stripView, final View divider) {
-            stripView.addView(divider);
-            final LinearLayout.LayoutParams params =
-                    (LinearLayout.LayoutParams)divider.getLayoutParams();
-            params.gravity = Gravity.CENTER;
-        }
-
-        public void layout(final SuggestedWords suggestedWords, final ViewGroup stripView,
-                final ViewGroup placer, final int stripWidth) {
-            if (suggestedWords.mIsPunctuationSuggestions) {
-                layoutPunctuationSuggestions(suggestedWords, stripView);
-                return;
-            }
-
-            final int countInStrip = mSuggestionsCountInStrip;
-            setupTexts(suggestedWords, countInStrip);
-            mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
-            int x = 0;
-            for (int indexInStrip = 0; indexInStrip < countInStrip; indexInStrip++) {
-                if (indexInStrip != 0) {
-                    final View divider = mDividers.get(indexInStrip);
-                    // Add divider if this isn't the left most suggestion in suggestions strip.
-                    addDivider(stripView, divider);
-                    x += divider.getMeasuredWidth();
-                }
-
-                final int width = getSuggestionWidth(indexInStrip, stripWidth);
-                final TextView word = layoutWord(suggestedWords, indexInStrip, width);
-                stripView.addView(word);
-                setLayoutWeight(word, getSuggestionWeight(indexInStrip),
-                        ViewGroup.LayoutParams.MATCH_PARENT);
-                x += word.getMeasuredWidth();
-
-                if (DBG) {
-                    layoutDebugInfo(suggestedWords, indexInStrip, placer, x);
-                }
-            }
-        }
-
-        /**
-         * Format appropriately the suggested word indirectly specified by
-         * <code>indexInStrip</code> as text in a corresponding {@link TextView}. When the
-         * suggested word doesn't exist, the corresponding {@link TextView} will be disabled
-         * and never respond to user interaction. The suggested word may be shrunk or ellipsized to
-         * fit in the specified width.
-         *
-         * The <code>indexInStrip</code> argument is the index in the suggestion strip. The indices
-         * increase towards the right for LTR scripts and the left for RTL scripts, starting with 0.
-         * The index of the most important suggestion is in {@link #mCenterSuggestionIndex}. This
-         * usually doesn't match the index in <code>suggedtedWords</code> -- see
-         * {@link #getIndexInSuggestedWords(int,SuggestedWords)}.
-         *
-         * @param suggestedWords the list of suggestions.
-         * @param indexInStrip the in the suggestion strip.
-         * @param width the maximum width for layout in pixels.
-         * @return the {@link TextView} containing the suggested word appropriately formatted.
-         */
-        private TextView layoutWord(final SuggestedWords suggestedWords, final int indexInStrip,
-                final int width) {
-            final int indexInSuggestedWords = getIndexInSuggestedWords(
-                    indexInStrip, suggestedWords);
-            final CharSequence styled = mTexts.get(indexInSuggestedWords);
-            final TextView word = mWords.get(indexInSuggestedWords);
-            if (indexInStrip == mCenterSuggestionIndex && mMoreSuggestionsAvailable) {
-                // TODO: This "more suggestions hint" should have a nicely designed icon.
-                word.setCompoundDrawablesWithIntrinsicBounds(
-                        null, null, null, mMoreSuggestionsHint);
-                // HACK: Align with other TextViews that have no compound drawables.
-                word.setCompoundDrawablePadding(-mMoreSuggestionsHint.getIntrinsicHeight());
-            } else {
-                word.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
-            }
-
-            // Disable this suggestion if the suggestion is null or empty.
-            word.setEnabled(!TextUtils.isEmpty(styled));
-            word.setTextColor(getSuggestionTextColor(indexInStrip, suggestedWords));
-            final CharSequence text = getEllipsizedText(styled, width, word.getPaint());
-            final float scaleX = word.getTextScaleX();
-            word.setText(text); // TextView.setText() resets text scale x to 1.0.
-            word.setTextScaleX(scaleX);
-            return word;
-        }
-
-        private void layoutDebugInfo(final SuggestedWords suggestedWords, final int indexInStrip,
-                final ViewGroup placer, final int x) {
-            final int indexInSuggestedWords = getIndexInSuggestedWords(
-                    indexInStrip, suggestedWords);
-            if (indexInSuggestedWords >= suggestedWords.size()) {
-                return;
-            }
-            final String debugInfo = Utils.getDebugInfo(suggestedWords, indexInSuggestedWords);
-            if (debugInfo == null) {
-                return;
-            }
-            final TextView info = mInfos.get(indexInSuggestedWords);
-            info.setText(debugInfo);
-            placer.addView(info);
-            info.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-            final int infoWidth = info.getMeasuredWidth();
-            final int y = info.getMeasuredHeight();
-            ViewLayoutUtils.placeViewAt(
-                    info, x - infoWidth, y, infoWidth, info.getMeasuredHeight());
-        }
-
-        private int getSuggestionWidth(final int indexInStrip, final int maxWidth) {
-            final int paddings = mPadding * mSuggestionsCountInStrip;
-            final int dividers = mDividerWidth * (mSuggestionsCountInStrip - 1);
-            final int availableWidth = maxWidth - paddings - dividers;
-            return (int)(availableWidth * getSuggestionWeight(indexInStrip));
-        }
-
-        private float getSuggestionWeight(final int indexInStrip) {
-            if (indexInStrip == mCenterSuggestionIndex) {
-                return mCenterSuggestionWeight;
-            } else {
-                // TODO: Revisit this for cases of 5 or more suggestions
-                return (1.0f - mCenterSuggestionWeight) / (mSuggestionsCountInStrip - 1);
-            }
-        }
-
-        private void setupTexts(final SuggestedWords suggestedWords, final int countInStrip) {
-            mTexts.clear();
-            final int count = Math.min(suggestedWords.size(), countInStrip);
-            for (int pos = 0; pos < count; pos++) {
-                final CharSequence styled = getStyledSuggestionWord(suggestedWords, pos);
-                mTexts.add(styled);
-            }
-            for (int pos = count; pos < countInStrip; pos++) {
-                // Make this inactive for touches in layout().
-                mTexts.add(null);
-            }
-        }
-
-        private void layoutPunctuationSuggestions(final SuggestedWords suggestedWords,
-                final ViewGroup stripView) {
-            final int countInStrip = Math.min(suggestedWords.size(), PUNCTUATIONS_IN_STRIP);
-            for (int indexInStrip = 0; indexInStrip < countInStrip; indexInStrip++) {
-                if (indexInStrip != 0) {
-                    // Add divider if this isn't the left most suggestion in suggestions strip.
-                    addDivider(stripView, mDividers.get(indexInStrip));
-                }
-
-                final TextView word = mWords.get(indexInStrip);
-                word.setEnabled(true);
-                word.setTextColor(mColorAutoCorrect);
-                final String text = suggestedWords.getWord(indexInStrip);
-                word.setText(text);
-                word.setTextScaleX(1.0f);
-                word.setCompoundDrawables(null, null, null, null);
-                stripView.addView(word);
-                setLayoutWeight(word, 1.0f, mSuggestionsStripHeight);
-            }
-            mMoreSuggestionsAvailable = false;
-        }
-
-        public void layoutAddToDictionaryHint(final String word, final ViewGroup stripView,
-                final int stripWidth, final CharSequence hintText, final OnClickListener listener) {
-            final int width = stripWidth - mDividerWidth - mPadding * 2;
-
-            final TextView wordView = mWordToSaveView;
-            wordView.setTextColor(mColorTypedWord);
-            final int wordWidth = (int)(width * mCenterSuggestionWeight);
-            final CharSequence text = getEllipsizedText(word, wordWidth, wordView.getPaint());
-            final float wordScaleX = wordView.getTextScaleX();
-            wordView.setTag(word);
-            wordView.setText(text);
-            wordView.setTextScaleX(wordScaleX);
-            stripView.addView(wordView);
-            setLayoutWeight(wordView, mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
-
-            stripView.addView(mDividers.get(0));
-
-            final TextView leftArrowView = mLeftwardsArrowView;
-            leftArrowView.setTextColor(mColorAutoCorrect);
-            leftArrowView.setText(LEFTWARDS_ARROW);
-            stripView.addView(leftArrowView);
-
-            final TextView hintView = mHintToSaveView;
-            hintView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
-            hintView.setTextColor(mColorAutoCorrect);
-            final int hintWidth = width - wordWidth - leftArrowView.getWidth();
-            final float hintScaleX = getTextScaleX(hintText, hintWidth, hintView.getPaint());
-            hintView.setText(hintText);
-            hintView.setTextScaleX(hintScaleX);
-            stripView.addView(hintView);
-            setLayoutWeight(
-                    hintView, 1.0f - mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
-
-            wordView.setOnClickListener(listener);
-            leftArrowView.setOnClickListener(listener);
-            hintView.setOnClickListener(listener);
-        }
-
-        public CharSequence getAddToDictionaryWord() {
-            return (CharSequence)mWordToSaveView.getTag();
-        }
-
-        public boolean isAddToDictionaryShowing(final View v) {
-            return v == mWordToSaveView || v == mHintToSaveView || v == mLeftwardsArrowView;
-        }
-
-        private static void setLayoutWeight(final View v, final float weight, final int height) {
-            final ViewGroup.LayoutParams lp = v.getLayoutParams();
-            if (lp instanceof LinearLayout.LayoutParams) {
-                final LinearLayout.LayoutParams llp = (LinearLayout.LayoutParams)lp;
-                llp.weight = weight;
-                llp.width = 0;
-                llp.height = height;
-            }
-        }
-
-        private static float getTextScaleX(final CharSequence text, final int maxWidth,
-                final TextPaint paint) {
-            paint.setTextScaleX(1.0f);
-            final int width = getTextWidth(text, paint);
-            if (width <= maxWidth) {
-                return 1.0f;
-            }
-            return maxWidth / (float)width;
-        }
-
-        private static CharSequence getEllipsizedText(final CharSequence text, final int maxWidth,
-                final TextPaint paint) {
-            if (text == null) return null;
-            paint.setTextScaleX(1.0f);
-            final int width = getTextWidth(text, paint);
-            if (width <= maxWidth) {
-                return text;
-            }
-            final float scaleX = maxWidth / (float)width;
-            if (scaleX >= MIN_TEXT_XSCALE) {
-                paint.setTextScaleX(scaleX);
-                return text;
-            }
-
-            // Note that TextUtils.ellipsize() use text-x-scale as 1.0 if ellipsize is needed. To
-            // get squeezed and ellipsized text, passes enlarged width (maxWidth / MIN_TEXT_XSCALE).
-            final CharSequence ellipsized = TextUtils.ellipsize(
-                    text, paint, maxWidth / MIN_TEXT_XSCALE, TextUtils.TruncateAt.MIDDLE);
-            paint.setTextScaleX(MIN_TEXT_XSCALE);
-            return ellipsized;
-        }
-
-        private static int getTextWidth(final CharSequence text, final TextPaint paint) {
-            if (TextUtils.isEmpty(text)) return 0;
-            final Typeface savedTypeface = paint.getTypeface();
-            paint.setTypeface(getTextTypeface(text));
-            final int len = text.length();
-            final float[] widths = new float[len];
-            final int count = paint.getTextWidths(text, 0, len, widths);
-            int width = 0;
-            for (int i = 0; i < count; i++) {
-                width += Math.round(widths[i] + 0.5f);
-            }
-            paint.setTypeface(savedTypeface);
-            return width;
-        }
-
-        private static Typeface getTextTypeface(final CharSequence text) {
-            if (!(text instanceof SpannableString))
-                return Typeface.DEFAULT;
-
-            final SpannableString ss = (SpannableString)text;
-            final StyleSpan[] styles = ss.getSpans(0, text.length(), StyleSpan.class);
-            if (styles.length == 0)
-                return Typeface.DEFAULT;
-
-            switch (styles[0].getStyle()) {
-            case Typeface.BOLD: return Typeface.DEFAULT_BOLD;
-            // TODO: BOLD_ITALIC, ITALIC case?
-            default: return Typeface.DEFAULT;
-            }
-        }
-    }
+    private final SuggestionStripLayoutHelper mLayoutHelper;
 
     /**
      * Construct a {@link SuggestionStripView} for showing suggestions to be picked by the user.
@@ -630,7 +104,7 @@
             mInfos.add((TextView)inflater.inflate(R.layout.suggestion_info, null));
         }
 
-        mParams = new SuggestionStripViewParams(
+        mLayoutHelper = new SuggestionStripLayoutHelper(
                 context, attrs, defStyle, mWords, mDividers, mInfos);
 
         mMoreSuggestionsContainer = inflater.inflate(R.layout.more_suggestions, null);
@@ -657,24 +131,25 @@
     public void setSuggestions(final SuggestedWords suggestedWords) {
         clear();
         mSuggestedWords = suggestedWords;
-        mParams.layout(mSuggestedWords, mSuggestionsStrip, this, getWidth());
+        mLayoutHelper.layout(mSuggestedWords, mSuggestionsStrip, this, getWidth());
         if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
             ResearchLogger.suggestionStripView_setSuggestions(mSuggestedWords);
         }
     }
 
     public int setMoreSuggestionsHeight(final int remainingHeight) {
-        return mParams.setMoreSuggestionsHeight(remainingHeight);
+        return mLayoutHelper.setMoreSuggestionsHeight(remainingHeight);
     }
 
     public boolean isShowingAddToDictionaryHint() {
         return mSuggestionsStrip.getChildCount() > 0
-                && mParams.isAddToDictionaryShowing(mSuggestionsStrip.getChildAt(0));
+                && mLayoutHelper.isAddToDictionaryShowing(mSuggestionsStrip.getChildAt(0));
     }
 
     public void showAddToDictionaryHint(final String word, final CharSequence hintText) {
         clear();
-        mParams.layoutAddToDictionaryHint(word, mSuggestionsStrip, getWidth(), hintText, this);
+        mLayoutHelper.layoutAddToDictionaryHint(
+                word, mSuggestionsStrip, getWidth(), hintText, this);
     }
 
     public boolean dismissAddToDictionaryHint() {
@@ -739,29 +214,29 @@
         if (parentKeyboard == null) {
             return false;
         }
-        final SuggestionStripViewParams params = mParams;
-        if (!params.mMoreSuggestionsAvailable) {
+        final SuggestionStripLayoutHelper layoutHelper = mLayoutHelper;
+        if (!layoutHelper.mMoreSuggestionsAvailable) {
             return false;
         }
         final int stripWidth = getWidth();
         final View container = mMoreSuggestionsContainer;
         final int maxWidth = stripWidth - container.getPaddingLeft() - container.getPaddingRight();
         final MoreSuggestions.Builder builder = mMoreSuggestionsBuilder;
-        builder.layout(mSuggestedWords, params.mSuggestionsCountInStrip, maxWidth,
-                (int)(maxWidth * params.mMinMoreSuggestionsWidth),
-                params.getMaxMoreSuggestionsRow(), parentKeyboard);
+        builder.layout(mSuggestedWords, layoutHelper.mSuggestionsCountInStrip, maxWidth,
+                (int)(maxWidth * layoutHelper.mMinMoreSuggestionsWidth),
+                layoutHelper.getMaxMoreSuggestionsRow(), parentKeyboard);
         mMoreSuggestionsView.setKeyboard(builder.build());
         container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
 
         final MoreKeysPanel moreKeysPanel = mMoreSuggestionsView;
         final int pointX = stripWidth / 2;
-        final int pointY = -params.mMoreSuggestionsBottomGap;
+        final int pointY = -layoutHelper.mMoreSuggestionsBottomGap;
         moreKeysPanel.showMoreKeysPanel(this, mMoreSuggestionsController, pointX, pointY,
                 mMoreSuggestionsListener);
         mMoreSuggestionsMode = MORE_SUGGESTIONS_CHECKING_MODAL_OR_SLIDING;
         mOriginX = mLastX;
         mOriginY = mLastY;
-        for (int i = 0; i < params.mSuggestionsCountInStrip; i++) {
+        for (int i = 0; i < layoutHelper.mSuggestionsCountInStrip; i++) {
             mWords.get(i).setPressed(false);
         }
         return true;
@@ -832,8 +307,8 @@
 
     @Override
     public void onClick(final View view) {
-        if (mParams.isAddToDictionaryShowing(view)) {
-            mListener.addWordToUserDictionary(mParams.getAddToDictionaryWord().toString());
+        if (mLayoutHelper.isAddToDictionaryShowing(view)) {
+            mListener.addWordToUserDictionary(mLayoutHelper.getAddToDictionaryWord().toString());
             clear();
             return;
         }
