Merge "Allow LogUnits to hold >1 word"
diff --git a/dictionaries/en_GB_wordlist.combined.gz b/dictionaries/en_GB_wordlist.combined.gz
index b3e5cfc..93c5f3d 100644
--- a/dictionaries/en_GB_wordlist.combined.gz
+++ b/dictionaries/en_GB_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/en_US_wordlist.combined.gz b/dictionaries/en_US_wordlist.combined.gz
index 67328d8..c2421dc 100644
--- a/dictionaries/en_US_wordlist.combined.gz
+++ b/dictionaries/en_US_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/en_wordlist.combined.gz b/dictionaries/en_wordlist.combined.gz
index 7fc6cff..3732993 100644
--- a/dictionaries/en_wordlist.combined.gz
+++ b/dictionaries/en_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/fr_wordlist.combined.gz b/dictionaries/fr_wordlist.combined.gz
index c7c6977..7de4625 100644
--- a/dictionaries/fr_wordlist.combined.gz
+++ b/dictionaries/fr_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/ru_wordlist.combined.gz b/dictionaries/ru_wordlist.combined.gz
index 4f92805..253c515 100644
--- a/dictionaries/ru_wordlist.combined.gz
+++ b/dictionaries/ru_wordlist.combined.gz
Binary files differ
diff --git a/java/res/color/setup_step_action_background.xml b/java/res/color/setup_step_action_background.xml
new file mode 100644
index 0000000..79120b4
--- /dev/null
+++ b/java/res/color/setup_step_action_background.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:state_focused="true"
+        android:color="@color/setup_text_action" />
+    <item
+        android:state_pressed="true"
+        android:color="@color/setup_text_action" />
+    <item
+        android:color="@color/setup_step_background" />
+</selector>
diff --git a/java/res/drawable/setup_step_action_color.xml b/java/res/color/setup_step_action_color.xml
similarity index 100%
rename from java/res/drawable/setup_step_action_color.xml
rename to java/res/color/setup_step_action_color.xml
diff --git a/java/res/drawable-hdpi/unbundled_check_01.png b/java/res/drawable-hdpi/unbundled_check_01.png
index 8234399..42cce2f 100644
--- a/java/res/drawable-hdpi/unbundled_check_01.png
+++ b/java/res/drawable-hdpi/unbundled_check_01.png
Binary files differ
diff --git a/java/res/drawable-hdpi/unbundled_check_02.png b/java/res/drawable-hdpi/unbundled_check_02.png
index 6ccd07b..dcd120e 100644
--- a/java/res/drawable-hdpi/unbundled_check_02.png
+++ b/java/res/drawable-hdpi/unbundled_check_02.png
Binary files differ
diff --git a/java/res/drawable-hdpi/unbundled_earth_01.png b/java/res/drawable-hdpi/unbundled_earth_01.png
index 3d22f3b..4a0f087 100644
--- a/java/res/drawable-hdpi/unbundled_earth_01.png
+++ b/java/res/drawable-hdpi/unbundled_earth_01.png
Binary files differ
diff --git a/java/res/drawable-hdpi/unbundled_earth_02.png b/java/res/drawable-hdpi/unbundled_earth_02.png
index 1998aea..f4bd421 100644
--- a/java/res/drawable-hdpi/unbundled_earth_02.png
+++ b/java/res/drawable-hdpi/unbundled_earth_02.png
Binary files differ
diff --git a/java/res/drawable-hdpi/unbundled_key_01.png b/java/res/drawable-hdpi/unbundled_key_01.png
index 84591ec..87c9e2c 100644
--- a/java/res/drawable-hdpi/unbundled_key_01.png
+++ b/java/res/drawable-hdpi/unbundled_key_01.png
Binary files differ
diff --git a/java/res/drawable-hdpi/unbundled_key_02.png b/java/res/drawable-hdpi/unbundled_key_02.png
index f366e52..0747384 100644
--- a/java/res/drawable-hdpi/unbundled_key_02.png
+++ b/java/res/drawable-hdpi/unbundled_key_02.png
Binary files differ
diff --git a/java/res/drawable-hdpi/unbundled_select_01.png b/java/res/drawable-hdpi/unbundled_select_01.png
index 3887fe4..bb3de2f 100644
--- a/java/res/drawable-hdpi/unbundled_select_01.png
+++ b/java/res/drawable-hdpi/unbundled_select_01.png
Binary files differ
diff --git a/java/res/drawable-hdpi/unbundled_select_02.png b/java/res/drawable-hdpi/unbundled_select_02.png
index 6a99b6b..e56fdab 100644
--- a/java/res/drawable-hdpi/unbundled_select_02.png
+++ b/java/res/drawable-hdpi/unbundled_select_02.png
Binary files differ
diff --git a/java/res/drawable-mdpi/unbundled_check_01.png b/java/res/drawable-mdpi/unbundled_check_01.png
new file mode 100644
index 0000000..d0d02a3
--- /dev/null
+++ b/java/res/drawable-mdpi/unbundled_check_01.png
Binary files differ
diff --git a/java/res/drawable-mdpi/unbundled_check_02.png b/java/res/drawable-mdpi/unbundled_check_02.png
new file mode 100644
index 0000000..d34fa22
--- /dev/null
+++ b/java/res/drawable-mdpi/unbundled_check_02.png
Binary files differ
diff --git a/java/res/drawable-mdpi/unbundled_earth_01.png b/java/res/drawable-mdpi/unbundled_earth_01.png
new file mode 100644
index 0000000..ba60181
--- /dev/null
+++ b/java/res/drawable-mdpi/unbundled_earth_01.png
Binary files differ
diff --git a/java/res/drawable-mdpi/unbundled_earth_02.png b/java/res/drawable-mdpi/unbundled_earth_02.png
new file mode 100644
index 0000000..9c52638
--- /dev/null
+++ b/java/res/drawable-mdpi/unbundled_earth_02.png
Binary files differ
diff --git a/java/res/drawable-mdpi/unbundled_key_01.png b/java/res/drawable-mdpi/unbundled_key_01.png
new file mode 100644
index 0000000..8cd72db
--- /dev/null
+++ b/java/res/drawable-mdpi/unbundled_key_01.png
Binary files differ
diff --git a/java/res/drawable-mdpi/unbundled_key_02.png b/java/res/drawable-mdpi/unbundled_key_02.png
new file mode 100644
index 0000000..4ef6e0c
--- /dev/null
+++ b/java/res/drawable-mdpi/unbundled_key_02.png
Binary files differ
diff --git a/java/res/drawable-mdpi/unbundled_select_01.png b/java/res/drawable-mdpi/unbundled_select_01.png
new file mode 100644
index 0000000..9ab008a
--- /dev/null
+++ b/java/res/drawable-mdpi/unbundled_select_01.png
Binary files differ
diff --git a/java/res/drawable-mdpi/unbundled_select_02.png b/java/res/drawable-mdpi/unbundled_select_02.png
new file mode 100644
index 0000000..8af807b
--- /dev/null
+++ b/java/res/drawable-mdpi/unbundled_select_02.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/unbundled_check_01.png b/java/res/drawable-xhdpi/unbundled_check_01.png
new file mode 100644
index 0000000..1300a7f
--- /dev/null
+++ b/java/res/drawable-xhdpi/unbundled_check_01.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/unbundled_check_02.png b/java/res/drawable-xhdpi/unbundled_check_02.png
new file mode 100644
index 0000000..7151886
--- /dev/null
+++ b/java/res/drawable-xhdpi/unbundled_check_02.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/unbundled_earth_01.png b/java/res/drawable-xhdpi/unbundled_earth_01.png
new file mode 100644
index 0000000..24b6634
--- /dev/null
+++ b/java/res/drawable-xhdpi/unbundled_earth_01.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/unbundled_earth_02.png b/java/res/drawable-xhdpi/unbundled_earth_02.png
new file mode 100644
index 0000000..59aa031
--- /dev/null
+++ b/java/res/drawable-xhdpi/unbundled_earth_02.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/unbundled_key_01.png b/java/res/drawable-xhdpi/unbundled_key_01.png
new file mode 100644
index 0000000..c8b117b
--- /dev/null
+++ b/java/res/drawable-xhdpi/unbundled_key_01.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/unbundled_key_02.png b/java/res/drawable-xhdpi/unbundled_key_02.png
new file mode 100644
index 0000000..dc2da56
--- /dev/null
+++ b/java/res/drawable-xhdpi/unbundled_key_02.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/unbundled_select_01.png b/java/res/drawable-xhdpi/unbundled_select_01.png
new file mode 100644
index 0000000..baf1e55
--- /dev/null
+++ b/java/res/drawable-xhdpi/unbundled_select_01.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/unbundled_select_02.png b/java/res/drawable-xhdpi/unbundled_select_02.png
new file mode 100644
index 0000000..ad1058e
--- /dev/null
+++ b/java/res/drawable-xhdpi/unbundled_select_02.png
Binary files differ
diff --git a/java/res/drawable/ic_setup_step3_finish.xml b/java/res/drawable/ic_setup_finish.xml
similarity index 100%
rename from java/res/drawable/ic_setup_step3_finish.xml
rename to java/res/drawable/ic_setup_finish.xml
diff --git a/java/res/layout-land/setup_steps_screen.xml b/java/res/layout-land/setup_steps_screen.xml
new file mode 100644
index 0000000..0b4a096
--- /dev/null
+++ b/java/res/layout-land/setup_steps_screen.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    android:baselineAligned="false">
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="@integer/setup_title_weight_in_screen"
+        android:orientation="vertical">
+        <include layout="@layout/setup_steps_title" />
+    </LinearLayout>
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="@integer/setup_body_weight_in_screen"
+        android:orientation="vertical">
+        <include layout="@layout/setup_steps_cards" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/java/res/layout-land/setup_welcome_screen.xml b/java/res/layout-land/setup_welcome_screen.xml
new file mode 100644
index 0000000..8b162e2
--- /dev/null
+++ b/java/res/layout-land/setup_welcome_screen.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    android:baselineAligned="false">
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="@integer/setup_title_weight_in_screen"
+        android:orientation="vertical">
+        <include layout="@layout/setup_welcome_title" />
+    </LinearLayout>
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="@integer/setup_body_weight_in_screen"
+        android:orientation="vertical">
+        <include layout="@layout/setup_welcome_video" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/java/res/layout/setup_start_indicator_label.xml b/java/res/layout/setup_start_indicator_label.xml
new file mode 100644
index 0000000..33854bb
--- /dev/null
+++ b/java/res/layout/setup_start_indicator_label.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <view class="com.android.inputmethod.latin.setup.SetupStartIndicatorView$LabelView"
+        android:id="@+id/setup_start_label"
+        android:text="@string/setup_start_action"
+        android:gravity="end|center_vertical"
+        android:layout_width="0dp"
+        android:layout_weight="1.0"
+        style="@style/setupStepActionLabelStyleCommon" />
+    <view class="com.android.inputmethod.latin.setup.SetupStartIndicatorView$IndicatorView"
+        android:id="@+id/setup_start_indicator"
+        style="@style/setupStepStartIndicatorStyle" />
+</merge>
diff --git a/java/res/layout/setup_step.xml b/java/res/layout/setup_step.xml
index c15d07b..c6462e9 100644
--- a/java/res/layout/setup_step.xml
+++ b/java/res/layout/setup_step.xml
@@ -25,34 +25,14 @@
     <TextView
         android:id="@+id/setup_step_title"
         style="@style/setupStepTitleStyle"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
         android:paddingTop="16dp"
-        android:paddingBottom="16dp"
-        android:paddingLeft="24dp"
-        android:paddingRight="24dp" />
+        android:paddingBottom="16dp" />
     <TextView
         android:id="@+id/setup_step_instruction"
         style="@style/setupStepInstructionStyle"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingBottom="16dp"
-        android:paddingLeft="24dp"
-        android:paddingRight="24dp" />
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="2dp" />
-    <Button
+        android:paddingBottom="16dp" />
+    <TextView
         android:id="@+id/setup_step_action_label"
         style="@style/setupStepActionLabelStyle"
-        android:gravity="center_vertical"
-        android:drawablePadding="12dp"
-        android:layout_width="match_parent"
-        android:layout_height="48dp"
-        android:clickable="true"
-        android:focusable="true"
-        android:paddingLeft="12dp"
-        android:paddingStart="12dp"
-        android:paddingRight="24dp"
-        android:paddingEnd="24dp" />
+        android:layout_marginTop="2dp" />
 </LinearLayout>
diff --git a/java/res/layout/setup_steps_cards.xml b/java/res/layout/setup_steps_cards.xml
new file mode 100644
index 0000000..17207d3
--- /dev/null
+++ b/java/res/layout/setup_steps_cards.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <LinearLayout
+        android:id="@+id/setup_step_bullets"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:orientation="horizontal">
+        <TextView
+            android:id="@+id/setup_step1_bullet"
+            style="@style/setupStepBulletStyle"
+            android:text="@string/setup_step1_bullet" />
+        <TextView
+            android:id="@+id/setup_step2_bullet"
+            style="@style/setupStepBulletStyle"
+            android:text="@string/setup_step2_bullet" />
+        <TextView
+            android:id="@+id/setup_step3_bullet"
+            style="@style/setupStepBulletStyle"
+            android:text="@string/setup_step3_bullet" />
+    </LinearLayout>
+    <com.android.inputmethod.latin.setup.SetupStepIndicatorView
+        android:id="@+id/setup_step_indicator"
+        android:layout_width="match_parent"
+        android:layout_height="24dp" />
+    <FrameLayout
+        android:id="@+id/setup_steps_pane"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <include
+            android:id="@+id/setup_step1"
+            layout="@layout/setup_step" />
+        <include
+            android:id="@+id/setup_step2"
+            layout="@layout/setup_step" />
+        <include
+            android:id="@+id/setup_step3"
+            layout="@layout/setup_step" />
+    </FrameLayout>
+    <TextView
+        android:id="@+id/setup_finish"
+        android:text="@string/setup_finish_action"
+        style="@style/setupStepActionLabelStyle"
+        android:layout_marginTop="2dp" />
+</merge>
diff --git a/java/res/layout/setup_steps_screen.xml b/java/res/layout/setup_steps_screen.xml
new file mode 100644
index 0000000..1159c0a
--- /dev/null
+++ b/java/res/layout/setup_steps_screen.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <include layout="@layout/setup_steps_title" />
+    <include layout="@layout/setup_steps_cards" />
+</LinearLayout>
diff --git a/java/res/layout/setup_steps_title.xml b/java/res/layout/setup_steps_title.xml
new file mode 100644
index 0000000..e3694bf
--- /dev/null
+++ b/java/res/layout/setup_steps_title.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <TextView
+        android:id="@+id/setup_title"
+        style="@style/setupTitleStyle"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true" />
+</merge>
diff --git a/java/res/layout/setup_welcome_screen.xml b/java/res/layout/setup_welcome_screen.xml
new file mode 100644
index 0000000..44e98e2
--- /dev/null
+++ b/java/res/layout/setup_welcome_screen.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <include layout="@layout/setup_welcome_title" />
+    <include layout="@layout/setup_welcome_video" />
+</LinearLayout>
diff --git a/java/res/layout/setup_welcome_title.xml b/java/res/layout/setup_welcome_title.xml
new file mode 100644
index 0000000..6e6d781
--- /dev/null
+++ b/java/res/layout/setup_welcome_title.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <TextView
+        android:id="@+id/setup_welcome_title"
+        style="@style/setupTitleStyle"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true" />
+    <TextView
+        android:id="@+id/setup_welcome_description"
+        android:text="@string/setup_welcome_additional_description"
+        android:layout_marginTop="12dp"
+        style="@style/setupWelcomeDescritpionStyle" />
+</merge>
diff --git a/java/res/layout/setup_welcome_video.xml b/java/res/layout/setup_welcome_video.xml
new file mode 100644
index 0000000..a72fbd7
--- /dev/null
+++ b/java/res/layout/setup_welcome_video.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <VideoView
+        android:id="@+id/setup_welcome_video"
+        android:layout_margin="36dp"
+        android:layout_width="240dp"
+        android:layout_height="150dp"
+        android:layout_centerHorizontal="true" />
+    <com.android.inputmethod.latin.setup.SetupStartIndicatorView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+</merge>
diff --git a/java/res/layout/setup_wizard.xml b/java/res/layout/setup_wizard.xml
index acbbe30..e766e4c 100644
--- a/java/res/layout/setup_wizard.xml
+++ b/java/res/layout/setup_wizard.xml
@@ -18,61 +18,18 @@
 */
 -->
 
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:fillViewport="true">
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:background="@color/setup_background"
-        android:paddingLeft="@dimen/setup_horizontal_padding"
-        android:paddingRight="@dimen/setup_horizontal_padding"
-        android:paddingTop="16dp"
-        android:paddingBottom="16dp">
-        <TextView
-            android:id="@+id/setup_title"
-            style="@style/setupTitleStyle"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentLeft="true"
-            android:layout_alignParentStart="true"
-            android:layout_alignParentTop="true" />
-        <LinearLayout
-            android:id="@+id/setup_step_bullets"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/setup_title"
-            android:paddingTop="16dp"
-            android:orientation="horizontal">
-            <TextView
-                style="@style/setupStepBulletStyle"
-                android:text="@string/setup_step1_bullet" />
-            <TextView
-                style="@style/setupStepBulletStyle"
-                android:text="@string/setup_step2_bullet" />
-            <TextView
-                style="@style/setupStepBulletStyle"
-                android:text="@string/setup_step3_bullet" />
-        </LinearLayout>
-        <com.android.inputmethod.latin.setup.SetupStepIndicatorView
-            android:id="@+id/setup_step_indicator"
-            android:layout_width="match_parent"
-            android:layout_height="24dp"
-            android:layout_below="@id/setup_step_bullets" />
-        <FrameLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/setup_step_indicator">
-            <include
-                android:id="@+id/setup_step1"
-                layout="@layout/setup_step" />
-            <include
-                android:id="@+id/setup_step2"
-                layout="@layout/setup_step" />
-            <include
-                android:id="@+id/setup_step3"
-                layout="@layout/setup_step" />
-        </FrameLayout>
-    </RelativeLayout>
-</ScrollView>
+    android:background="@color/setup_background"
+    android:paddingLeft="@dimen/setup_horizontal_padding"
+    android:paddingRight="@dimen/setup_horizontal_padding"
+    android:paddingTop="16dp"
+    android:paddingBottom="16dp">
+    <include
+        android:id="@+id/setup_welcome_screen"
+        layout="@layout/setup_welcome_screen" />
+    <include
+        android:id="@+id/setup_steps_screen"
+        layout="@layout/setup_steps_screen" />
+</FrameLayout>
diff --git a/java/res/raw/main_en.dict b/java/res/raw/main_en.dict
index 526761c..086874d 100644
--- a/java/res/raw/main_en.dict
+++ b/java/res/raw/main_en.dict
Binary files differ
diff --git a/java/res/raw/main_fr.dict b/java/res/raw/main_fr.dict
index 7520898..9044c7e 100644
--- a/java/res/raw/main_fr.dict
+++ b/java/res/raw/main_fr.dict
Binary files differ
diff --git a/java/res/raw/main_ru.dict b/java/res/raw/main_ru.dict
index 216ff09..9fd6133 100644
--- a/java/res/raw/main_ru.dict
+++ b/java/res/raw/main_ru.dict
Binary files differ
diff --git a/java/res/raw/setup_welcome_video.mp4 b/java/res/raw/setup_welcome_video.mp4
new file mode 100644
index 0000000..09357d8
--- /dev/null
+++ b/java/res/raw/setup_welcome_video.mp4
Binary files differ
diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml
index e42ed3f..03a8b93 100644
--- a/java/res/values-am/strings.xml
+++ b/java/res/values-am/strings.xml
@@ -162,7 +162,7 @@
     <string name="not_now" msgid="6172462888202790482">"አሁን አልፈልግም"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"ተመሳሳዩ የግብዓት ቅጥ አስቀድሞ አለ፦ <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"የተገልጋይነት ጥናት ሁነታ"</string>
-    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"የቁልፍ ረጅም ጭነት መዘግየት"</string>
+    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"የሰሌዳ ቁልፍ ጠቅታ በመጫን መዘግየት"</string>
     <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"የቁልፍ ጭነት ንዝረት ርዝመት"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"የቁልፍ ጭነት ድምጽ መጠን"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"ውጫዊ የመዝገበቃላት ፋይል አንብብ"</string>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index 74aa556..3a9b579 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -162,8 +162,8 @@
     <string name="not_now" msgid="6172462888202790482">"Не сега"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Същият стил на въвеждане вече съществува: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим за изучаване на използваемостта"</string>
-    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Забавяне при продълж. натискане на клавишите"</string>
-    <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Продълж. на вибрир. при натискане на клавиш"</string>
+    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Забавяне при продълж. натискане"</string>
+    <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Продълж. на вибриране при натискане"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Сила на звука при натиск. на клавиш"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Четене на файл за външен речник"</string>
     <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"В папката „Изтегляния“ няма файлове за речник"</string>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index 1c8b16b..2da24af 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -42,15 +42,15 @@
     <string name="show_language_switch_key" msgid="5915478828318774384">"Tecla para cambiar de idioma"</string>
     <string name="show_language_switch_key_summary" msgid="7343403647474265713">"Mostrar cuando haya varios idiomas de entrada habilitados"</string>
     <string name="sliding_key_input_preview" msgid="6604262359510068370">"Mostrar indicador deslizante"</string>
-    <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Mostrar pista visual al deslizar desde Mayús o tecla de símbolos"</string>
-    <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Retraso al ampliar tecla"</string>
+    <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Mostrar pista visual al deslizar desde la tecla Mayús o la tecla de símbolos"</string>
+    <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Retraso para ampliar tecla"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Sin retraso"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predeterminado"</string>
     <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> ms"</string>
     <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir contactos"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizar nombres de contactos para sugerencias y correcciones"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Punto y espacio"</string>
-    <string name="use_double_space_period_summary" msgid="6532892187247952799">"Si tocas dos veces el espacio, se inserta un punto seguido de un espacio."</string>
+    <string name="use_double_space_period_summary" msgid="6532892187247952799">"Si tocas dos veces el espacio, se inserta un punto seguido de un espacio"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string>
     <string name="auto_cap_summary" msgid="7934452761022946874">"Poner la primera letra de cada palabra en mayúscula"</string>
     <string name="configure_dictionaries_title" msgid="4238652338556902049">"Diccionarios complementarios"</string>
@@ -162,7 +162,7 @@
     <string name="not_now" msgid="6172462888202790482">"Ahora no"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Ya existe el estilo de entrada <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>."</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo estudio de usabilidad"</string>
-    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Retraso pulsación prolongada"</string>
+    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Retraso de pulsación prolongada"</string>
     <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Duración vibración al pulsar"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volumen sonido al pulsar tecla"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Leer archivo de diccionario externo"</string>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index 48b9d9e..e7f5c96 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -139,7 +139,7 @@
     <string name="hint_add_to_dictionary" msgid="573678656946085380">"برای ذخیره دوباره لمس کنید"</string>
     <string name="has_dictionary" msgid="6071847973466625007">"دیکشنری موجود است"</string>
     <string name="prefs_enable_log" msgid="6620424505072963557">"فعال کردن بازخورد کاربر"</string>
-    <string name="prefs_description_log" msgid="7525225584555429211">"با ارسال خودکار آمار کاربرد و گزارش‌های خرابی، به بهبود این ویرایشگر روش ورودی کمک کنید"</string>
+    <string name="prefs_description_log" msgid="7525225584555429211">"با ارسال خودکار آمار استفاده و گزارش‌های خرابی، به بهبود این ویرایشگر روش ورودی کمک کنید"</string>
     <string name="keyboard_layout" msgid="8451164783510487501">"طرح زمینه صفحه‌کلید"</string>
     <string name="subtype_en_GB" msgid="88170601942311355">"انگلیسی (بریتانیا)"</string>
     <string name="subtype_en_US" msgid="6160452336634534239">"انگلیسی (امریکا)"</string>
@@ -166,8 +166,8 @@
     <string name="not_now" msgid="6172462888202790482">"اکنون خیر"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"سبک ورودی مشابهی در حال حاضر وجود دارد: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"حالت بررسی قابلیت استفاده"</string>
-    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"تأخیر فشردن طولانی مدت کلید"</string>
-    <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"طول مدت لرزش فشردن کلید"</string>
+    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"تأخیر فشار طولانی کلید"</string>
+    <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"طول مدت لرزش در اثر فشردن کلید"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"میزان صدای فشردن کلید"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"خواندن فایل فرهنگ لغت خارجی"</string>
     <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"فایل فرهنگ لغتی در پوشه دانلودها وجود ندارد"</string>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index fc40bd1..caa98cc 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -162,8 +162,8 @@
     <string name="not_now" msgid="6172462888202790482">"Ikke nå"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Inndatastilen finnes allerede: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Bruksstudiemodus"</string>
-    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Forsinkelser i lange tastetrykk"</string>
-    <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrasjonsvarighet ved tastetrykk"</string>
+    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Forsinkelse lange tastetrykk"</string>
+    <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrasjonstid ved tastetrykk"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Lydstyrke ved tastetrykk"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Bruk en ekstern ordlistefil"</string>
     <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Det ligger ingen ordboksfiler i Nedlastinger-mappen"</string>
diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml
index 708d7fd..8702601 100644
--- a/java/res/values-sw/strings.xml
+++ b/java/res/values-sw/strings.xml
@@ -162,7 +162,7 @@
     <string name="not_now" msgid="6172462888202790482">"Sio sasa"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Mfumo sawa wa maingizo tayari upo: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modi ya uchunguzi wa utumizi"</string>
-    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Uchelewaji wa kubonyeza kitufe kwa muda mrefu"</string>
+    <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Ubofyaji kitufe kunakochelewa"</string>
     <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Bonyeza kitufe cha muda wa kutetema"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Bonyeza kitufe cha kiwango cha sauti"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Soma faili ya kamusi ya nje"</string>
diff --git a/java/res/values-sw600dp-land/setup-dimens.xml b/java/res/values-sw600dp-land/setup-dimens.xml
index 9aea214..e5051ea 100644
--- a/java/res/values-sw600dp-land/setup-dimens.xml
+++ b/java/res/values-sw600dp-land/setup-dimens.xml
@@ -16,5 +16,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <dimen name="setup_title_text_size">64sp</dimen>
+    <dimen name="setup_welcome_description_text_size">36sp</dimen>
     <dimen name="setup_horizontal_padding">96dp</dimen>
 </resources>
diff --git a/java/res/values-sw768dp-land/setup-dimens.xml b/java/res/values-sw768dp-land/setup-dimens.xml
index 0d2af17..34b7f42 100644
--- a/java/res/values-sw768dp-land/setup-dimens.xml
+++ b/java/res/values-sw768dp-land/setup-dimens.xml
@@ -16,5 +16,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <dimen name="setup_title_text_size">64sp</dimen>
+    <dimen name="setup_welcome_description_text_size">36sp</dimen>
     <dimen name="setup_horizontal_padding">192dp</dimen>
 </resources>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index 053222c..a0a6a67 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -51,7 +51,7 @@
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Öneri ve düzeltmeler için Kişiler\'deki adları kullan"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Çift boşlukla nokta ekleme"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Boşluk çubuğuna iki kez vurmak nokta ve ardından bir boşluk ekler"</string>
-    <string name="auto_cap" msgid="1719746674854628252">"Otomatik olarak büyük fark yap"</string>
+    <string name="auto_cap" msgid="1719746674854628252">"Otomatik olarak büyük harf yap"</string>
     <string name="auto_cap_summary" msgid="7934452761022946874">"Her cümlenin ilk kelimesini büyük harf yap"</string>
     <string name="configure_dictionaries_title" msgid="4238652338556902049">"Ek sözlükler"</string>
     <string name="main_dictionary" msgid="4798763781818361168">"Ana sözlük"</string>
diff --git a/java/res/values-v17/setup-styles.xml b/java/res/values-v17/setup-styles.xml
new file mode 100644
index 0000000..8a9d664
--- /dev/null
+++ b/java/res/values-v17/setup-styles.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="setupTitleStyle" parent="setupTitleStyleCommon">
+        <item name="android:layout_alignParentStart">true</item>
+    </style>
+    <style name="setupStepActionLabelStyle" parent="setupStepActionLabelStyleCommon">
+        <item name="android:paddingStart">12dp</item>
+        <item name="android:paddingEnd">24dp</item>
+    </style>
+</resources>
diff --git a/java/res/values/setup-dimens.xml b/java/res/values/setup-dimens.xml
index 007906d..1c6811f 100644
--- a/java/res/values/setup-dimens.xml
+++ b/java/res/values/setup-dimens.xml
@@ -16,5 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <dimen name="setup_title_text_size">46sp</dimen>
+    <dimen name="setup_welcome_description_text_size">26sp</dimen>
     <dimen name="setup_horizontal_padding">16dp</dimen>
+    <integer name="setup_title_weight_in_screen">40</integer>
+    <integer name="setup_body_weight_in_screen">60</integer>
 </resources>
diff --git a/java/res/values/setup-styles-common.xml b/java/res/values/setup-styles-common.xml
new file mode 100644
index 0000000..e9c72eb
--- /dev/null
+++ b/java/res/values/setup-styles-common.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="setupTitleStyleCommon">
+        <item name="android:textColor">@color/setup_text_dark</item>
+        <item name="android:textSize">@dimen/setup_title_text_size</item>
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+    </style>
+    <style name="setupWelcomeDescritpionStyle" parent="setupTitleStyle">
+        <item name="android:textSize">@dimen/setup_welcome_description_text_size</item>
+    </style>
+    <style name="setupStepBulletStyle">
+        <item name="android:textColor">@color/setup_text_dark</item>
+        <item name="android:textSize">22sp</item>
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_weight">1.0</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">center_horizontal</item>
+    </style>
+    <style name="setupStepBaseStyle">
+        <item name="android:textColor">@color/setup_text_dark</item>
+        <item name="android:background">@color/setup_step_background</item>
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:paddingLeft">24dp</item>
+        <item name="android:paddingRight">24dp</item>
+    </style>
+    <style name="setupStepTitleStyle" parent="setupStepBaseStyle">
+        <item name="android:textSize">22sp</item>
+    </style>
+    <style name="setupStepInstructionStyle" parent="setupStepBaseStyle">
+        <item name="android:textSize">14sp</item>
+    </style>
+    <style name="setupStepStartIndicatorStyle">
+        <item name="android:layout_width">24dp</item>
+        <item name="android:layout_height">48dp</item>
+    </style>
+    <style name="setupStepActionLabelStyleCommon" parent="setupStepBaseStyle">
+        <item name="android:textColor">@color/setup_step_action_color</item>
+        <item name="android:background">@drawable/setup_step_action_background</item>
+        <item name="android:layout_height">48dp</item>
+        <item name="android:paddingLeft">12dp</item>
+        <item name="android:textSize">18sp</item>
+        <item name="android:drawablePadding">12dp</item>
+        <item name="android:gravity">center_vertical</item>
+        <item name="android:clickable">true</item>
+        <item name="android:focusable">true</item>
+    </style>
+    <style name="setupStepStartActionLabelStyleCommon" parent="setupStepActionLabelStyleCommon">
+        <item name="android:paddingLeft">24dp</item>
+        <item name="android:paddingRight">24dp</item>
+    </style>
+</resources>
diff --git a/java/res/values/setup-styles.xml b/java/res/values/setup-styles.xml
index 420adcb..1ffe8ca 100644
--- a/java/res/values/setup-styles.xml
+++ b/java/res/values/setup-styles.xml
@@ -15,31 +15,6 @@
 -->
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <style name="setupTitleStyle">
-        <item name="android:textColor">@color/setup_text_dark</item>
-        <item name="android:textSize">@dimen/setup_title_text_size</item>
-    </style>
-    <style name="setupStepBulletStyle">
-        <item name="android:textColor">@color/setup_text_dark</item>
-        <item name="android:textSize">22sp</item>
-        <item name="android:layout_width">0dp</item>
-        <item name="android:layout_weight">1.0</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:gravity">center_horizontal</item>
-    </style>
-    <style name="setupStepTitleStyle">
-        <item name="android:background">@color/setup_step_background</item>
-        <item name="android:textColor">@color/setup_text_dark</item>
-        <item name="android:textSize">22sp</item>
-    </style>
-    <style name="setupStepInstructionStyle">
-        <item name="android:background">@color/setup_step_background</item>
-        <item name="android:textColor">@color/setup_text_dark</item>
-        <item name="android:textSize">14sp</item>
-    </style>
-    <style name="setupStepActionLabelStyle">
-        <item name="android:background">@drawable/setup_step_action_background</item>
-        <item name="android:textColor">@drawable/setup_step_action_color</item>
-        <item name="android:textSize">18sp</item>
-    </style>
+    <style name="setupTitleStyle" parent="setupTitleStyleCommon" />
+    <style name="setupStepActionLabelStyle" parent="setupStepActionLabelStyleCommon" />
 </resources>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 3d283de..10cfc78 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -448,6 +448,8 @@
     <string name="setup_welcome_additional_description">with Gesture Typing</string>
     <!-- The label of the button that starts the setup wizard. [CHAR_LIMIT=64] -->
     <string name="setup_start_action">Get started</string>
+    <!-- The label of the button that navigates the user to the next step of the setup wizard. [CHAR_LIMIT=64] -->
+    <string name="setup_next_action">Next step</string>
     <!-- Title of the setup wizard. [CHAR LIMT=40] -->
     <string name="setup_steps_title">"Setting up <xliff:g id="application_name">%s</xliff:g>"</string>
     <!-- Ordinal number of the 1st step in the setup wizard. [CHAR LIMIT=5] -->
@@ -456,16 +458,16 @@
     <string name="setup_step1_title">"Enable <xliff:g id="application_name">%s</xliff:g>"</string>
     <!-- Detailed instruction of the 1st step in the setup wizard. [CHAR LIMIT=80] -->
     <string name="setup_step1_instruction">"Please check \"<xliff:g id="application_name">%s</xliff:g>\" in your Language &amp; input settings. This will authorize it to run on your device."</string>
-    <!-- Title of the Language & input settings. This should be aligned with msgid="5292716747264442359" -->
-    <string name="setup_step1_action">Language &amp; input</string>
+    <!-- The label of the button that triggers the Language & input settings in order to enable the keyboard. [CHAR_LIMIT=64] -->
+    <string name="setup_step1_action">Enable in Settings</string>
     <!-- Ordinal number of the 2nd step in the setup wizard. [CHAR LIMIT=5] -->
     <string name="setup_step2_bullet" translatable="false">2</string>
     <!-- Title of the 2nd step in the setup wizard. [CHAR LIMIT=64] -->
     <string name="setup_step2_title">"Switch to <xliff:g id="application_name">%s</xliff:g>"</string>
     <!-- Detailed instruction of the 2nd step in the setup wizard. [CHAR LIMIT=80] -->
-    <string name="setup_step2_instruction">"Now that it's enabled, select \"<xliff:g id="application_name">%s</xliff:g>\", one more time to activate it."</string>
-    <!-- Title of the Input method picker. This should be aligned with msgid="4653387336791222978" -->
-    <string name="setup_step2_action">Choose input method</string>
+    <string name="setup_step2_instruction">"Next, select \"<xliff:g id="application_name">%s</xliff:g>\" as your active text-input method."</string>
+    <!-- The label of the button that triggers the choose input method dialog in order to select the keyboard. [CHAR_LIMIT=64] -->
+    <string name="setup_step2_action">Switch input methods</string>
     <!-- Ordinal number of the 3rd step in the setup wizard. [CHAR LIMIT=5] -->
     <string name="setup_step3_bullet" translatable="false">3</string>
     <!-- Title of the 3rd step in the setup wizard. [CHAR LIMIT=64] -->
@@ -477,7 +479,7 @@
     <!-- The label of the button that finishes the setup wizard. [CHAR_LIMIT=64] -->
     <string name="setup_finish_action">Finished</string>
     <!-- Option to show setup wizard icon. [CHAR LIMIT=30]-->
-    <string name="show_setup_wizard_icon" translatable="false">Show setup wizard icon</string>
+    <string name="show_setup_wizard_icon">Show setup wizard icon</string>
 
     <!-- The dictionary provider application name. Visible in Settings/Applications/Manage applications. -->
     <string name="app_name">Dictionary Provider</string>
diff --git a/java/src/com/android/inputmethod/compat/TextViewCompatUtils.java b/java/src/com/android/inputmethod/compat/TextViewCompatUtils.java
index d4f1ea8..f8e1902 100644
--- a/java/src/com/android/inputmethod/compat/TextViewCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/TextViewCompatUtils.java
@@ -22,23 +22,23 @@
 import java.lang.reflect.Method;
 
 public final class TextViewCompatUtils {
-    // Note that TextView.setCompoundDrawablesRelative(Drawable,Drawable,Drawable,Drawable) has
-    // been introduced in API level 17 (Build.VERSION_CODE.JELLY_BEAN_MR1).
-    private static final Method METHOD_setCompoundDrawablesRelative = CompatUtils.getMethod(
-            TextView.class, "setCompoundDrawablesRelative",
+    // Note that TextView.setCompoundDrawablesRelativeWithIntrinsicBounds(Drawable,Drawable,
+    // Drawable,Drawable) has been introduced in API level 17 (Build.VERSION_CODE.JELLY_BEAN_MR1).
+    private static final Method METHOD_setCompoundDrawablesRelativeWithIntrinsicBounds =
+            CompatUtils.getMethod(TextView.class, "setCompoundDrawablesRelativeWithIntrinsicBounds",
             Drawable.class, Drawable.class, Drawable.class, Drawable.class);
 
     private TextViewCompatUtils() {
         // This utility class is not publicly instantiable.
     }
 
-    public static void setCompoundDrawablesRelative(final TextView textView, final Drawable start,
-            final Drawable top, final Drawable end, final Drawable bottom) {
-        if (METHOD_setCompoundDrawablesRelative == null) {
-            textView.setCompoundDrawables(start, top, end, bottom);
+    public static void setCompoundDrawablesRelativeWithIntrinsicBounds(final TextView textView,
+            final Drawable start, final Drawable top, final Drawable end, final Drawable bottom) {
+        if (METHOD_setCompoundDrawablesRelativeWithIntrinsicBounds == null) {
+            textView.setCompoundDrawablesWithIntrinsicBounds(start, top, end, bottom);
             return;
         }
-        CompatUtils.invoke(textView, null, METHOD_setCompoundDrawablesRelative,
+        CompatUtils.invoke(textView, null, METHOD_setCompoundDrawablesRelativeWithIntrinsicBounds,
                 start, top, end, bottom);
     }
 }
diff --git a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
index df4a52f..faf5d3c 100644
--- a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
+++ b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
@@ -174,7 +174,7 @@
             final long downloadId = UpdateHandler.registerDownloadRequest(manager, request, db,
                     mWordList.mId, mWordList.mVersion);
             Utils.l("Starting download of", uri, "with id", downloadId);
-            PrivateLog.log("Starting download of " + uri + ", id : " + downloadId, context);
+            PrivateLog.log("Starting download of " + uri + ", id : " + downloadId);
         }
     }
 
@@ -333,7 +333,7 @@
                     mWordList.mRemoteFilename, mWordList.mLastUpdate, mWordList.mChecksum,
                     mWordList.mFileSize, mWordList.mVersion, mWordList.mFormatVersion);
             PrivateLog.log("Insert 'available' record for " + mWordList.mDescription
-                    + " and locale " + mWordList.mLocale, context);
+                    + " and locale " + mWordList.mLocale);
             db.insert(MetadataDbHelper.METADATA_TABLE_NAME, null, values);
         }
     }
@@ -383,7 +383,7 @@
                     mWordList.mChecksum, mWordList.mFileSize, mWordList.mVersion,
                     mWordList.mFormatVersion);
             PrivateLog.log("Insert 'preinstalled' record for " + mWordList.mDescription
-                    + " and locale " + mWordList.mLocale, context);
+                    + " and locale " + mWordList.mLocale);
             db.insert(MetadataDbHelper.METADATA_TABLE_NAME, null, values);
         }
     }
@@ -424,7 +424,7 @@
                     mWordList.mRemoteFilename, mWordList.mLastUpdate, mWordList.mChecksum,
                     mWordList.mFileSize, mWordList.mVersion, mWordList.mFormatVersion);
             PrivateLog.log("Updating record for " + mWordList.mDescription
-                    + " and locale " + mWordList.mLocale, context);
+                    + " and locale " + mWordList.mLocale);
             db.update(MetadataDbHelper.METADATA_TABLE_NAME, values,
                     MetadataDbHelper.WORDLISTID_COLUMN + " = ? AND "
                             + MetadataDbHelper.VERSION_COLUMN + " = ?",
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
index f8d1c4f..4fbe162 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
@@ -189,7 +189,7 @@
      */
     @Override
     public String getType(final Uri uri) {
-        PrivateLog.log("Asked for type of : " + uri, this);
+        PrivateLog.log("Asked for type of : " + uri);
         final int match = matchUri(uri);
         switch (match) {
             case NO_MATCH: return null;
@@ -220,7 +220,7 @@
     public Cursor query(final Uri uri, final String[] projection, final String selection,
             final String[] selectionArgs, final String sortOrder) {
         Utils.l("Uri =", uri);
-        PrivateLog.log("Query : " + uri, this);
+        PrivateLog.log("Query : " + uri);
         final String clientId = getClientId(uri);
         final int match = matchUri(uri);
         switch (match) {
@@ -228,7 +228,7 @@
             case DICTIONARY_V2_WHOLE_LIST:
                 final Cursor c = MetadataDbHelper.queryDictionaries(getContext(), clientId);
                 Utils.l("List of dictionaries with count", c.getCount());
-                PrivateLog.log("Returned a list of " + c.getCount() + " items", this);
+                PrivateLog.log("Returned a list of " + c.getCount() + " items");
                 return c;
             case DICTIONARY_V2_DICT_INFO:
                 // In protocol version 2, we return null if the client is unknown. Otherwise
@@ -248,10 +248,10 @@
                 // TODO: pass clientId to the following function
                 DictionaryService.updateNowIfNotUpdatedInAVeryLongTime(getContext());
                 if (null != dictFiles && dictFiles.size() > 0) {
-                    PrivateLog.log("Returned " + dictFiles.size() + " files", this);
+                    PrivateLog.log("Returned " + dictFiles.size() + " files");
                     return new ResourcePathCursor(dictFiles);
                 } else {
-                    PrivateLog.log("No dictionary files for this URL", this);
+                    PrivateLog.log("No dictionary files for this URL");
                     return new ResourcePathCursor(Collections.<WordListInfo>emptyList());
                 }
             // V2_METADATA and V2_DATAFILE are not supported for query()
@@ -488,7 +488,7 @@
     public Uri insert(final Uri uri, final ContentValues values)
             throws UnsupportedOperationException {
         if (null == uri || null == values) return null; // Should never happen but let's be safe
-        PrivateLog.log("Insert, uri = " + uri.toString(), this);
+        PrivateLog.log("Insert, uri = " + uri.toString());
         final String clientId = getClientId(uri);
         switch (matchUri(uri)) {
             case DICTIONARY_V2_METADATA:
@@ -517,7 +517,7 @@
                 break;
             case DICTIONARY_V1_WHOLE_LIST:
             case DICTIONARY_V1_DICT_INFO:
-                PrivateLog.log("Attempt to insert : " + uri, this);
+                PrivateLog.log("Attempt to insert : " + uri);
                 throw new UnsupportedOperationException(
                         "Insertion in the dictionary is not supported in this version");
         }
@@ -532,7 +532,7 @@
     @Override
     public int update(final Uri uri, final ContentValues values, final String selection,
             final String[] selectionArgs) throws UnsupportedOperationException {
-        PrivateLog.log("Attempt to update : " + uri, this);
+        PrivateLog.log("Attempt to update : " + uri);
         throw new UnsupportedOperationException("Updating dictionary words is not supported");
     }
 }
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
index 5817eb4..46bb554 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
@@ -21,7 +21,6 @@
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.os.IBinder;
 import android.text.format.DateUtils;
 import android.util.Log;
@@ -190,7 +189,7 @@
         // is still more recent than UPDATE_FREQUENCY, do nothing.
         if (!isLastUpdateAtLeastThisOld(context, UPDATE_FREQUENCY)) return;
 
-        PrivateLog.log("Date changed - registering alarm", context);
+        PrivateLog.log("Date changed - registering alarm");
         AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
 
         // Best effort to wake between midnight and MAX_ALARM_DELAY in the morning.
@@ -215,7 +214,7 @@
     private static boolean isLastUpdateAtLeastThisOld(final Context context, final long time) {
         final long now = System.currentTimeMillis();
         final long lastUpdate = MetadataDbHelper.getOldestUpdateTime(context);
-        PrivateLog.log("Last update was " + lastUpdate, context);
+        PrivateLog.log("Last update was " + lastUpdate);
         return lastUpdate + time < now;
     }
 
diff --git a/java/src/com/android/inputmethod/dictionarypack/LogProblemReporter.java b/java/src/com/android/inputmethod/dictionarypack/LogProblemReporter.java
index c127ad5..c9e128d 100644
--- a/java/src/com/android/inputmethod/dictionarypack/LogProblemReporter.java
+++ b/java/src/com/android/inputmethod/dictionarypack/LogProblemReporter.java
@@ -28,7 +28,8 @@
         TAG = tag;
     }
 
+    @Override
     public void report(final Exception e) {
-        Log.e(TAG, "Reporting problem : " + e);
+        Log.e(TAG, "Reporting problem", e);
     }
 }
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
index 55f545a..cb8e25e 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
@@ -16,13 +16,11 @@
 
 package com.android.inputmethod.dictionarypack;
 
-import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
-import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -309,8 +307,7 @@
      * @param uri the metadata URI we just downloaded
      */
     public static void saveLastUpdateTimeOfUri(final Context context, final String uri) {
-        PrivateLog.log("Save last update time of URI : " + uri + " " + System.currentTimeMillis(),
-                context);
+        PrivateLog.log("Save last update time of URI : " + uri + " " + System.currentTimeMillis());
         final ContentValues values = new ContentValues();
         values.put(CLIENT_LAST_UPDATE_DATE_COLUMN, System.currentTimeMillis());
         final SQLiteDatabase defaultDb = getDb(context, null);
diff --git a/java/src/com/android/inputmethod/dictionarypack/PrivateLog.java b/java/src/com/android/inputmethod/dictionarypack/PrivateLog.java
index 8593c1c..67dd7b9 100644
--- a/java/src/com/android/inputmethod/dictionarypack/PrivateLog.java
+++ b/java/src/com/android/inputmethod/dictionarypack/PrivateLog.java
@@ -16,7 +16,6 @@
 
 package com.android.inputmethod.dictionarypack;
 
-import android.content.ContentProvider;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.sqlite.SQLiteDatabase;
@@ -24,6 +23,7 @@
 
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.Locale;
 
 /**
  * Class to keep long-term log. This is inactive in production, and is only for debug purposes.
@@ -44,10 +44,10 @@
             + COLUMN_EVENT + " TEXT);";
 
     private static final SimpleDateFormat sDateFormat =
-            new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+            new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.US);
 
     private static PrivateLog sInstance = new PrivateLog();
-    private static DebugHelper mDebugHelper = null;
+    private static DebugHelper sDebugHelper = null;
 
     private PrivateLog() {
     }
@@ -55,8 +55,8 @@
     public static synchronized PrivateLog getInstance(final Context context) {
         if (!DEBUG) return sInstance;
         synchronized(PrivateLog.class) {
-            if (sInstance.mDebugHelper == null) {
-                sInstance.mDebugHelper = new DebugHelper(context);
+            if (sDebugHelper == null) {
+                sDebugHelper = new DebugHelper(context);
             }
             return sInstance;
         }
@@ -94,16 +94,9 @@
 
     }
 
-    public static void log(String event, Context context) {
+    public static void log(String event) {
         if (!DEBUG) return;
-        final SQLiteDatabase l = getInstance(context).mDebugHelper.getWritableDatabase();
-        mDebugHelper.insert(l, event);
-    }
-
-    public static void log(String event, ContentProvider provider) {
-        if (!DEBUG) return;
-        final SQLiteDatabase l =
-                getInstance(provider.getContext()).mDebugHelper.getWritableDatabase();
-        mDebugHelper.insert(l, event);
+        final SQLiteDatabase l = sDebugHelper.getWritableDatabase();
+        DebugHelper.insert(l, event);
     }
 }
diff --git a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
index e05a79b..a596609 100644
--- a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
+++ b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
@@ -181,10 +181,9 @@
             if (!cursor.moveToFirst()) return;
             do {
                 final String clientId = cursor.getString(0);
-                if (TextUtils.isEmpty(clientId)) continue; // This probably can't happen
                 final String metadataUri =
                         MetadataDbHelper.getMetadataUriAsString(context, clientId);
-                PrivateLog.log("Update for clientId " + Utils.s(clientId), context);
+                PrivateLog.log("Update for clientId " + Utils.s(clientId));
                 Utils.l("Update for clientId", clientId, " which uses URI ", metadataUri);
                 uris.add(metadataUri);
             } while (cursor.moveToNext());
@@ -212,7 +211,7 @@
      */
     private static void updateClientsWithMetadataUri(final Context context,
             final boolean updateNow, final String metadataUri) {
-        PrivateLog.log("Update for metadata URI " + Utils.s(metadataUri), context);
+        PrivateLog.log("Update for metadata URI " + Utils.s(metadataUri));
         final Request metadataRequest = new Request(Uri.parse(metadataUri));
         Utils.l("Request =", metadataRequest);
 
@@ -258,7 +257,7 @@
             // method will ignore it.
             writeMetadataDownloadId(context, metadataUri, downloadId);
         }
-        PrivateLog.log("Requested download with id " + downloadId, context);
+        PrivateLog.log("Requested download with id " + downloadId);
     }
 
     /**
@@ -405,7 +404,7 @@
     /* package */ static void downloadFinished(final Context context, final Intent intent) {
         // Get and check the ID of the file that was downloaded
         final long fileId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, NOT_AN_ID);
-        PrivateLog.log("Download finished with id " + fileId, context);
+        PrivateLog.log("Download finished with id " + fileId);
         Utils.l("DownloadFinished with id", fileId);
         if (NOT_AN_ID == fileId) return; // Spurious wake-up: ignore
 
@@ -492,7 +491,7 @@
 
     private static void publishUpdateCycleCompletedEvent(final Context context) {
         // Even if this is not successful, we have to publish the new state.
-        PrivateLog.log("Publishing update cycle completed event", context);
+        PrivateLog.log("Publishing update cycle completed event");
         Utils.l("Publishing update cycle completed event");
         for (UpdateEventListener listener : linkedCopyOfList(sUpdateEventListeners)) {
             listener.updateCycleCompleted();
@@ -583,7 +582,7 @@
         }
 
         Utils.l("Downloaded metadata :", newMetadata);
-        PrivateLog.log("Downloaded metadata\n" + newMetadata, context);
+        PrivateLog.log("Downloaded metadata\n" + newMetadata);
 
         final ActionBatch actions = computeUpgradeTo(context, clientId, newMetadata);
         // TODO: Check with UX how we should report to the user
@@ -611,7 +610,7 @@
                 MetadataDbHelper.DESCRIPTION_COLUMN), "for", downloadRecord.mClientId);
         PrivateLog.log("Downloaded a new word list with description : "
                 + downloadRecord.mAttributes.getAsString(MetadataDbHelper.DESCRIPTION_COLUMN)
-                + " for " + downloadRecord.mClientId, context);
+                + " for " + downloadRecord.mClientId);
 
         final String locale =
                 downloadRecord.mAttributes.getAsString(MetadataDbHelper.LOCALE_COLUMN);
diff --git a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
index 0d923ae..93f12d5 100644
--- a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
+++ b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
@@ -23,7 +23,9 @@
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewParent;
 import android.widget.Button;
+import android.widget.ListView;
 
 import com.android.inputmethod.latin.R;
 
@@ -42,6 +44,7 @@
     // What to display in the "status" field when we receive unknown data as a status from
     // the content provider. Empty string sounds sensible.
     static final private String NO_STATUS_MESSAGE = "";
+    static final private int NOT_AN_INDEX = -1;
 
     /// Actions
     static final private int ACTION_UNKNOWN = 0;
@@ -64,7 +67,8 @@
     static final private int ANIMATION_IN = 1;
     static final private int ANIMATION_OUT = 2;
 
-    private static Button sLastClickedActionButton = null;
+    private static int sLastClickedIndex = NOT_AN_INDEX;
+    private static String sLastClickedWordlistId = null;
     private final OnWordListPreferenceClick mPreferenceClickHandler =
             new OnWordListPreferenceClick();
     private final OnActionButtonClick mActionButtonClickHandler =
@@ -196,7 +200,8 @@
         ((ViewGroup)view).setLayoutTransition(null);
         final Button button = (Button)view.findViewById(R.id.wordlist_button);
         button.setText(getButtonLabel(mStatus));
-        button.setVisibility(View.INVISIBLE);
+        // String identity match. This is an ==, not an .equals, on purpose.
+        button.setVisibility(mWordlistId == sLastClickedWordlistId ? View.VISIBLE : View.INVISIBLE);
         button.setOnClickListener(mActionButtonClickHandler);
         view.setOnClickListener(mPreferenceClickHandler);
     }
@@ -205,15 +210,31 @@
         @Override
         public void onClick(final View v) {
             final Button button = (Button)v.findViewById(R.id.wordlist_button);
-            if (null != sLastClickedActionButton) {
-                animateButton(sLastClickedActionButton, ANIMATION_OUT);
-            }
             animateButton(button, ANIMATION_IN);
-            sLastClickedActionButton = button;
+            final ViewParent parent = v.getParent();
+            // Just in case something changed in the framework, test for the concrete class
+            if (!(parent instanceof ListView)) return;
+            final ListView listView = (ListView)parent;
+            final int myIndex = listView.indexOfChild(v) + listView.getFirstVisiblePosition();
+            if (NOT_AN_INDEX != sLastClickedIndex) {
+                animateButton(getButtonForIndex(listView, sLastClickedIndex), ANIMATION_OUT);
+            }
+            sLastClickedIndex = myIndex;
+            sLastClickedWordlistId = mWordlistId;
         }
     }
 
+    private Button getButtonForIndex(final ListView listView, final int index) {
+        final int indexInChildren = index - listView.getFirstVisiblePosition();
+        if (indexInChildren < 0 || index > listView.getLastVisiblePosition()) {
+            // The view is offscreen.
+            return null;
+        }
+        return (Button)listView.getChildAt(indexInChildren).findViewById(R.id.wordlist_button);
+    }
+
     private void animateButton(final Button button, final int direction) {
+        if (null == button) return;
         final float outerX = ((View)button.getParent()).getWidth();
         final float innerX = button.getX() - button.getTranslationX();
         if (View.INVISIBLE == button.getVisibility()) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 0e1c4dc..16eab4b 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -439,6 +439,7 @@
         mHandler.onCreate();
         DEBUG = LatinImeLogger.sDBG;
 
+        // TODO: Resolve mutual dependencies of {@link #loadSettings()} and {@link #initSuggest()}.
         loadSettings();
         initSuggest();
 
@@ -476,6 +477,7 @@
         final InputAttributes inputAttributes =
                 new InputAttributes(getCurrentInputEditorInfo(), isFullscreenMode());
         mSettings.loadSettings(locale, inputAttributes);
+        // May need to reset the contacts dictionary depending on the user settings.
         resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary());
     }
 
@@ -745,6 +747,11 @@
         mRecapitalizeStatus.deactivate();
         mCurrentlyPressedHardwareKeys.clear();
 
+        // Note: the following does a round-trip IPC on the main thread: be careful
+        final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
+        if (null != mSuggest && null != currentLocale && !currentLocale.equals(mSuggest.mLocale)) {
+            initSuggest();
+        }
         if (mSuggestionStripView != null) {
             // This will set the punctuation suggestions if next word suggestion is off;
             // otherwise it will clear the suggestion strip.
@@ -797,8 +804,7 @@
         // to the user dictionary.
         if (null != mPositionalInfoForUserDictPendingAddition
                 && mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord(
-                        mConnection, editorInfo, mLastSelectionEnd,
-                        mSubtypeSwitcher.getCurrentSubtypeLocale())) {
+                        mConnection, editorInfo, mLastSelectionEnd, currentLocale)) {
             mPositionalInfoForUserDictPendingAddition = null;
         }
         // If tryReplaceWithActualWord returns false, we don't know what word was
@@ -1678,7 +1684,7 @@
         private SuggestedWords getSuggestedWordsGestureLocked(final InputPointers batchPointers) {
             mLatinIme.mWordComposer.setBatchInputPointers(batchPointers);
             final SuggestedWords suggestedWords =
-                    mLatinIme.getSuggestedWords(Suggest.SESSION_GESTURE);
+                    mLatinIme.getSuggestedWordsOrOlderSuggestions(Suggest.SESSION_GESTURE);
             final int suggestionCount = suggestedWords.size();
             if (suggestionCount <= 1) {
                 final String mostProbableSuggestion = (suggestionCount == 0) ? null
@@ -1970,9 +1976,12 @@
         // If we have a recapitalize in progress, use it; otherwise, create a new one.
         if (!mRecapitalizeStatus.isActive()
                 || !mRecapitalizeStatus.isSetAt(mLastSelectionStart, mLastSelectionEnd)) {
+            final CharSequence selectedText =
+                    mConnection.getSelectedText(0 /* flags, 0 for no styles */);
+            if (TextUtils.isEmpty(selectedText)) return; // Race condition with the input connection
             mRecapitalizeStatus.initialize(mLastSelectionStart, mLastSelectionEnd,
-                    mConnection.getSelectedText(0 /* flags, 0 for no styles */).toString(),
-                    mSettings.getCurrentLocale(), mSettings.getWordSeparators());
+                    selectedText.toString(), mSettings.getCurrentLocale(),
+                    mSettings.getWordSeparators());
             // We trim leading and trailing whitespace.
             mRecapitalizeStatus.trim();
             // Trimming the object may have changed the length of the string, and we need to
@@ -2152,7 +2161,8 @@
             return;
         }
 
-        final SuggestedWords suggestedWords = getSuggestedWords(Suggest.SESSION_TYPING);
+        final SuggestedWords suggestedWords =
+                getSuggestedWordsOrOlderSuggestions(Suggest.SESSION_TYPING);
         final String typedWord = mWordComposer.getTypedWord();
         showSuggestionStrip(suggestedWords, typedWord);
     }
@@ -2162,7 +2172,6 @@
         if (keyboard == null || mSuggest == null) {
             return SuggestedWords.EMPTY;
         }
-        final String typedWord = mWordComposer.getTypedWord();
         // Get the word on which we should search the bigrams. If we are composing a word, it's
         // whatever is *before* the half-committed word in the buffer, hence 2; if we aren't, we
         // should just skip whitespace if any, so 1.
@@ -2170,10 +2179,13 @@
         final String prevWord =
                 mConnection.getNthPreviousWord(mSettings.getCurrent().mWordSeparators,
                 mWordComposer.isComposingWord() ? 2 : 1);
-        final SuggestedWords suggestedWords = mSuggest.getSuggestedWords(mWordComposer,
-                prevWord, keyboard.getProximityInfo(), mSettings.getCurrent().mCorrectionEnabled,
-                sessionId);
-        return maybeRetrieveOlderSuggestions(typedWord, suggestedWords);
+        return mSuggest.getSuggestedWords(mWordComposer, prevWord, keyboard.getProximityInfo(),
+                mSettings.getCurrent().mCorrectionEnabled, sessionId);
+    }
+
+    private SuggestedWords getSuggestedWordsOrOlderSuggestions(final int sessionId) {
+        return maybeRetrieveOlderSuggestions(mWordComposer.getTypedWord(),
+                getSuggestedWords(sessionId));
     }
 
     private SuggestedWords maybeRetrieveOlderSuggestions(final String typedWord,
@@ -2186,7 +2198,7 @@
         // old suggestions. Also, if we are showing the "add to dictionary" hint, we need to
         // revert to suggestions - although it is unclear how we can come here if it's displayed.
         if (suggestedWords.size() > 1 || typedWord.length() <= 1
-                || suggestedWords.mTypedWordValid
+                || suggestedWords.mTypedWordValid || null == mSuggestionStripView
                 || mSuggestionStripView.isShowingAddToDictionaryHint()) {
             return suggestedWords;
         } else {
@@ -2577,8 +2589,8 @@
     // Outside LatinIME, only used by the {@link InputTestsBase} test suite.
     @UsedForTesting
     void loadKeyboard() {
-        // When the device locale is changed in SetupWizard etc., this method may get called via
-        // onConfigurationChanged before SoftInputWindow is shown.
+        // TODO: Why are we calling {@link #loadSettings()} and {@link #initSuggest()} in a
+        // different order than in {@link #onStartInputView}?
         initSuggest();
         loadSettings();
         if (mKeyboardSwitcher.getMainKeyboardView() != null) {
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 671d714..59d0207 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -68,7 +68,7 @@
     private float mAutoCorrectionThreshold;
 
     // Locale used for upper- and title-casing words
-    private final Locale mLocale;
+    public final Locale mLocale;
 
     public Suggest(final Context context, final Locale locale,
             final SuggestInitializationListener listener) {
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
index 099169a..a7a4171 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
@@ -17,10 +17,12 @@
 package com.android.inputmethod.latin.setup;
 
 import android.app.Activity;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
+import android.media.MediaPlayer;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Message;
 import android.provider.Settings;
@@ -28,6 +30,7 @@
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.TextView;
+import android.widget.VideoView;
 
 import com.android.inputmethod.compat.TextViewCompatUtils;
 import com.android.inputmethod.compat.ViewCompatUtils;
@@ -39,14 +42,23 @@
 
 import java.util.HashMap;
 
-public final class SetupActivity extends Activity {
+// TODO: Use Fragment to implement welcome screen and setup steps.
+public final class SetupActivity extends Activity implements View.OnClickListener {
+    private View mWelcomeScreen;
+    private View mSetupScreen;
     private SetupStepIndicatorView mStepIndicatorView;
-    private final SetupStepGroup mSetupSteps = new SetupStepGroup();
+    private Uri mWelcomeVideoUri;
+    private VideoView mWelcomeVideoView;
+    private View mActionStart;
+    private TextView mActionFinish;
+    private final SetupStepGroup mSetupStepGroup = new SetupStepGroup();
     private static final String STATE_STEP = "step";
     private int mStepNumber;
+    private static final int STEP_0 = 0;
     private static final int STEP_1 = 1;
     private static final int STEP_2 = 2;
     private static final int STEP_3 = 3;
+    private boolean mWasLanguageAndInputSettingsInvoked;
 
     private final SettingsPoolingHandler mHandler = new SettingsPoolingHandler(this);
 
@@ -108,16 +120,20 @@
             return;
         }
 
-        // TODO: Use sans-serif-thin font family depending on the system locale white list and
-        // the SDK version.
-        final TextView titleView = (TextView)findViewById(R.id.setup_title);
-        final int appName = getApplicationInfo().labelRes;
-        titleView.setText(getString(R.string.setup_steps_title, getString(appName)));
+        final String applicationName = getResources().getString(getApplicationInfo().labelRes);
+        mWelcomeScreen = findViewById(R.id.setup_welcome_screen);
+        final TextView welcomeTitle = (TextView)findViewById(R.id.setup_welcome_title);
+        welcomeTitle.setText(getString(R.string.setup_welcome_title, applicationName));
+
+        mSetupScreen = findViewById(R.id.setup_steps_screen);
+        final TextView stepsTitle = (TextView)findViewById(R.id.setup_title);
+        stepsTitle.setText(getString(R.string.setup_steps_title, applicationName));
 
         mStepIndicatorView = (SetupStepIndicatorView)findViewById(R.id.setup_step_indicator);
 
-        final SetupStep step1 = new SetupStep(findViewById(R.id.setup_step1),
-                appName, R.string.setup_step1_title, R.string.setup_step1_instruction,
+        final SetupStep step1 = new SetupStep(applicationName,
+                (TextView)findViewById(R.id.setup_step1_bullet), findViewById(R.id.setup_step1),
+                R.string.setup_step1_title, R.string.setup_step1_instruction,
                 R.drawable.ic_setup_step1, R.string.setup_step1_action);
         step1.setAction(new Runnable() {
             @Override
@@ -126,10 +142,11 @@
                 mHandler.startPollingImeSettings();
             }
         });
-        mSetupSteps.addStep(STEP_1, step1);
+        mSetupStepGroup.addStep(STEP_1, step1);
 
-        final SetupStep step2 = new SetupStep(findViewById(R.id.setup_step2),
-                appName, R.string.setup_step2_title, R.string.setup_step2_instruction,
+        final SetupStep step2 = new SetupStep(applicationName,
+                (TextView)findViewById(R.id.setup_step2_bullet), findViewById(R.id.setup_step2),
+                R.string.setup_step2_title, R.string.setup_step2_instruction,
                 R.drawable.ic_setup_step2, R.string.setup_step2_action);
         step2.setAction(new Runnable() {
             @Override
@@ -139,10 +156,11 @@
                         .showInputMethodPicker();
             }
         });
-        mSetupSteps.addStep(STEP_2, step2);
+        mSetupStepGroup.addStep(STEP_2, step2);
 
-        final SetupStep step3 = new SetupStep(findViewById(R.id.setup_step3),
-                appName, R.string.setup_step3_title, R.string.setup_step3_instruction,
+        final SetupStep step3 = new SetupStep(applicationName,
+                (TextView)findViewById(R.id.setup_step3_bullet), findViewById(R.id.setup_step3),
+                R.string.setup_step3_title, R.string.setup_step3_instruction,
                 R.drawable.ic_setup_step3, R.string.setup_step3_action);
         step3.setAction(new Runnable() {
             @Override
@@ -150,7 +168,40 @@
                 invokeSubtypeEnablerOfThisIme();
             }
         });
-        mSetupSteps.addStep(STEP_3, step3);
+        mSetupStepGroup.addStep(STEP_3, step3);
+
+        mWelcomeVideoUri = new Uri.Builder()
+                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+                .authority(getPackageName())
+                .path(Integer.toString(R.raw.setup_welcome_video))
+                .build();
+        mWelcomeVideoView = (VideoView)findViewById(R.id.setup_welcome_video);
+        mWelcomeVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+            @Override
+            public void onCompletion(final MediaPlayer mp) {
+                mp.start();
+            }
+        });
+
+        mActionStart = findViewById(R.id.setup_start_label);
+        mActionStart.setOnClickListener(this);
+        mActionFinish = (TextView)findViewById(R.id.setup_finish);
+        TextViewCompatUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(mActionFinish,
+                getResources().getDrawable(R.drawable.ic_setup_finish), null, null, null);
+        mActionFinish.setOnClickListener(this);
+    }
+
+    @Override
+    public void onClick(final View v) {
+        if (v == mActionStart) {
+            mStepNumber = STEP_1;
+            updateSetupStepView();
+            return;
+        }
+        if (v == mActionFinish) {
+            finish();
+            return;
+        }
     }
 
     private void invokeSetupWizardOfThisIme() {
@@ -165,7 +216,8 @@
         final Intent intent = new Intent();
         intent.setClass(this, SettingsActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
-                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                | Intent.FLAG_ACTIVITY_CLEAR_TOP
+                | Intent.FLAG_ACTIVITY_NO_HISTORY);
         startActivity(intent);
     }
 
@@ -174,6 +226,7 @@
         intent.setAction(Settings.ACTION_INPUT_METHOD_SETTINGS);
         intent.addCategory(Intent.CATEGORY_DEFAULT);
         startActivity(intent);
+        mWasLanguageAndInputSettingsInvoked = true;
     }
 
     private void invokeSubtypeEnablerOfThisIme() {
@@ -224,7 +277,7 @@
     private int determineSetupStepNumber() {
         mHandler.cancelPollingImeSettings();
         if (!isThisImeEnabled(this)) {
-            return STEP_1;
+            return mWasLanguageAndInputSettingsInvoked ? STEP_1 : STEP_0;
         }
         if (!isThisImeCurrent(this)) {
             return STEP_2;
@@ -263,6 +316,22 @@
     }
 
     @Override
+    public void onBackPressed() {
+        if (mStepNumber == STEP_1) {
+            mStepNumber = STEP_0;
+            updateSetupStepView();
+            return;
+        }
+        super.onBackPressed();
+    }
+
+    @Override
+    protected void onPause() {
+        mWelcomeVideoView.stopPlayback();
+        super.onPause();
+    }
+
+    @Override
     public void onWindowFocusChanged(final boolean hasFocus) {
         super.onWindowFocusChanged(hasFocus);
         if (!hasFocus) {
@@ -273,10 +342,20 @@
     }
 
     private void updateSetupStepView() {
+        final boolean welcomeScreen = (mStepNumber == STEP_0);
+        mWelcomeScreen.setVisibility(welcomeScreen ? View.VISIBLE : View.GONE);
+        mSetupScreen.setVisibility(welcomeScreen ? View.GONE: View.VISIBLE);
+        if (welcomeScreen) {
+            mWelcomeVideoView.setVideoURI(mWelcomeVideoUri);
+            mWelcomeVideoView.start();
+            return;
+        }
+        mWelcomeVideoView.stopPlayback();
         final int layoutDirection = ViewCompatUtils.getLayoutDirection(mStepIndicatorView);
         mStepIndicatorView.setIndicatorPosition(
-                getIndicatorPosition(mStepNumber, mSetupSteps.getTotalStep(), layoutDirection));
-        mSetupSteps.enableStep(mStepNumber);
+                getIndicatorPosition(mStepNumber, mSetupStepGroup.getTotalStep(), layoutDirection));
+        mSetupStepGroup.enableStep(mStepNumber);
+        mActionFinish.setVisibility((mStepNumber == STEP_3) ? View.VISIBLE : View.GONE);
     }
 
     private static float getIndicatorPosition(final int step, final int totalStep,
@@ -286,20 +365,26 @@
     }
 
     static final class SetupStep implements View.OnClickListener {
-        private final View mRootView;
+        private final View mStepView;
+        private final TextView mBulletView;
+        private final int mActivatedColor;
+        private final int mDeactivatedColor;
         private final TextView mActionLabel;
         private Runnable mAction;
 
-        public SetupStep(final View rootView, final int appName, final int title,
-                final int instruction, final int actionIcon, final int actionLabel) {
-            mRootView = rootView;
-            final Resources res = rootView.getResources();
-            final String applicationName = res.getString(appName);
+        public SetupStep(final String applicationName, final TextView bulletView,
+                final View stepView, final int title, final int instruction, final int actionIcon,
+                final int actionLabel) {
+            mStepView = stepView;
+            mBulletView = bulletView;
+            final Resources res = stepView.getResources();
+            mActivatedColor = res.getColor(R.color.setup_text_action);
+            mDeactivatedColor = res.getColor(R.color.setup_text_dark);
 
-            final TextView titleView = (TextView)rootView.findViewById(R.id.setup_step_title);
+            final TextView titleView = (TextView)mStepView.findViewById(R.id.setup_step_title);
             titleView.setText(res.getString(title, applicationName));
 
-            final TextView instructionView = (TextView)rootView.findViewById(
+            final TextView instructionView = (TextView)mStepView.findViewById(
                     R.id.setup_step_instruction);
             if (instruction == 0) {
                 instructionView.setVisibility(View.GONE);
@@ -307,21 +392,20 @@
                 instructionView.setText(res.getString(instruction, applicationName));
             }
 
-            mActionLabel = (TextView)rootView.findViewById(R.id.setup_step_action_label);
+            mActionLabel = (TextView)mStepView.findViewById(R.id.setup_step_action_label);
             mActionLabel.setText(res.getString(actionLabel));
             if (actionIcon == 0) {
                 final int paddingEnd = ViewCompatUtils.getPaddingEnd(mActionLabel);
                 ViewCompatUtils.setPaddingRelative(mActionLabel, paddingEnd, 0, paddingEnd, 0);
             } else {
-                final Drawable icon = res.getDrawable(actionIcon);
-                icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
-                TextViewCompatUtils.setCompoundDrawablesRelative(
-                        mActionLabel, icon, null, null, null);
+                TextViewCompatUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(
+                        mActionLabel, res.getDrawable(actionIcon), null, null, null);
             }
         }
 
         public void setEnabled(final boolean enabled) {
-            mRootView.setVisibility(enabled ? View.VISIBLE : View.GONE);
+            mStepView.setVisibility(enabled ? View.VISIBLE : View.GONE);
+            mBulletView.setTextColor(enabled ? mActivatedColor : mDeactivatedColor);
         }
 
         public void setAction(final Runnable action) {
@@ -331,8 +415,9 @@
 
         @Override
         public void onClick(final View v) {
-            if (mAction != null) {
+            if (v == mActionLabel && mAction != null) {
                 mAction.run();
+                return;
             }
         }
     }
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java b/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java
new file mode 100644
index 0000000..ca974f6
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java
@@ -0,0 +1,108 @@
+/*
+ * 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.setup;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.inputmethod.compat.ViewCompatUtils;
+import com.android.inputmethod.latin.R;
+
+public final class SetupStartIndicatorView extends LinearLayout {
+    public SetupStartIndicatorView(final Context context, final AttributeSet attrs) {
+        super(context, attrs);
+        setOrientation(HORIZONTAL);
+        LayoutInflater.from(context).inflate(R.layout.setup_start_indicator_label, this);
+
+        final LabelView labelView = (LabelView)findViewById(R.id.setup_start_label);
+        labelView.setIndicatorView(findViewById(R.id.setup_start_indicator));
+    }
+
+    public static final class LabelView extends TextView {
+        private View mIndicatorView;
+
+        public LabelView(final Context context, final AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public void setIndicatorView(final View indicatorView) {
+            mIndicatorView = indicatorView;
+        }
+
+        @Override
+        public void setPressed(final boolean pressed) {
+            super.setPressed(pressed);
+            if (mIndicatorView != null) {
+                mIndicatorView.setPressed(pressed);
+            }
+        }
+    }
+
+    public static final class IndicatorView extends View {
+        private final Path mIndicatorPath = new Path();
+        private final Paint mIndicatorPaint = new Paint();
+        private final ColorStateList mIndicatorColor;
+
+        public IndicatorView(final Context context, final AttributeSet attrs) {
+            super(context, attrs);
+            mIndicatorColor = getResources().getColorStateList(
+                    R.color.setup_step_action_background);
+            mIndicatorPaint.setStyle(Paint.Style.FILL);
+        }
+
+        @Override
+        public void setPressed(final boolean pressed) {
+            super.setPressed(pressed);
+            invalidate();
+        }
+
+        @Override
+        protected void onDraw(final Canvas canvas) {
+            super.onDraw(canvas);
+            final int layoutDirection = ViewCompatUtils.getLayoutDirection(this);
+            final int width = getWidth();
+            final int height = getHeight();
+            final float halfHeight = height / 2.0f;
+            final Path path = mIndicatorPath;
+            path.rewind();
+            if (layoutDirection == ViewCompatUtils.LAYOUT_DIRECTION_RTL) {
+                // Left arrow
+                path.moveTo(width, 0.0f);
+                path.lineTo(0.0f, halfHeight);
+                path.lineTo(width, height);
+            } else { // LAYOUT_DIRECTION_LTR
+                // Right arrow
+                path.moveTo(0.0f, 0.0f);
+                path.lineTo(width, halfHeight);
+                path.lineTo(0.0f, height);
+            }
+            path.close();
+            final int[] stateSet = getDrawableState();
+            final int color = mIndicatorColor.getColorForState(stateSet, 0);
+            mIndicatorPaint.setColor(color);
+            canvas.drawPath(path, mIndicatorPaint);
+        }
+    }
+}