diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index 65eb1712a09590d8102e8900ddba736bfcc46003..3f0773e156a18ccd60eed8919b5023afbab3f307 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -440,9 +440,6 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
                 attr, R.styleable.Keyboard_Include);
         final TypedArray keyAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Key);
         int keyboardLayout = 0;
-        float savedDefaultKeyWidth = 0;
-        int savedDefaultKeyLabelFlags = 0;
-        int savedDefaultBackgroundType = Key.BACKGROUND_TYPE_NORMAL;
         try {
             XmlParseUtils.checkAttributeExists(
                     keyboardAttr, R.styleable.Keyboard_Include_keyboardLayout, "keyboardLayout",
@@ -450,24 +447,10 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
             keyboardLayout = keyboardAttr.getResourceId(
                     R.styleable.Keyboard_Include_keyboardLayout, 0);
             if (row != null) {
-                if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {
-                    // Override current x coordinate.
-                    row.setXPos(row.getKeyX(keyAttr));
-                }
-                // TODO: Remove this if-clause and do the same as backgroundType below.
-                savedDefaultKeyWidth = row.getDefaultKeyWidth();
-                if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyWidth)) {
-                    // Override default key width.
-                    row.setDefaultKeyWidth(row.getKeyWidth(keyAttr));
-                }
-                savedDefaultKeyLabelFlags = row.getDefaultKeyLabelFlags();
-                // Bitwise-or default keyLabelFlag if exists.
-                row.setDefaultKeyLabelFlags(keyAttr.getInt(
-                        R.styleable.Keyboard_Key_keyLabelFlags, 0) | savedDefaultKeyLabelFlags);
-                savedDefaultBackgroundType = row.getDefaultBackgroundType();
-                // Override default backgroundType if exists.
-                row.setDefaultBackgroundType(keyAttr.getInt(
-                        R.styleable.Keyboard_Key_backgroundType, savedDefaultBackgroundType));
+                // Override current x coordinate.
+                row.setXPos(row.getKeyX(keyAttr));
+                // Push current Row attributes and update with new attributes.
+                row.pushRowAttributes(keyAttr);
             }
         } finally {
             keyboardAttr.recycle();
@@ -484,10 +467,8 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
             parseMerge(parserForInclude, row, skip);
         } finally {
             if (row != null) {
-                // Restore default keyWidth, keyLabelFlags, and backgroundType.
-                row.setDefaultKeyWidth(savedDefaultKeyWidth);
-                row.setDefaultKeyLabelFlags(savedDefaultKeyLabelFlags);
-                row.setDefaultBackgroundType(savedDefaultBackgroundType);
+                // Restore Row attributes.
+                row.popRowAttributes();
             }
             parserForInclude.close();
         }
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
index 23c0b91e60a0061194761971818e7c9a6dca32a5..0f9497c27795f3ac034b0f433b2576e6d8ea6d55 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
@@ -23,10 +23,13 @@ import android.util.Xml;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.ResourceUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 
+import java.util.ArrayDeque;
+
 /**
  * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate.
  * Some of the key size defaults can be overridden per row from what the {@link Keyboard}
@@ -40,33 +43,68 @@ public final class KeyboardRow {
     private final KeyboardParams mParams;
     /** The height of this row. */
     private final int mRowHeight;
-    /** Default width of a key in this row. */
-    private float mDefaultKeyWidth;
-    /** Default keyLabelFlags in this row. */
-    private int mDefaultKeyLabelFlags;
-    /** Default backgroundType for this row */
-    private int mDefaultBackgroundType;
+
+    private final ArrayDeque<RowAttributes> mRowAttributesStack = CollectionUtils.newArrayDeque();
+
+    private static class RowAttributes {
+        /** Default width of a key in this row. */
+        public final float mDefaultKeyWidth;
+        /** Default keyLabelFlags in this row. */
+        public final int mDefaultKeyLabelFlags;
+        /** Default backgroundType for this row */
+        public final int mDefaultBackgroundType;
+
+        /**
+         * Parse and create key attributes. This constructor is used to parse Row tag.
+         *
+         * @param keyAttr an attributes array of Row tag.
+         * @param defaultKeyWidth a default key width.
+         * @param keyboardWidth the keyboard width that is required to calculate keyWidth attribute.
+         */
+        public RowAttributes(final TypedArray keyAttr, final float defaultKeyWidth,
+                final int keyboardWidth) {
+            mDefaultKeyWidth = keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
+                    keyboardWidth, keyboardWidth, defaultKeyWidth);
+            mDefaultKeyLabelFlags = keyAttr.getInt(R.styleable.Keyboard_Key_keyLabelFlags, 0);
+            mDefaultBackgroundType = keyAttr.getInt(R.styleable.Keyboard_Key_backgroundType,
+                    Key.BACKGROUND_TYPE_NORMAL);
+        }
+
+        /**
+         * Parse and update key attributes using default attributes. This constructor is used
+         * to parse include tag.
+         *
+         * @param keyAttr an attributes array of include tag.
+         * @param defaultRowAttr default Row attributes.
+         * @param keyboardWidth the keyboard width that is required to calculate keyWidth attribute.
+         */
+        public RowAttributes(final TypedArray keyAttr, final RowAttributes defaultRowAttr,
+                final int keyboardWidth) {
+            mDefaultKeyWidth = keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
+                    keyboardWidth, keyboardWidth, defaultRowAttr.mDefaultKeyWidth);
+            mDefaultKeyLabelFlags = keyAttr.getInt(R.styleable.Keyboard_Key_keyLabelFlags, 0)
+                    | defaultRowAttr.mDefaultKeyLabelFlags;
+            mDefaultBackgroundType = keyAttr.getInt(R.styleable.Keyboard_Key_backgroundType,
+                    defaultRowAttr.mDefaultBackgroundType);
+        }
+    }
 
     private final int mCurrentY;
     // Will be updated by {@link Key}'s constructor.
     private float mCurrentX;
 
-    public KeyboardRow(final Resources res, final KeyboardParams params, final XmlPullParser parser,
-            final int y) {
+    public KeyboardRow(final Resources res, final KeyboardParams params,
+            final XmlPullParser parser, final int y) {
         mParams = params;
         final TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
                 R.styleable.Keyboard);
         mRowHeight = (int)ResourceUtils.getDimensionOrFraction(keyboardAttr,
-                R.styleable.Keyboard_rowHeight,
-                params.mBaseHeight, params.mDefaultRowHeight);
+                R.styleable.Keyboard_rowHeight, params.mBaseHeight, params.mDefaultRowHeight);
         keyboardAttr.recycle();
         final TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
                 R.styleable.Keyboard_Key);
-        mDefaultKeyWidth = keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
-                params.mBaseWidth, params.mBaseWidth, params.mDefaultKeyWidth);
-        mDefaultKeyLabelFlags = keyAttr.getInt(R.styleable.Keyboard_Key_keyLabelFlags, 0);
-        mDefaultBackgroundType = keyAttr.getInt(R.styleable.Keyboard_Key_backgroundType,
-                Key.BACKGROUND_TYPE_NORMAL);
+        mRowAttributesStack.push(new RowAttributes(
+                keyAttr, params.mDefaultKeyWidth, params.mBaseWidth));
         keyAttr.recycle();
 
         mCurrentY = y;
@@ -77,28 +115,26 @@ public final class KeyboardRow {
         return mRowHeight;
     }
 
-    public float getDefaultKeyWidth() {
-        return mDefaultKeyWidth;
+    public void pushRowAttributes(final TypedArray keyAttr) {
+        final RowAttributes newAttributes = new RowAttributes(
+                keyAttr, mRowAttributesStack.peek(), mParams.mBaseWidth);
+        mRowAttributesStack.push(newAttributes);
     }
 
-    public void setDefaultKeyWidth(final float defaultKeyWidth) {
-        mDefaultKeyWidth = defaultKeyWidth;
+    public void popRowAttributes() {
+        mRowAttributesStack.pop();
     }
 
-    public int getDefaultKeyLabelFlags() {
-        return mDefaultKeyLabelFlags;
+    public float getDefaultKeyWidth() {
+        return mRowAttributesStack.peek().mDefaultKeyWidth;
     }
 
-    public void setDefaultKeyLabelFlags(final int keyLabelFlags) {
-        mDefaultKeyLabelFlags = keyLabelFlags;
+    public int getDefaultKeyLabelFlags() {
+        return mRowAttributesStack.peek().mDefaultKeyLabelFlags;
     }
 
     public int getDefaultBackgroundType() {
-        return mDefaultBackgroundType;
-    }
-
-    public void setDefaultBackgroundType(final int backgroundType) {
-        mDefaultBackgroundType = backgroundType;
+        return mRowAttributesStack.peek().mDefaultBackgroundType;
     }
 
     public void setXPos(final float keyXPos) {
@@ -131,13 +167,9 @@ public final class KeyboardRow {
         return Math.max(keyXPos + keyboardRightEdge, mCurrentX);
     }
 
-    public float getKeyWidth(final TypedArray keyAttr) {
-        return getKeyWidth(keyAttr, mCurrentX);
-    }
-
     public float getKeyWidth(final TypedArray keyAttr, final float keyXPos) {
         if (keyAttr == null) {
-            return mDefaultKeyWidth;
+            return getDefaultKeyWidth();
         }
         final int widthType = ResourceUtils.getEnumValue(keyAttr,
                 R.styleable.Keyboard_Key_keyWidth, KEYWIDTH_NOT_ENUM);
@@ -149,7 +181,7 @@ public final class KeyboardRow {
             return keyboardRightEdge - keyXPos;
         default: // KEYWIDTH_NOT_ENUM
             return keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
-                    mParams.mBaseWidth, mParams.mBaseWidth, mDefaultKeyWidth);
+                    mParams.mBaseWidth, mParams.mBaseWidth, getDefaultKeyWidth());
         }
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
index 98f0d8b6863403ef064c0fc9dcd6bc6c0e926d0a..cc25102cea88b77d1dc8f317a847c9ff03449534 100644
--- a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin.utils;
 
 import android.util.SparseArray;
 
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -94,6 +95,10 @@ public final class CollectionUtils {
         return new CopyOnWriteArrayList<E>(array);
     }
 
+    public static <E> ArrayDeque<E> newArrayDeque() {
+        return new ArrayDeque<E>();
+    }
+
     public static <E> SparseArray<E> newSparseArray() {
         return new SparseArray<E>();
     }